jQuery: Unrecognized Expression (getting around this error) - javascript

jQuery("input[name=a.b.c]")
Executing this line using jQuery 1.10.2 or 1.9.1 results in the message:
"Syntax error, unrecognized expression: input:hidden[name=a.b.c]".
I understand the core problem which is that the dots are not escaped or quoted out. This would work:
jQuery("input[name='a.b.c']")
The constraint is that I do not have the ability to change the line of code with the bad selector. That line is produced by the website (which I don't own) and they don't give me the ability to change that.
However, they do allow me to add arbitrary JS files to the header of the page (which means I can use a different jQuery version or even edit the jQuery file). My question is whether anyone knows another way around this so that jQuery can cope without the quotes since I cannot change the bad code.
For those saying that I can just change the name, this doesn't help because the JS still throws an error because changing the name of the element doesn't fix the bad selector.
Thanks

The proper way of executing this selector is:
jQuery('input[name="a.b.c"]')
Obviously you need to edit the algorithm that creates this line, there's no way jquery will accept an invalid selector.

Take a look here.
How do I extend jQuery's selector engine to warn me when a selector is not found?
In your case I would do something like this.
var oldInit = $.fn.init;
$.fn.init = function(selector, context, rootjQuery) {
selector = fixItWithQuotes(selector, context, rootjQuery);
return new oldInit(selector, context, rootjQuery);
};
untested by me, but it should give you an idea.
Also, this might give you more ideas?
http://blog.tallan.com/2012/01/17/customizing-the-default-jquery-selector-behavior/
Hope that makes sense.

Why don't you change the name attribute yourself?
var el = $("input");
el.attr("name", el.attr("name").replace(/[\d\.]+/g, ""));
console.log(el.attr("name"));
Then change it back if you need to. jsFiddle here

Related

Javascript Find User

I have the below javascript to get the UserID from a online form. This script will go through IE DOM Explorer to find the valued. But when I run the script, it is totally ignoring my "If" statement. It is just providing a value for "NewAuthUserID", without considering the "if".
(function () {
var NewAuthUserID = "";
var UserId = $('tr.background-highlight:contains("REQUESTER PROFILE") + tr').children('td:contains("User ID:")+td').text();
if ('tr.background-highlight:contains("NEW AUTHORIZED INDIVIDUAL PROFILE:"') {
var NewAuthUserID = $('td:contains("User ID:")+td:eq(2)').text();
};
alert(UserId);
alert(NewAuthUserID)
})();
Firstly, I'd suggest to check out how the if statement works: https://www.w3schools.com/js/js_if_else.asp
You need the if statement conditional to return true or false. Right now you're TRYING to use jquery to select things but even that has a syntax issues. Not only that but once the syntax is fixed it STILL won't do what you're attempting to do because you're putting something that will always evaluate to true as the conditional. That jquery selector just returns a function, not a boolean like it looks like you're intending to do. Try this:
(function(){
var NewAuthUserID = "";
var UserId=$('tr.background-highlight:contains("REQUESTER PROFILE") + tr').children('td:contains("User ID:")+td').text();
if($('tr.background-highlight').text() == "NEW AUTHORIZED INDIVIDUAL PROFILE:")){
var NewAuthUserID=$('td:contains("User ID:")+td:eq(2)').text();
}
alert(UserId);
alert(NewAuthUserID)
})();
Notice how I'm snagging the text that you're trying to test against with jquery and expressing it with a conditional instead? In this manner, it will return the boolean: true/false which is what you need to get the if statement to trigger.
Also if you check your syntax, you were missing the $() wrapper around your if statement, but you have a string that looked like it was trying to snag text via jquery.
I suggest formatting your code a bit, this always helps to debug.
The problem is you are trying to use a jQuery selector in your if statement, but you didn't include the $ to evaluate jQuery. It's just evaluating a string, wich results in TRUE (basically doing this: if(true)), so the code block is executed.
Try this instead:
javascript: (function() {
var NewAuthUserID = "";
var UserId = $('tr.background-highlight:contains("REQUESTER PROFILE") + tr').children('td:contains("User ID:")+td').text();
if ($('tr.background-highlight:contains("NEW AUTHORIZED INDIVIDUAL PROFILE:"').length > 0) {
var NewAuthUserID = $('td:contains("User ID:")+td:eq(2)').text();
};
alert(UserId);
alert(NewAuthUserID)
})();
EDIT: I added the length > 0 check on the returned object. It's possible to accomplish this with OP's code, he was just missing those two pieces. :contains is not the same as .text() ==.
Off topic response:
The way you manage/select your nodes may require a lot of maintanance in the future and is prone to errors.
For example: tr.background-highlight:contains("REQUESTER PROFILE") + tr
In words: Get me the table-row after a table-row with hilighted background, that contains "REQUESTER PROFILE".
What if you'll have to add a row in between them? what if you'll need to select the row, wether it is hilighted or not? what if further rows will be hilighted in the future, so that this selector ain't uniqu anymore? what if the label changes? maybe even the language? ...
In each of these cases you'll have to revisit (potentially all) your jquery selectors, just because some minor layout changed.
That's not very reliable.
Will you remember that when you'll get asked to do these changes? Maybe someone else will have to do these changes, will he/she know what to look for?
Tell me, do you remember the details/implications/quirks of the work you've done a week ago? not to speak about your work from a few months ago.
Better:
Use "unique" identifier to, well, identify your nodes by their role; and I'm not talking about IDs. Unique within their specific context.
The easiest way would be to use css-classes. Annotating the rows/cells so you can select the very same field as $('.ref-requester-provile .ref-user-id')
This is way more reliable and future-proof than your bulky $('tr.background-highlight:contains("REQUESTER PROFILE") + tr').children('td:contains("User ID:")+td') where your JS needs to know every little detail of your template/markup, and needs to be adapted with every little change.
Why did I prepend these classes with ref-? to distinct them from classes that are meant for styling
If you don't need to style these nodes and need these identifyer solely to reference them in your JS, I'd rather use a data-attribute. Why? Let's sum it up with:
performance: when you need to add/remove these marker; avoid unnecessary render-cycles
A cleaner seperation between style and code: classes are primarily for styling, but we don't style here.

