43

Does anyone know how to escape the square bracket character when setting a class name with jQuery?

Try the following:

$('#txtFirstname').addClass('test[someval]')

then

$('#txtFirstname').attr('class')

you'll see the class is there.

Now try

$('#txtFirstname').hasClass('test[someval]')

FAIL

The only reason I can think of is the square brackets.

And I need these for my jQuery validation you see.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Duncan
  • 10,218
  • 14
  • 64
  • 96

4 Answers4

86

Escape with TWO (2) backslashes.

http://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/

TylerH
  • 20,799
  • 66
  • 75
  • 101
Duncan
  • 10,218
  • 14
  • 64
  • 96
  • 9
    The two backslashes are only because of JavaScript string escaping. It's actually, correctly, a single backslash you are sending to jQuery itself. – bobince Sep 23 '09 at 13:57
  • 8
    For `` you can select with `$("#foo\\[bar\\]")` as discussed, or `$('[id="foo[bar]"]')` by using the [attribute equals selector](http://api.jquery.com/attribute-equals-selector/) – Travis P Jun 01 '11 at 22:16
  • @Travis I don't think square brackets [] are valid in "id" for html versions prior to 5. They are valid in "name". – cquezel Sep 28 '12 at 04:07
  • I've confirmed this works for apostropies also: `jQuery("#accommodations option[value='L\\'acquaviva 11/1/2010-11/8/2010']").attr("disabled", "disabled").hide();` Thanks for the great tip! – Devin Walker Jan 09 '13 at 07:55
  • 1
    I am not able to select (coincidentally a select tag) ` – Frank N Jan 30 '13 at 14:02
  • 1
    For the records, this was a jQuery bug that was fixed on 1.4. With later versions you don't need to escape metacharacters in class names when calling `.hasClass()`. See my answer for further details. – Álvaro González Sep 06 '13 at 20:11
  • BTW, the FAQ entry talks about **selectors** and the `addClass()` function does not accept selectors. If you add two backslashes you'll add a bogus slash to the class name: [online demo](http://jsbin.com/ISemozUk/1/edit?html,js,console) – Álvaro González Nov 07 '13 at 09:20
  • The FAQ item was renamed: http://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/ – David Leppik Dec 16 '13 at 17:36
9

The introduction of jQuery API page gives the above explanation about this:

To use any of the meta-characters ( such as !"#$%&'()*+,./:;<=>?@[]^`{|}~ ) as a literal part of a name, it must be escaped with with two backslashes: \\.

digiogo
  • 300
  • 4
  • 5
  • That quote is from the **Selectors** category. A class name is not a selector. If prepend two backslashes you'll add a bogus slash to the class name: [proof](http://jsbin.com/ISemozUk/1/edit?html,js,console) – Álvaro González Nov 07 '13 at 09:18
4

If the selector is contained within a variable (or if you can get it into a variable), the code below may be helpful:

selector_name = $this.attr('class');
//e.g selector_name = users[0][first:name]

escaped_selector_name = selector_name.replace(/(:|\.|\[|\])/g,'\\$1');
//e.g escaped_selector_name = users\\[0\\]\\[first\\:name\\]

In short we prefix all special characters with double backslash. Here's some additional documentation from the jQuery site:

http://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/

Eric Kigathi
  • 1,815
  • 21
  • 23
1

Short answer: you don't need to escape brackets because the argument is a class name, not a selector. It didn't work for you because of a bug in earlier jQuery versions that has long been fixed.

To demonstrate it, here's your code running under different versions:

  • jQuery/1.3.2 (buggy):

$('#txtFirstname').addClass('test[someval]')
$('#txtFirstname').attr('class')
console.log($('#txtFirstname').hasClass('test[someval]'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div id="txtFirstname"></div>
  • jQuery/1.4.0 (fixed):

$('#txtFirstname').addClass('test[someval]')
$('#txtFirstname').attr('class')
console.log($('#txtFirstname').hasClass('test[someval]'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
<div id="txtFirstname"></div>

So the issued was apparently fixed on jQuery/1.4.0. I found a ticket regarding this (though it's tagged as being fixed on 1.4.2 rather than 1.4.0).

I insist: the rule to quote or escape metacharacters with \\ in order to use them as a literal part of a name only applies to selectors. However, the .hasClass() method does not receive a selector as argument but as class name:

.hasClass( className )

    className
    Type: String
    The class name to search for.
Álvaro González
  • 142,137
  • 41
  • 261
  • 360