Parsing XML with namespaces using jQuery $().find - javascript

I'm trying to get the contents of a XML document element, but the element has a colon in it's name.
This line works for every element but the ones with a colon in the name:
$(this).find("geo:lat").text();
I assume that the colon needs escaping. How do I fix this?

Use a backslash, which itself should be escaped so JavaScript doesn't eat it:
$(this).find("geo\\:lat").text();

That isn't just an ordinary element name. That's a qualified name, meaning that it is a name that specifically refers to an element type within a namespace. The element type name is 'lat', and the namespace prefix is 'geo'.
Right now, jQuery can't deal with namespaces very well, see bug 155 for details.
Right now, as a workaround, you should be able to select these elements with just the local name:
$(this).find("lat").text();
If you have to distinguish between element types with the same local name, then you can use filter():
var NS = "http://example.com/whatever-the-namespace-is-for-geo";
$(this).find("lat").filter(function() { return this.namespaceURI == NS; }).text();
Edit: my mistake, I was under the impression that patch had already landed. Use Adam's suggestion for the selector, and filter() if you need the namespacing too:
var NS = "http://example.com/whatever-the-namespace-is-for-geo";
$(this).find("geo\\:lat").filter(function() { return this.namespaceURI == NS; }).text();

if you have a jquery selector problem with chrome or webkit not selecting it try
$(this).find('[nodeName=geo:lat]').text();
this way it works in all browsers

Related

Can jQuery event namespaces contain dashes?

Can jQuery event namespaces contain dashes (hyphens)? I have long namespaces and I want to separate them with dashes, is it possible? I didn't find any documentation on http://api.jquery.com/unbind/. Do you know where it's documented?
The code is something like this:
var close_menu_event_element = $('{selector}');
var event = 'click.our-top-menu'; // Can be also 'click.our-compose-menu'
if (close_menu_event_element.length > 0) {
close_menu_event_element.unbind(event);
if (typeof(func) === "function") {
close_menu_event_element.bind(event, func);
}
}
Update: bind and unbind work in Chrome 41.0.2272.101 m with namespaces with dashes, but I want to know if it works in any browser with jQuery? We are using jQuery 2.1.1.
I want to know if it works in any browser with jQuery
Yes, it will work in all major browsers without problems. All jQuery do to resolve namespaces is split selector string by . character. Something like this:
namespaces = ( tmp[2] || "" ).split( "." ).sort();
Nothing fancy here, split method will work everywhere, you can use - or # if you want in namespace substring.
Here is the best documentation: source code.
Not sure if jQuery gets the last word on this, but the answer is no according to the jQuery documentation for .on().
Namespaces should contain upper/lowercase letters and digits only.

Loop though DOM with jQuery to get some data- attribute value

This seems like a simple thing, but I keep getting "undefined"
I am trying out the "data-" HTML5 attribute and I am looping through a bunch of div tags that look like this:
<div id="myEvent"
data-scheduledOn="1399985100000"
data-eventStatus="3">
And I am looping through a bunch of these like this:
$('[id="myEvent"]').each(function(index, divItem) {
alert($(divItem).data("scheduledOn"));
}
But I keep getting "undefined" If I do this (get the attribute) it works fine:
alert($(divItem).attr("data-scheduledOn"));
So What am I missing?
http://api.jquery.com/data/
"The .data() method allows us to attach data of any type to DOM elements in a way that is safe from circular references and therefore from memory leaks."
At least at this point in time, to use the .data function you have to attach the data using the function before you can read it back using the .data function.
If you need to read pre-existing data use the .attr or .prop functions.
It seems as though It is a naming problem as Hamza Kubba suggested, but just a bit different...
if I changed the name of the data attribute to "data-scheduled-on" I can retrieve it by .data("scheduledOn") OR using data-scheduledon and .data("scheduledon") also works.
So don't use CAPS for data- names is the moral of this story!
Please note that per HTML 5 specs, the attribute name should not contain any uppercase letters and some browsers such as FF & Chrome will change any uppercase letter to lowercase. That's why the following demo works if you access the data attributes with lowercase names:
http://jsfiddle.net/fiddleyetu/5LdQd/
$('div.myEvent').each(function(index, divItem) {
console.log($(divItem).data("scheduledon"));
console.log( $(divItem).data("eventstatus") );
});
Ans since you cannot have more than one element on a page with the same ID, I have used a class selector for the demo.
MORAL: Do not use UPPERcase; your browsers may not always be that 'understanding'.

Array check element ID with wildcard in if statement

I can check an object ID in a array with
if (obj[0].id != "myID")
I would like to do the same with a wildcard, so that
if (obj[0].id != "myID*")
will exclude #myID1, #myID2, #myID3 etc.
I have to stay inside the if statement for this check, I can't call an external function.
If it is not possible, I can use obj[0].className instead of .id :
if (obj[0].className != "myClass")
but every object has several classes in addition of myClass.
jQuery is allowed although I'm not sure it will help.
If you're using jQuery (you've added the tag), why not use the selectors?
$('*:not[id^="myID"]')
This gets all the elements where the attribute does not start with myID. You can use this in your if statement like so:
if($(obj[0]).is('[id^="myID"]'))
First of all, you can definitely use an id attribute selector like this
if(!$(obj[0]).is("[id^=myID]"))
However, why not assign a class to all those elements instead? That sounds like a much more reasonable approach, allowing
if(!$(obj[0]).hasClass("myClass"))
Using String.prototype.indexOf might be one possible approach:
if (obj[0].id.indexOf('myID') !== 0) {
// ID does not start with 'myID'
}
You can even use regular expressions:
if( !/(myId)/g.test( obj[0].id.indexOf('myID') ) ) {
}
I can suggest you this really good playground to test you regexp:
http://lea.verou.me/regexplained/
And this talk:
http://www.youtube.com/watch?v=EkluES9Rvak
Regular expression can be very powerful. Maybe your case is not that hard to be managed with other tecniques but you would find regular expressions reeeally useful in the future for other problems.
You could check that the first 4 characters are myID with .substring():
if(obj[0].id.substring(0,4) != 'myId'){ }
If you wanted to use jQuery it would be really easy to check the id or class:
if(!$(obj[0]).is('[id^=myId]')){ }
or
if(!$(obj[0]).hasClass('myClass')){ }

