22

Why do I get this error and how can I test for it so it wont break, I tried checking for null but obviously that wont work, thanks.

Please don't advice to not write the ID like this as I know its wrong but it is a possibility.

var jsonTest = [
  {
    "myId": "''''''\"\"\"\"'''''''''''''\"#####$'''''",
  }
];

alert(jsonTest[0].myId); 
// Works - alerts the myId

$('#' + jsonTest[0].myId ).length; 
// Error: Syntax error, unrecognized expression:
// #''''''""""'''''''''''''"#####$'''''
0

4 Answers 4

44

jQuery's uses this code to detect an id based selector :

characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+"
...
"ID": new RegExp( "^#(" + characterEncoding + ")" ),

This regex fails for "''''''\"\"\"\"'''''''''''''\"#####$'''''" or more simply for "'".

The query engine is limited, which isn't very surprising for a so concise language and id validity rules so lax. it can't handle any valid id.

If you really need to be able to handle any kind of valid id, use

$(document.getElementById(jsonTest[0].myId))

In fact, you should never use $('#'+id) as it simply adds a useless (and a little dangerous) layer of parsing for the same operation.

Sign up to request clarification or add additional context in comments.

3 Comments

Hashes escaping might also help.
@VisioN It wouldn't be enough.
Thanks dystroy that's an awesome solution
8

If I understood your question, you have an ID that contains special characters. You basically need to escape them so they're treated as literal characters rather than query selectors:

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

... and in this case you also need an additional escaping level for the string delimiter, ". It's crazy but this works:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript"><!--
jQuery(function($){
    console.log( $("#" + "\\'\\'\\'\\'\\'\\'\\\"\\\"\\\"\\\"\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\\"\\#\\#\\#\\#\\#\\$\\'\\'\\'\\'\\'").length );
});
//--></script>
</head>
<body>

<div id="''''''&quot;&quot;&quot;&quot;'''''''''''''&quot;#####$'''''">Foo</div>

</body>
</html>

Edit: Of course, dystroy's answer —omit jQuery selection engine and use getElementByID()— is way more practical. jQuery manual links an interesting blog entry that covers this and other related techniques:

document.getElementById() and similar functions like document.getElementsByClassName() can just use the unescaped attribute value, the way it’s used in the HTML. Of course, you would have to escape any quotes so that you still end up with a valid JavaScript string.

Comments

4

W3C has defined a new function for this this: CSS.escape(). In your example code, it would look like this:

var jsonTest = [
  {
    "myId": "''''''\"\"\"\"'''''''''''''\"#####$'''''",
  }
];

$('#' + CSS.escape(jsonTest[0].myId)).length; // Works 

Browsers don't yet support it, but there is a polyfill library that you can use in the mean time: https://github.com/mathiasbynens/CSS.escape

I've used it with success in my project.

Comments

0

I faced this error while upgrading from jquery 1.6 to jquery 3.6. I got this error in flexigrid library. The fix to this problem is simple as mentioned in above answers.

You need to escape all special characters and unescape them if needed to show in a grid or for further processing.

The code looks like:

var str = "[email protected]";

//make str value to, basically escape all special chars : "abc/@abc/.com"
str = str.replace(/[.*+?^$@%{}()|[\]\\]/g, '\\$&');

//do some processing

//revert str value to: "[email protected]"
str = str.replaceAll("\\", ""); 
                                    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.