87

I have a DOM element with an ID similar to:

something[500]

which was built by my Ruby on Rails application. I need to be able to get this element via jQuery so that I can traverse my way up the DOM to delete the parent of it's parent, which has a variable ID that I don't have access to beforehand.

Does anyone know how I could go about this? The following code doesn't seem to be working:

alert($("#something["+id+"]").parent().parent().attr("id"));

Upon further inspection, the following:

$("#something["+id+"]")

returns an object, but when I run ".html()" or ".text()" on it, the result is always null or just an empty string.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Mike Trpcic
  • 25,305
  • 8
  • 78
  • 114
  • 2
    In addition to the correct answer (which is that you need to escape the brackets with double backslashes), you should really use closest() instead of multiple parent() calls. It is cleaner and less likely to break if a level happens to change... So if you're trying to get the closest div you do .closest('div') or even better .closest('div.meaningfulclassthatiwant') – Paolo Bergantino Aug 06 '09 at 14:16
  • Thanks for the suggestion Paolo, but as I mentioned I don't know the ID/class of the parent I'm looking for ahead of time, and since both parents are divs, closest would not work. Thanks though. – Mike Trpcic Aug 06 '09 at 14:49
  • Ah, sorry, I didn't read the question just looked at the title and the code in it :) Guess that serves me about right. – Paolo Bergantino Aug 06 '09 at 14:53

7 Answers7

119

You need to escape the square brackets so that they are not counted as attribute selectors. Try this:

alert($("#something\\["+id+"\\]").parent().parent().attr("id"));

See Special Characters In Selectors, specifically the second paragraph:

To use any of the meta-characters (such as !"#$%&'()*+,./:;<=>?@[\]^``{|}~) as a literal part of a name, it must be escaped with with two backslashes: \\. For example, an element with id="foo.bar", can use the selector $("#foo\\.bar"). The W3C CSS specification contains the complete set of rules regarding valid CSS selectors. Also useful is the blog entry by Mathias Bynens on CSS character escape sequences for identifiers.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
karim79
  • 339,989
  • 67
  • 413
  • 406
  • 1
    jQuery has a built-in function to help: https://api.jquery.com/jQuery.escapeSelector/ ... eg: $("#"+$.escapeSelector(id)) where id might have special characters – dlo Jun 23 '20 at 20:09
15

You can also do

$('[id="something['+id+']"]')
Community
  • 1
  • 1
steampowered
  • 11,809
  • 12
  • 78
  • 98
9

Square brackets have special meaning to jQuery selectors, the attribute filters specifically.

Just escape these and it will find your element fine

$( "#something\\[" + id + "\\]" )
Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
Peter Bailey
  • 105,256
  • 31
  • 182
  • 206
9

An id cannot include square brackets. It is forbidden by the spec.

Some browsers might error correct and cope, but you should fix you data instead of trying to deal with bad data.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Thanks for the link to the spec. I realize that they're not valid ID's, but Rails adds them for convenience sake in the controller. – Mike Trpcic Aug 06 '09 at 14:29
  • 1
    Not just rails--many web apps use this trick, since it allows a form handler to iterate through an array, rather than divining a number of optional rows that have been submitted. – Bryan Agee Apr 23 '13 at 00:30
  • @BryanAgee — `id`s are not `name`s, and most form handler libraries use counting to iterate though multiple controls with the same name rather then special naming conventions or divination. – Quentin Apr 23 '13 at 04:59
  • @Quentin - true, but the spec you quoted specifically mentions both as having the same char requirements. – Bryan Agee Apr 23 '13 at 15:24
  • 2
    @BryanAgee — No it doesn't. The value of a `name` attribute isn't a `NAME` token. – Quentin Apr 23 '13 at 15:25
  • @Quentin -- oh right--because an id attr has to be an ID token, but a name attr is generally CDATA. – Bryan Agee Apr 23 '13 at 15:31
  • `id` attributes are `NAME` tokens. :) – Quentin Apr 23 '13 at 15:33
  • zend frameworks 2 adds square brackets as ID of subforms (fieldset) as a default – E Ciotti Aug 23 '13 at 12:03
  • 11
    Starting from HTML5 this is not true anymore. http://www.w3.org/TR/html5/dom.html#the-id-attribute. – Jiloc Sep 07 '15 at 17:47
4

Try this:

alert($("#something\\["+id+"\\]").parent()[0].parent()[0].attr("id"));
Tim S. Van Haren
  • 8,861
  • 2
  • 30
  • 34
4

You can escape them using \\ or you could do something like this...

$(document.getElementById("something[" + id + "]"))
Josh Stodola
  • 81,538
  • 47
  • 180
  • 227
3

"Any of the meta-characters

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

as a literal part of a name, it must be escaped with with two backslashes: \\.

For example, an element with id="foo.bar", can use the selector

$("#foo\\.bar")

" [source: jquery doc], and an element with id="foo[bar]" (even though not valid for W3C but recognised by JQuery), can use the selector

$("#foo\\[bar\\]")

(Just an asnwer like the many others, but all together :))

E Ciotti
  • 4,740
  • 1
  • 25
  • 17