jQuery eq function unexpected behavior - javascript

I found a bug in a program I had written, but the behavior of the error is inexplicable to me:
If I have:
<input type="text" name="cust_id" value="666" />
<input type="text" name="phone[]" value="666" />
And then use this selector:
var test = $("input[name=phone[]]:eq(0)");
test.css("color", "red");
I see this:
What I'm surprised by is the fact that the eq(0) selects the first input even though I explicitly tell it to find only ones with name=phone[]
Here is a fiddle: https://jsfiddle.net/1xdnv1t8/
Is this expected behavior? Does the eq selector ignore attribute selectors?

You need to quote name attribute:
var test = $("input[name='phone[]']:eq(0)");
because phone[] is not valid name without quotes. So jQuery parser (or DOM) simply ignores everything invalid and treats selector as if it was simply input[name='phone']:eq(0). Also worth noting, that looks like this behaviour is fixed in more up to date versions of jQuery. You use pretty old 1.6.4 in your demo, but if you check it with 1.8.x and above it will work properly throwing error.
For example, if you try
try {
document.querySelector("input[name=phone[]]")
}
catch(e) {
alert(e.message)
}
it will even throw an error
Uncaught SyntaxError: Failed to execute 'querySelector' on 'Document': 'input[name=phone[]]' is not a valid selector.
But jQuery is more forgiving and it just selects whatever it can.

Use
var test = $("input[name='phone[]']:eq(0)");
JSFiddle
In the selector especification states
jQuery( "[attribute='value']" )
attribute: An attribute name.
value: An attribute value. Can be either an unquoted single word or a quoted string.

You are missing quotes around the attribute value. Try this -
var test = $('input[name="phone[]"]:eq(0)');

The square brackets in your selector confuse the attribute selection part as it is not quoted. Notice if you change the name of the second input to phone then it works as expected:
$("input[name=phone]:eq(0)")
Alternatively, wrap the attribute selector in quotes:
$("input[name='phone']:eq(0)")

While quoting the name attribute's value isn't strictly required (jQuery for the most part will work fine without them), as you noticed you can run into unusual situations when there are non-alphanumeric characters involved and jQuery interprets them as CSS notation.
The solution is to always properly escape any of these characters (:, ., [, ], etc.) as jQuery recommends, with two backslashes:
In order to tell jQuery to treat these characters literally rather
than as CSS notation, they must be "escaped" by placing two
backslashes in front of them.
So according to the jQuery documentation, you should be using var test = $("input[name='phone\\[\\]']:eq(0)"); as the selector (although simply properly quoting the string in your case will also work fine).
jsFiddle example
Ref: How do I select an element by an ID that has characters used in CSS notation?

Related

JQuery Unrecognized expression contains selector

I'm copying some code over from a project that used jQuery v1.11.2 to a new project which uses v3.1.0 and the following line of code doesn't work. I get an unrecognized expression error in the console:
$('#createEditTabs a[data-target=#tabEditConfig]').tab('show');
This line worked fine in the old project but fails to work in the new updated one. Not sure exactly why or if v3.1.0 has some differences when using contains selectors.
Wrap attribute value with quotes to avoid the issue with # in the beginning.
$('#createEditTabs a[data-target="#tabEditConfig"]').tab('show');
// -^-- --^-
The attribute value should be a valid identifier or quoted string. In your code, it's not a valid identifier(contains #) so use quoted string.

get dynamic id by partial match

im trying to get the id of an element that will be partially dynamic every time, separated by a colon. here is an example of what i mean:
<input type="text" id="j_id235:keyValue" />
the part after the colon is always the same, i need to somehow search by that only.
i've tried this:
console.log(document.querySelector('[id^=:keyValue]').id)
but am getting this error:
Uncaught SyntaxError: Failed to execute 'querySelector' on 'Document':
'[id^=:keyValue]' is not a valid selector.
: is a special character in selectors. If you want to match an attribute value that contains special characters, you have to quote the value.
Also note that ^= is the prefix selector. You probably want the suffix selector:
[id$=":keyValue"]
If you know the element type, it would probably make sense to use that as well:
input[id$=":keyValue"]
More information can be found in the CSS3 specification.