jQuery validator gives error when a form element contains id with some special symbols. 'Unrecognized expression'

I have a form with some elements that use ids wich special symbols like this:
id="$FormData[1]$PersonData[1]$PhysicalPerson[1]$PersonName[1]$Affix[#type='qualification' and #position='prefix'][1]cb"
I have a function getEscapedID(id) that I use to escape a problematic characters when I need to find an element using jquery selector:
var input = $("#"+getEscapedID(id)).
This is not a problem - when I try it, I get the exact needed element. But calling input.valid(); gives me an error:
Error: Syntax error, unrecognized expression: label[for='$FormData[1]$PersonData[1]$PhysicalPerson[1]$PersonName[1]$Affix[#type='qualification' and #position='prefix'][1]cb']
EDIT:
My question is whether it is possible to do something about it. If not, then I will consider simplifying ids.
The problem was that I used perhaps old jquery.validate.min.js script. When I tried the one from here, it works:
http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.js
Eventually the form's ids were changed because it was not valid according to http://validator.w3.org, so I doubt the problem was primarily in the plugin.

Why doesn't IE8 like this JS?

IE8 has been throwing this error at me
SCRIPT65535: Unexpected call to method or property access.
load-scripts.php, line 4 character 25690
I removed a .js file from the code, and the error went away. I started commenting functions out, and narrowed it down to this one. With this one commented, I don't get the error. With it active, I do get it
$("title, .ab-item").each(function() {
var text = $(this).text();
text = text.replace("RepAgent", "Review Scout");
$(this).text(text);
});
I've used JSHint and it says that it's valid?
I'm pretty sure that Internet Explorer doesn't like you messing with <title> element contents. That's not really how you set the document title anyway; just set document.title.
jQuery uses appendChild inside $.text() .
Although <title/> has a appendChild-method(inherited from HTMLElement), this method may not be used.(it's also not listed in the title-methods)

Javascript regex match fails on actual page, but regex tests work just fine

I have a very specific problem concerning a regular expression matching in Javascript. I'm trying to match a piece of source code, more specifically a portion here:
<TD WIDTH=100% ALIGN=right>World Boards | Olympa - Trade | <b>Bump when Yasir...</b></TD>
The part I'm trying to match is boardid=106121">Olympa - Trade</a>, the part I actually need is "Olympa". So I use the following line of JS code to get a match and have "Olympa" returned:
var world = document.documentElement.innerHTML.match('/boardid=[0-9]+">([A-Z][a-z]+)( - Trade){0,1}<\/a>/i')[1];
the ( - Trade) part is optional in my problem, hence the {0,1} in the regex.
There's also no easier way to narrow down the code by e.g. getElementsByTagName, so searching the complete source code is my only option.
Now here's the funny thing. I have used two online regex matchers (of which one was for JS-regex specifically) to test my regex against the complete source code. Both times, it had a match and returned "Olympa" exactly as it should have. However, when I have Chrome include the script on the actual page, it gives the following error:
Error in event handler for 'undefined': Cannot read property '1' of null TypeError: Cannot read property '1' of null
Obviously, the first part of my line returns "null" because it does not find a match, and taking [1] of "null" doesn't work.
I figured I might not be doing the match on the source code, but when I let the script output document.documentElement.innerHTML to the console, it outputs the complete source code.
I see no reason why this regex fails, so I must be overlooking something very silly. Does anyone else see the problem?
All help appreciated,
Kenneth
You're putting your regular expression inside a string. It should not be inside a string.
var world = document.documentElement.innerHTML.match(/boardid=[0-9]+">([A-Z][a-z]+)( - Trade){0,1}<\/a>/i)[1];
Another thing — it appears you have a document object, in which case all this HTML is already parsed for you, and you can take advantage of that instead of reinventing a fragile wheel.
var element = document.querySelector('a[href*="boardid="]');
var world = element.textContent;
(This assumes that you don't need <=IE8 support. If you do, there remains a better way, though.)
(P.S. ? is shorthand for {0,1}.)

Uncaught TypeError: Cannot call method 'get' of null

I know there are many threads about this issue and i ve been looking for my specific case but i have not found anything relevant.
I am implementing this javascript cashRegister effect in this page but i get this error msg
"Uncaught TypeError: Cannot call method 'get' of null"
It points to the raw 18 of the plugin.js:
var current_value = this.element.get('text');
What might cause this error? What i should try to do now?
Thanks
I think your problem is at this line:
var total = $('total');
The selector total means "find elements with the name 'total'". What you really want is to find the element with the id of "total," so do this instead:
var total = $('#total');
Edit:
I think some of the confusion stems from the fact that the $ in the site you're referencing is the $ from MooTools. In your page, you are including jQuery, which has an entirely different $ object that behaves differently. I believe that $('total') is how you select an element by ID in MooTools.
I'm not sure how you can load both libraries without having naming conflicts, but if you can figure that out, make sure you're using MooTools to select the total instead of jQuery.
Edit 2:
After a bit of research (I'm unfamiliar with MooTools), I see that you could replace $('total') with:
document.id('total')

Categories