Ticket #143 (closed enhancement: fixed)
'.'s in element ids
| Reported by: | anonymous | Owned by: | |
|---|---|---|---|
| Priority: | major | Milestone: | 1.1.3 |
| Component: | core | Version: | 1.1.2 |
| Keywords: | Cc: | ||
| Blocking: | Blocked by: |
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
Change History
Changed 7 years ago by anonymous
-
attachment
jquery-1.0a.js.dotAndColon
added
Fix proposal for the dot and colon problem
comment:2 Changed 7 years ago by john
- Status changed from new to closed
- Resolution set to wontfix
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 '.'.
comment:3 Changed 7 years ago by anonymous
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?
comment:4 Changed 7 years ago by anonymous
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.
comment:5 follow-up: ↓ 14 Changed 6 years ago by rbygrave
- Status changed from closed to reopened
- Resolution wontfix deleted
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.
comment:6 Changed 6 years ago by brandon
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.
comment:7 Changed 6 years ago by joern
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.
comment:8 Changed 6 years ago by cdonat
@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
- jQuery claims to (mostly) implement CSS selectors and CSS does it that way
- 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 .
- it can easily be implemented in jQuery.
comment:9 Changed 6 years ago by klaus
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.
comment:10 follow-up: ↓ 11 Changed 6 years ago by brandon
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
comment:11 in reply to: ↑ 10 ; follow-up: ↓ 12 Changed 6 years ago by brandon
Replying to brandon:
The regex should be: /^([#.]?)(([a-z0-9\*_-]|\:)*)/i
comment:12 in reply to: ↑ 11 Changed 6 years ago by john
Replying to 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?
comment:13 Changed 6 years ago by john
- Status changed from reopened to closed
- Resolution set to fixed
- Version set to 1.1.2
- Milestone set to 1.1.3
- need set to Review
- Type changed from bug to enhancement
Fixed in SVN rev [1578].
comment:14 in reply to: ↑ 5 Changed 6 years ago by aakoch
Replying to rbygrave:
if (el[0] == "#")
doesn't work in IE6. I use
if (el.charAt(0) == "#")
instead.
Exactly how was this fixed?
Please follow the bug reporting guidlines and use jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

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