Javascript Split wont work when there are no characters to split

HTML
<div id="code1" data-code="123;12"></div>
<div id="code2" data-code="231"></div>
Jquery/Javascript
alert($("#code1").data("code").split(";")[0]);
alert($("#code2").data("code").split(";")[0]);
alert('test');
Since code2 does not have a ";", the code stops working all together. The last alert will not work nor will any code after the non-splitable code. How can I split code by ";" even when it may not have the ";" character?
data() will typecast a value to number if it is numeric
Try:
$("#code2").data("code").toString().split(';')
More about typecasting in the html 5 attributes section of data() docs
Use the following:
alert($("#code1").attr("data-code").split(";")[0]);
alert($("#code2").attr("data-code").split(";")[0]);
alert('test');
The reason that the second line fails is because the value is implicitly typecasted to a number by jQuery when using $.data. It has nothing to do with the implementation of String.prototype.split, since that returns an array with the 0th element being the full string if the delimiter does not exist.
In order to fix the problem, use $.attr instead of $.data to ensure that jQuery does not internally typecast the value to another type if it looks like another type.
Test on JSFiddle.

why jquery id selector not support special character

when using the special character to find the element like as below $("#search#") the exception will occur. how to resolve it?
I've tried using the all special character but it's working with * character like $("#search*") without any error, but others #$%^&() throw an error.So why it accepts the * character but why the other character doesn't.
If you have special character for ids, you should escape them using \\ (two backslashes) when you access them. But as far as I know this will only be allowed with html5.
As stated in jquery selector documentation
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").
alert($("#search\\$").html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="search$">Heh</div>
Try utilizing Attribute Equals Selector [name="value"]
$("[id='search#']").click(function() {
$(this).html(this.id)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="search#">click</div>
Many special characters are not allowed (Which characters are valid in CSS class names/selectors?).
A way to still select what you want, by looking for all but the special character(s) be seeing what some at the start, end, or contained somewhere within the tag's id.
Starts with: jQuery ID starts with
$('[id^="start-with"]')
Ends with: jQuery Selector: Id Ends With?
$('[id$="ending-part"]')
Contained somewhere within: jQuery ID Contains
$('[id*="any-spot-at-all"]')
There are others ways to "skin the cat" of course - some other selector options for example, to find only a part of a id or class or any other HTML tag attribute can be found at http://api.jquery.com/category/selectors/attribute-selectors/ .

Uncaught Error: Syntax error, unrecognized expression. Escaping characters?

I'm trying to show a div element with the id "online-payments" if a specific radio box is selected during the checkout process.
So far I have the following:
<div id="online-payments" style="display: none;">
Test
</div>
And for the javascript:
jQuery(document).ready(function(){
jQuery("radio[#name='payment\[method\]']").click(function(){
if (jQuery("radio[#name='payment\[method\]']:checked").val() == 'checkmo')
jQuery("#online-payments").show();
});
});
This is a Magento store so im using the no-conflict mode because of the prototype libraries.
The problem comes down to the radio's name. It's payment[method] by default on Magento (I've tried to change it, but it looks like it would give me more work than I had anticipated).
So it really comes down to escaping those brackets [ ], which I thought I did, but even then it's throwing me this error:
Uncaught Error: Syntax error, unrecognized expression: radio[#name='payment[method]']
What's wrong here?
Several problems there:
You're using an attribute selector, but with an invalid name (#name). Attribute names cannot start with #.
There's also no need for the backslashes as long as you use quotes (which you are, single quotes are fine). (And the ones you have aren't ending up as part of the selector, to put a backslash in a selector when the selector is in a JavaScript string, you have to escape the backslash as \\.)
radio isn't a tag name.
Perhaps you wanted:
jQuery("input[type=radio][name='payment[method]']")
jQuery offers an extension which is :radio, but using it isn't recommended, for the reasons discussed on its API page (basically, jQuery can't hand it off to the browser's native querySelector / querySelectorAll).

Categories