Be careful with your jQuery selectors!


I love jQuery! On my current ASP.NET 3.5 project I have a form which contains several input fields. I wanted to disable them given a condition. I created the following jQuery code:

$(document).ready(function() {
    $("input#ASP_Generated_User_Control_Prefix_Here_uxMyNumberField").keyup(function() {
        // select a selection of inputs and links
        var elements = $(":input:not(:submit)")
                       .not($(this))
                       .add("a.fxButton");

        if ($.trim($(this).val()) != "") {
            elements.attr('disabled', true);
        } else {
            elements.removeAttr('disabled');
        }
    });
});

In short this code applies to the keyup() event of input field named uxMyNumberField (the ID is autogenerated by ASP). As we will see in a moment, it is the jQuery selector which plays the star role of this blog entry. So to explain the selector: select all input fields that are not submit buttons, but exclude the current input field. Also include links of a given CSS class (fxButton) to the selection. So if a value is entered in uxMyNumberField then the code will immediately disable every element contained in the element set, and otherwise enable them (i.e. user presses backspace).

Everything worked as expected in the browser. The UI elements were being enabled and disabled when a value was entered or removed. However, when adding a value to the uxMyNumberField and clicking on the form’s submit button, the form was not being submitted as it was previously. The ASP event handler for my submit button was never being called, but I could confirm that a server request was being generated from the browser and the ASP Page’s Load event was being triggered. Curiously, the error only applied when a value was entered in the uxMyNumberField field. The remaining form fields were being submitting correctly when uxMyNumberField was empty.

To make a long story short, what was happening was the selector was also including hidden ASP input fields in the element set – fields used for internal ASP page state and event handling.

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />

In practice this was disabling the submit button’s event handler. When correcting the selector to only include my form elements everything worked as expected.

This nasty mistake took me some time to locate and only with the aid of Firebug – what would we do without it! I was certain the error was due to an ASP validator control change I had made earlier, which only applied to the uxMyNumberField.

This was also my first experience with the Firebug Javascript debugger. When stepping through my jQuery function, the debugger showed me which elements were part of the resulting element set, which in turn immediately led me towards correcting the selector and excluding the hidden ASP input fields.

So the moral of this experience is be careful not to include fields used by the platform when creating your jQuery selectors! 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s