views:

1573

answers:

5

I have a requirement to add a RequiredFieldValidator and RegularExpressionValidator to a dynamically created textbox in a dynamically generated tablecell, inside a Web User Control in the Content Area of a Page created from a Master.

The problem, as you can probably guess, is trying to dynamically set the ControlToValidate property to look at my dynamically created text box.

After some research the code now:

  • Creates a Panel (As I have heard the ControlToValidate and Validator must be within the same container). This was originally a placeholder but was trying a suggestion listed below.
  • Creates the Textbox and sets its ID.
  • Adds the Textbox to the Panel.
  • Creates the RequiredFieldValidator.
  • Sets the id of the ControlToValidate. Values I have attempted to use:

    • The ID of the control
    • the ClientID of the control
    • the ID of the control prefixed by the added text the server appends to child controls of the Web User Control
    • the Client ID modified the same way
    • the name of the control (on the off chance)
    • the name of the control prefixed by the text the server adds to the names of controls
    • using a bespoke Recursive FindControl Method in an attempt to cast a new Control object to Textbox and then using its ID and ClientID
    • the UniqueID of the control
    • the same modified with the prefix as detailed above
  • Add the validator to the panel.
  • Add the panel to the tablecell.

Needless to say I am still unable to convince the Validator to "see" the control it is supposed to validate and I am completely out of new ways to approach the problem.

EDIT: Further detective work has lead me to the point that the page doesn't have a problem until the page_load event has finished. The server seems to have a problem after the code for building the page has finished executing. I'm starting to wonder if I'm actually adding the controls into naming containers much too late instead of too early.

Any suggestions?

+1  A: 

What about creating a user control that contains the textbox and the two validators? Then you can set the ControlToValidate via Visual Studio, as usual, and then dynamically add this new control to your tablecell dynamically.

pgb
Interesting thought, but that could get messy as "Textbox" is just one of a number of control type options that *could* inhabit the cell and I'd want to keep the code desig consistent. However I may be forced to try this if all else fails. Thanks for the thought :)
As predicted it got really messy (as indicated by it being nearly a week later that I write this!) but it is the only thing that actually worked. Kudos and an upvote to pgb!
Nice to hear you got it working.
pgb
A: 

here is an example:

Add a Panel control to your page at design time with the ID = "PanelHolder"(or you can add dynamically).

then create your controls dynamically and add them to that panel like this:

var myTextbox = new TextBox() {ID="myTextBox"};
PanelHolder.Controls.Add(myTextBox);
var validator = new RequiredFieldValidator() {ControlToValidate="myTextBox",Display=ValidatorDisplay.Dynamic,ErrorMessage="Required field"}
PanelHolder.Controls.Add(validator);
Marwan Aouida
I will try it, but is this not essentially the same as adding the placeholder and adding the controls to that? If not, why not?
for the record this does not solve the problem. valiant effort though.
A: 

Just a couple of questions:

  • Is the control that's posting the page back causes validation? ( if so, make sure it's not in a separate validation group )

  • Are you sure there's no validation happening? If you don't set the ErrorMessage property of the validators it might be easy to think it's not doing anything. (and I can't see you setting it on your list)

Edit:

If you're doing something like this:

        Panel pTest = new Panel();

        TextBox tb = new TextBox();
        for (int i = 0; i < 2; i++)
        {
            tb.ID = "tbDynamicTextBox" + i;
            pTest.Controls.Add(tb );
            RequiredFieldValidator rfv = new RequiredFieldValidator();
            rfv.ControlToValidate = tb.ID;
            rfv.ErrorMessage = "Empty textbox";
            pTest.Controls.Add(rfv);
        }
        cell.Controls.Add(pTest);

Then you will get an error as only one instance of the textbox will be added to the controls collection. If you move the ' TextBox tb = new TextBox(); ' part inside the loop tho, it'll be fine.

I'm not sure if this's your problem, but worth a try.

snomag
The page won't load in the first place. So I'm pretty sure no validation is happening. The control loading does not cause a postback.
If the page doesn't load, how can you be so sure this is an issue?
hunter
What cause the page not to load is the fact that when an attempt is made to add the dynamic validator to the Page's control collection it can't find the textbox it is supposed to be validating thus causing the page to bork with an error message instead of loading. This is a problem to me. I want the page to load with a validating textbox on it. Not a .Net error message.
re: the edit. That's very interesting. I shall try that as soon as I can, probably tomorrow at this stage. But this sounds helpful, I will be disappointed if it doesn't help.
*sigh* :( no dice on that one either I'm afraid...
+1  A: 

I used a repeater in a similar situation:

<table>
<colgroup>
 <col style="white-space: nowrap;" />
 <col />
 <col />
</colgroup>
<asp:Repeater ID="InputFields" runat="server">
 <ItemTemplate>
  <tr>
   <td class="labelCell">
    <asp:Label id="FieldName" runat="server" Font-Bold="True" Text='<%# Eval("Name") %>'></asp:Label>:
   </td>
   <td class="fieldCell">
    <asp:TextBox id="FieldData" runat="server" autocomplete="off" />
   </td>
   <td class="errorCell">
    <asp:RequiredFieldValidator ID="FieldNameRequiredValidator" runat="server" CssClass="errorValidator" ErrorMessage='<%# Eval("Name") %> is required' 
     ControlToValidate="FieldData" Display="Dynamic">&nbsp;&nbsp;&nbsp;</asp:RequiredFieldValidator>
    <asp:RegularExpressionValidator ID="FieldNameRegexValidator" runat="server" CssClass="errorValidator" ErrorMessage='A valid <%# Eval("Name") %> is required'
     ControlToValidate="FieldData" Display="Dynamic" ValidationExpression='<%# Eval("RegEx") %>'>&nbsp;&nbsp;&nbsp;</asp:RegularExpressionValidator>
   </td>
  </tr>
 </ItemTemplate>
</asp:Repeater>

The repeater creates a "naming container" that ensures that the FieldData control ID is unique within the container.

P.J. Tezza
A: 

hello i generate a texbox and requiredfield validator for that texbox inside a grid.

I first tried to use textbox's clientID as controltovalidate property of requiredfield validator this gived unable to find control error than I gived texbox's ID as controltovalidate property of requiredfield validator and it was worked for me.The code below returns a RegularExpressionValidator for the control that gived as first argument for method.

private RegularExpressionValidator GetRegValidator(string itemId, string regExp)
    {
        RegularExpressionValidator _regVal = new RegularExpressionValidator();
        _regVal.ControlToValidate = itemId;
        _regVal.ValidationExpression = regExp;
        _regVal.ErrorMessage ="PropertyRegexDoesNotMatches";
        _regVal.Text = "*";
        _regVal.SetFocusOnError = true;
        _regVal.EnableClientScript = true;
        _regVal.ID = string.Format("{0}Validator", itemId);
        return _regVal;
    }
dankyy1