views:

54

answers:

2

I have an ASP.NET page and I am trying to quickly match the validation controls that are tied to a particular textbox (text input) using a jQuery selector. The validation controls render as a span and the "controltovalidate" property renders as an expando property. Here is a test example:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <script type="text/javascript" src="jquery.js"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox1"
            ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>

        <asp:Button ID="Button1" runat="server" Text="Button" /></div>

        <input type="button" value="Test" onclick="ml_test();" />

        <script type="text/javascript">
            ml_test = function() {
                alert($('[controltovalidate=TextBox1]').get().length);
            };
        </script>

    </form>
</body>
</html>

Renders as:

(code removed here)

        <input name="TextBox1" type="text" id="TextBox1" />
        <span id="RequiredFieldValidator1" style="color:Red;visibility:hidden;">RequiredFieldValidator</span>
        <span id="RegularExpressionValidator1"></span>

        <input type="submit" name="Button1" value="Button" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;Button1&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))" id="Button1" /></div>

        <input type="button" value="Test" onclick="ml_test();" />

        <script type="text/javascript">
            ml_test = function() {
                alert($('[controltovalidate=TextBox1]').get().length);
            };
        </script>

(code removed here)

<script type="text/javascript">
//<![CDATA[
var RequiredFieldValidator1 = document.all ? document.all["RequiredFieldValidator1"] : document.getElementById("RequiredFieldValidator1");
RequiredFieldValidator1.controltovalidate = "TextBox1";
RequiredFieldValidator1.errormessage = "RequiredFieldValidator";
RequiredFieldValidator1.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
RequiredFieldValidator1.initialvalue = "";
//]]>
</script>

The problem: the ml_test() function shows 1 in Internet Explorer 7 (as expected), but shows 0 in Firefox 3.6.8. I tried adding additional controls, but in Firefox it consistently doesn't work.

I discovered this post that shows the use of an ampersand in the selector like this [@expando=value], but when I try this syntax, jQuery 1.4.2 throws an error.

Is there a cross-browser way to select expando attributes, and if so, what is the proper syntax?

A: 

Are you looking for the span that shows the validation message if invalid?

If so try this: (using jQuery)

ml_test = function() {
    alert($('RequiredFieldValidator1').length);
};

If you want to also be able to see what control it's validating do something like this:

ml_test = function() {

    // getting the control with jQuery by its ID.  .Net already has it
    // defined in the script block that is generated by the 
    // RequiredFieldValidator control
    var validateCtrl = $(RequiredFieldValidator1.id);  

    // get the value from the .Net-defined validator variable
    var controlToValidate = RequiredFieldValidator1.controltovalidate;

    // alert the values:
    alert('RequiredValidatorControl count: ' + validator.length + 
          '\nControl To Validate: ' + controlToValidate);

};
Silkster
No, I am building a control. I am trying to retrieve all of the validation controls that validate TextBox1 in a simple jQuery selector. I won't know the names of the controls in advance, so this example won't work for my purpose. Note: I already know I can use the Page_Validators variable to do this, but I was hoping to accomplish my task without looping through all of the validation controls on the page - namely, by using a jQuery selector.
NightOwl888
I don't know a way around using .Net generated values for this.
Silkster
A: 

You can use .filter() like this:

ml_test = function() {
    alert($('span').filter(function() { return this.controltovalidate=='TextBox1'; }).length);
};

You can test it here, or make it a custom selector, like this:

jQuery.expr[':'].validatorFor = function(o, i, m){
  return o.controltovalidate === m[3];
};​

And call it like this:

ml_test = function() {
    alert($('span:validatorFor(TextBox1)').length);
};

You can that that version here.

Nick Craver
Thanks, this is more along the lines of what I was looking for. However, since ASP.NET allows developers to build their own validation controls, there is no guarantee that they will always render as a span. Is there a more generic way to do this without specifying the type of element?
NightOwl888
@NightOwl888 - Yes, you can take the `span` off there, but it'll check *every* element, any way you could slim it down would be helpful and make it more efficient.
Nick Craver
So in other words, the global JavaScript array variable ASP.NET generates will most likely be more efficient, considering there may be several dozen elements on the form and there will only be up to a dozen or so elements in the array. I will probably go that way, but thanks for letting me know about the custom selector functionality in jQuery.
NightOwl888