Saturday, May 21, 2011

Escaping Strings for jQuery Selectors

The possibility to get DOM elements via selectors is one of the most powerful features of jQuery. However, it's not so rare that you get problems because the id of the element you want to select or any other attribute, class or value relevant for the selection contains characters that are used by jQuery for the definition of the selector itself. In the jQuery documentation it's clearly defined which characters are considered as meta-characters for selectors and thus have to be escaped with a backslash (or better two backslashes if you're passing the value with a string literal):
"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: \\."

Unfortunately, jQuery doesn't offer any function to escape these characters within a string, so that you don't have to care about what characters you must not use when defining attributes of your markup.

So I've spent almost one hour playing (or better fighting) with regular expressions in order to create a general function to escape strings to use in jQuery selectors. So if you're an absolutely RegEx guru or just have the time to figure out the right regular expression to use for this purpose, then you're probably not so interested in the following function. Otherwise, you should really try it out! ;)

  function jQuerySelectorEscape(expression) {
      return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&');
  }

The function inserts a backslash before all meta-characters for jQuery selectors within a string.
Here's an example:
<div id="my#div$has[some]strange*characters">My DIV</div>
<br/>
<script type="text/javascript">
  var selector = '#' + jQuerySelectorEscape('my#div$has[some]strange*characters');
  document.write('selector = ' + selector);
  document.write('<br/><br/>');
  document.write('DIV content = ' + jQuery(selector).html());
</script>
Output:
My DIV

selector = #my\#div\$has\[some\]strange\*characters

DIV content = My DIV

I hope you can avoid some headaches with this function. If there's any question or problem with it, leave a comment below and I'll try to help you out.

6 comments:

  1. Using this on a jsp file doesn't seem to work as here, only in js file it seems. In the jsp file i had to put two more "\" in the replace method so it would stay like this:

    return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\\\$&');

    ReplyDelete
    Replies
    1. It depends on your JSP. This code is meant to be used within the Javascript context, i. e. like you said in a js file, or inside a <script> block of a HTML page for example. Actually it also should work inside a JSP, as long as you're not inside the Java context (i. e. inside <% %>), otherwise you would have to escape again all meta characters used in Java.

      Delete
    2. Yes i mean placing it in the jsp file inside the script block tag as if it was an html page.

      Delete
  2. Very handy. You should also add \s to your regex.

    ReplyDelete
    Replies
    1. Thanks, I usually don't use whitespaces inside HTML attributes, so I've never needed \s. And since whitespaces are not in the documentation (see quote above), I'm not sure what jQuery would do with it.

      Delete
  3. Thanks for this, was useful for me :)

    ReplyDelete