Thursday, March 15, 2012

Find the jQuery Bug #8: Suspicious Selectors

Introduction


In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.

You can view other posts in this series...

The Desired Feature


The following is a snippet of HTML markup that was generated by Oracle's JSF (JavaServer Faces). We want to select the first name field and add a class that will change it's border style.


The Buggy Code


The following code snippets is our first attempt at solving the problem, but there is a subtle error. Do you see it?


You can view, run, and edit the above code sample from JSBin.



The result that we expected was to see the first name textbox with a red border, but as you can see above it was not successful.

The Underlying Problem


At the root of the problem is that JSF inserts a : delimiter inside of the id attribute. jQuery abides by the W3C CSS Specification Rules when it comes to valid characters in a selector.

If your ID, name, or class contains one of the following meta-characters then you have a problem... !"#$%&'()*+,./:;<=>?@[\]^`{|}~

Here are some examples of invalid selectors in jQuery because they contain invalid characters:


A Solution


jQuery provides a solution of escaping invalid characters inside a selector. You can proceed each character with two backslashes \\ and then the selector should start working as you expect.

If you wish to use any of the meta-characters ( such as !"#$%&'()*+,./:;<=>?@[\]^`{|}~ ) as a literal part of a name, you must escape the character with two backslashes: \\. For example, if you have an element with id="foo.bar", you can use the selector $("#foo\\.bar").

-- http://api.jquery.com/category/selectors/

In order to fix our example we just need to escape the : character with \\ like the following code example demonstrates.


You can view, run, and edit the above code sample from JSBin.

If you test out the code again below you'll notice that once you've filled in the textbox and click enter then the behavior will continue as we expected.



The following examples are the corrected versions of the previous snippets shown in the previous section:


An Alternate Solution


An alternate way to look at this problem is to create a method that will automatically escape the id, name, or class name before using it as a selector.


The previous code snippet extends the String prototype and uses a regular expression to find all invalid meta-characters and escapes them with \\.

Conclusion


The key concept to remember here is that there is a set of characters that are invalid and need to be escaped before using them in a jQuery selector.

Until next time...

No comments:

Post a Comment