Bug Tracker

Opened 13 years ago

Closed 13 years ago

Last modified 8 years ago

#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:
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)

jquery-1.0a.js.dotAndColon (37.9 KB) - added by anonymous 13 years ago.
Fix proposal for the dot and colon problem
jquery-1.0a.js.2.dotAndColon (37.9 KB) - added by anonymous 13 years ago.
jquery-1_0a-DotColon.js (37.9 KB) - added by anonymous 13 years ago.

Download all attachments as: .zip

Change History (17)

comment:1 Changed 13 years ago by anonymous

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 13 years ago by anonymous

Attachment: jquery-1.0a.js.dotAndColon added

Fix proposal for the dot and colon problem

Changed 13 years ago by anonymous

Changed 13 years ago by anonymous

Attachment: jquery-1_0a-DotColon.js added

comment:2 Changed 13 years ago by john

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 '.'.

comment:3 Changed 13 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 13 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 Changed 13 years ago by rbygrave

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.

comment:6 Changed 13 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 13 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 13 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

  1. jQuery claims to (mostly) implement CSS selectors and CSS does it that way
  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.

comment:9 Changed 13 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 Changed 13 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 ; Changed 13 years ago by brandon

Replying to brandon:

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

comment:12 in reply to:  11 Changed 13 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 13 years ago by john

Milestone: 1.1.3
need: Review
Resolution: fixed
Status: reopenedclosed
Type: bugenhancement
Version: 1.1.2

Fixed in SVN rev [1578].

comment:14 in reply to:  5 Changed 12 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?

Note: See TracTickets for help on using tickets.