Skip to main content

Bug Tracker

Side navigation

#143 closed enhancement (fixed)

Opened August 27, 2006 01:33PM UTC

Closed March 25, 2007 02:04AM UTC

Last modified March 15, 2012 04:22PM UTC

'.'s in element ids

Reported by: anonymous Owned by:
Priority: major Milestone: 1.1.3
Component: core Version: 1.1.2
Keywords: Cc:
Blocked by: Blocking:
Description

$(Expression) does not find element

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

Attachments (3)
Change History (14)

Changed August 27, 2006 01:45PM UTC by anonymous comment:1

component: ajaxcore

oops... accidentally submitted the message while editing.

What I wanted to say:

$(Expression) does not find elements that contain a dot in their id, if you search like $("#foo.bar"). The same is true for the colon, I guess, as it also has a special meaning in the (really great!) jQuery lib.

The paragraph "ID and NAME..." in the original post was copied from

http://www.w3.org/TR/html4/types.html#type-name

Changed August 27, 2006 05:29PM UTC by john comment:2

resolution: → wontfix
status: newclosed

The period has special meaning in CSS - which is what jQuery implements. For example, try to write the CSS selector #foo.bar { ... } and it will completely not work. It is strange, though, that the CSS spec does only implement a subset of the HTML ID/NAME spec. Oh well.

The suggestion, up to this point, has been to use '-' instead of '.'.

Changed August 27, 2006 06:45PM UTC by anonymous comment:3

I implemented a fallback solution for jQuery.Select which tries to use the "foo.bar" as tagname (resp. id value) and if it does not find any matching elements falls back to the usual jQuery behaviour. Unfortunately, I cannot upload files using the "Attach File" button on this page, otherwise I would have posted it, but the patch is quite trivial anyway.

No chance to include such a fallback solution in the standard jQuery lib?

Changed August 27, 2006 07:09PM UTC by anonymous comment:4

FYI: In css you can escape the dot and the colon, like

#foo.bar { ... }

#foo:bar { ... }

But that's not a solution I'd like to see for jQuery, as this would require changes in some (many?) plugins, that work with ids, at least in the datepicker plugin, that I tried to use with a id that contains a dot.

Changed March 06, 2007 01:22AM UTC by rbygrave comment:5

resolution: wontfix
status: closedreopened

I want to use jQuery with Java Server Faces (JSF). JSF by default uses colons when naming elements which is not too helpful. ... id="formname:controlid"

I understand that this is currently considered a WONTFIX type bug.

I have come up with a possible workaround for my current issues and would like to know if it is reasonable. I am new to jQuery so this could be a silly thing to do??

The "PLAN" is to use $id() rather than $() when I am only finding a single element by its id.

example... the colon is not treated as part of the id (nothing found)

$("#formname:control").addClass("");

for me: I can change this to use my global $id function instead

$id("#formname:control").addClass("");

/**

$id returns a jQuery object using a 'normal' document.getElementById.

Note that this will return a jQuery object that contains an empty list if

no such object is found.

*/

function $id(el) {

var el = getById(el);

return el? $(el): $([]);

}

function getById(el) {

if (typeof el == 'string') {

if (el[0] == "#") el = el.substring(1);

el = document.getElementById(el);

}

return el;

}

Thanks for your consideration - Rob.

Changed March 07, 2007 02:03PM UTC by brandon comment:6

Perhaps we could do a quick id search before breaking it out into different selectors. If it finds an element, return it. Otherwise, do the typical search. It would add a couple of milliseconds to each request that starts with # but maybe worth it.

Changed March 08, 2007 10:14PM UTC by joern comment:7

How about another custom selector as a workaround, something like $("$my:id")

You can always fall back to your custom byID function that returns a jQuery object, but that is more limiting, I can't combine it with following selectors without great effors, eg.

$("$my:id div>ul") is way better then $id("my:id").find("div>ul")

The check-first-for-id-then-fall-back approach has obvious drawbacks:

<form id="form:first">

<div id="form">

Now what does $("#form:first") select? That isn't too unlikely.

Changed March 09, 2007 10:20AM UTC by cdonat comment:8

@anonymous

I don't see a reason, why that would need any changes in any plugins. if you write

$('#foo.bar')
or
$('#foo:bar')
everything will be as it is. Change it to
$('#foo.bar')
or
$('#foo:bar')
and jQuery can search for IDs with
.
or
:
inside, just as it is with CSS.

I think that using a

}}} as escape character is the best way to solve the problem, since[[BR]]
1. jQuery claims to (mostly) implement CSS selectors and CSS does it that way[[BR]]
2. most existing code that uses jQuery doesn't have a Problem with that change as long as you don't use {{{
as the last character in an ID or classname and append a custom selector to it. In those rare case you simply need to add another {{{}}}.

3. it can easily be implemented in jQuery.

Changed March 09, 2007 10:45AM UTC by klaus comment:9

From CSS 2.1 Spec:

In CSS 2.1, a backslash () character indicates three types of

character escapes.

[...]

Second, it cancels the meaning of special CSS characters. Any

character (except a hexadecimal digit) can be escaped with a backslash

to remove its special meaning. For example, """ is a string consisting

of one double quote. Style sheet preprocessors must not remove these

backslashes from a style sheet since that would change the style sheet's

meaning.

http://www.w3.org/TR/CSS21/syndata.html#q6

Thus, I think a selector like "#my:elem" is perfectly valid and that

should be part of jQuery's selector engine.

Changed March 09, 2007 02:19PM UTC by brandon comment:10

From Christof Donat via Discuss mailing list

To make the patch to jQuery as small as possible and let most existing code

continue to work: How about something like this: $('#my:elem') selects the

Element with the ID "my:elem" whereas $('#my:elem') selects the Element with

the ID "my" and uses :elem as custom selector. That could be achieved by

simply changing the regular expression, Manfred named to

/^(#.?)(([a-z0-9\\*_-]|\\:)*)/i

Changed March 09, 2007 02:21PM UTC by brandon comment:11

Replying to [comment:10 brandon]:

The regex should be:

 /^([#.]?)(([a-z0-9\\*_-]|\\:)*)/i 

Changed March 15, 2007 04:44PM UTC by john comment:12

Replying to [comment:11 brandon]:

We could very easily just make that "\\." and handle any special character. However, there's a big "gotchya" here. You can't just escape any character. For example: "#foo:bar" becomes just "#foo:bar" since JavaScript auto-escapes strings. You'd have to do: "#foo\\:bar" - which is downright horrible.

That being said, I like the idea of being able to escape the characters - I'm just not sure how it'd work best in practice. Is requiring "#foo\\:bar" acceptable?

Changed March 25, 2007 02:04AM UTC by john comment:13

milestone: → 1.1.3
need: → Review
resolution: → fixed
status: reopenedclosed
type: bugenhancement
version: → 1.1.2

Fixed in SVN rev [1578].

Changed July 26, 2007 09:31PM UTC by aakoch comment:14

Replying to [comment:5 rbygrave]:

if (el[0] == "#")

doesn't work in IE6. I use

if (el.charAt(0) == "#")

instead.

Exactly how was this fixed?