jQuery, how to test of a variable is a text node, containing no markup?

http://jsfiddle.net/DerNalia/zrppg/8/
I have two lines of code that pretty much do the same thing
var doesntbreak = $j("hello");
var breaks = $j(" ");
​The first one doesn't error, but the second one throws this
Syntax error, unrecognized expression:
should'nt they both behave the same?
any insight as to how to solve this?
in the actual method I'm using, ele is from the Dom, so it could eb a text node, or any other kind of node.
UPDATE:
the input to the function that I'm using that I noticed this takes selection from the dom.
updated example: http://jsfiddle.net/DerNalia/zrppg/11/ <- includes html markup.
So, I guess, my question is, how do I test if something is JUST a text node? and doesn't contain any markup?
In general, you cannot create standalone text nodes with the jQuery function. If a string isn't obviously HTML, it gets treated as a selector, and is not recognized by jQuery as a valid selector.
Assuming you want to parse arbitrary strings (which may have HTML tags or not), I suggest something like var result = $('<div></div>').html(' ').contents();. Place your your HTML or text string in a div to parse it and then immediately extract the parsed result as a jQuery object with the list of elements. You can append the resultant list of elements with $(parentElem).append(result);
try this:
function isTextNode(node){
div=document.createElement('div');
div.innerHTML=node;
return $(div).text()==$(div).html();
}
And " " is'nt a valid selector if you want to find a elements containing some text you must use the :contains selector http://api.jquery.com/contains-selector/
Internet Explorer (older versions at least) don't have built in "querySelector" functions, so the Sizzle engine has to do the work directly. Thus, the slightly different tolerances for bogus input can cause differences in error reporting.
Your selector expression " " is equally invalid in all browsers, however. The library is not obliged to quietly accept anything you pass it, so perhaps you should reconsider your application design.
If you want to check for entities, you could use a regular expression if you're confident that it's just a text node. Or you could get the contents with .text() instead of .html().
So, I have to thank Apsillers and Rolando for pointing me in the right direction. Their answers were very close, but gave me the information I needed.
This is what I ended up using:
TEXT_NODE = 3;
objectify = function(n) {
return $j("<div></div>").html(n).contents();
}
function textOnly(n) {
var o = objectify(n);
for (var i = 0; i < o.length; i++) {
if (objectify(o[i])[0].nodeType != TEXT_NODE) {
return false
}
}
return true;
}
And here is a jsFiddle with some test cases, that neither of the original code submissions passed.
to pass, it needed to handle this kind of input
"hello" // true
"hello<b>there</b>" // false
"<b>there</b>" // false
" " // false
Not actual answer, but may help someone with similar issue as mine and loosely related to this question. :)
I was getting same issue today, so fixed by removing
Changed:
var breaks = $j(" ");
to:
var breaks = $j(" ".replace(/&.*;/g, ""));
Here I am removing , < etc...
Note: value at is dynamic for me, so it can be anything.

What does $$ mean in Javascript?

I am looking at some javascript code and it has this in a function:
$$('.CssClass').each(function(x) { .... } )
I get that the intent is to apply the anonymous function to each element with a class of CssClass, but I can't work what the $$ refers to ... and can't google for $$!
Update: thanks for the hints. The javascript comes from the iPhone look-alike library: jPint which includes the prototypejs library, and does define $$ as:
function $$() {
return Selector.findChildElements(document, $A(arguments));
}
Probably this prototype function:
$$(cssRule...) -> [HTMLElement...]
Takes an arbitrary number of CSS
selectors (strings) and returns a
document-order array of extended DOM
elements that match any of them.
http://www.prototypejs.org/api/utility#method-$$
$ is an ordinary symbol character, thus "$", "$$", "$$$" are ordinary variables.
the meaning of $ depends upon the libraries that are in use; in jQuery the $-function creates a jquery object from a css selector, e.g. $("DIV") is a collection of all DIVs in the current document.
Are you looking at a library such as mootools by chance? This is used as a short-hand to certain types of objects by accessing the DOM. They do things like $('myElement') to access page elements for example.
$ is a valid function name in javascript. So something defines a function $$ that takes a string looking for some class called .CssClass and returns a object where you call each on.
I know that jQuery defines a function called $ at least that does similar things.
Any chance you are looking at a MooTools script?
http://www.consideropen.com/blog/2008/08/30-days-of-mootools-12-tutorials-day-2-selectors/ (now owned by a domain grabber)
"The $$ lets you quickly select multiple elements and places them into an array (a type of list that lets you manipulate, retrieve, and reorder the list in all sorts of ways). You can select elements by name (such as div, a, img) or an ID, and you can even mix and match."
Most likely a shorthand function name that handles the DOM accessing of the specified arguments, whether tag name or object id.
As per above, you're likely in MooTools or jQuery.
In the browser's console, it is another way to write querySelectorAll().
Simply selects all the elements on the web page that you need and puts them in an array.
Practical examples:
Select all the elements and set an outline guide for debugging layouts [source]:
$$('*').map((A,B)=>A.style.outline=`1px solid hsl(${B*B},99%,50%`)
Print the image addresses for all the images on a webpage [source]
$$('img').forEach(img => console.log(img.src))

Categories

Resources