Bug Tracker

Modify

Ticket #143 (closed enhancement: fixed)

Opened 7 years ago

Last modified 14 months ago

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

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

Change History

comment:1 Changed 7 years ago by anonymous

  • Component changed from ajax to core

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

Fix proposal for the dot and colon problem

Changed 7 years ago by anonymous

Changed 7 years ago by anonymous

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

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

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.