How to detect specific attribute with specific text inside - javascript

I want to be able to specify that IF data-path == "USB/sda1-usb-SanDisk_Cruzer_B" then do code etc data-path is my attribute.
Any idea how to do this with JS? document.getelementbyid i dont think has the extension for it but perhaps im wrong? I couldnt find anything anywhere for it.
I also know that you can use:
document.getElementById("db-1").hasAttribute("data-path");
But thats if it has it which it does but i want to check inside and match.
Thanks!

try the getAttribute method
var attrValue = document.getElementById("db-1").getAttribute("data-path");
if ( attrValue == "USB/sda1-usb-SanDisk_Cruzer_B" )
{
//your code here
}

This way ?
let path=document.getElementById("db-1").dataset.path;
if(path==="USB/sda1-usb-SanDisk_Cruzer_B"){
//do stuff
}

The HTMLElement.dataset property allows access, both in reading and writing mode, to all the custom data attributes (data-*) set on the element. It is a map of DOMString, one entry for each custom data attribute.
Code:
var el = document.getElementById('db-1');
if (el && el.dataset.path === 'USB/sda1-usb-SanDisk_Cruzer_B') {
// Your code...
}

Related

Compare variable against test strings

Here is my JQuery Code and I would like to compare the text in the text variable "text" to the possible CR Status (e.g. Approved Implemented), but I don't know how to do it.
_spBodyOnLoadFunctionNames.push("colouring");
function colouring(){
var $th = $("div[Name='CR_x0020_Status']").parent().css("background-color","#66CD00");
var $index = $th.index();
$th.parent().parent().children(".ms-itmhover").each(function(index, elem) {
var $div = $($(this).children("td").get($index));
var text = $div.text();
$("text:contains('Approved')").css("background-color","#66CD00");
})
}
I tried different options, but I still don't know how to do it!
Best regards and thank you in advance
Matthias
You can't put variables in jQuery selectors. $("text:contains(Approved)") means an element with tag text that contains Approved. You could write:
if (text.indexOf('Approved') > -1)
But you don't need the .each() loop at all, you can do it all with jQuery selectors:
$th.parent().parent().find(".ms-itmhover > td:contains(Approved)").css("background-color", "#66CD00");
Hard to tell exactly what you need, but possibly:
if(text == "Approved Implemented"){
...do more stuff here...
}
Possibly, you just need to duplicate the existing line and modify it for another colour:
$("text:contains('Approved')").css("background-color","#66CD00");
$("text:contains('Approved Implemented')").css("background-color","#0066CD");

How to verify and traverse XML with JavaScript. Really no better way?

I'm doing a simple jQuery.get call to api.facebook.com to retrieve the number of likes for a URL. The result is in XML (which is unexpected in itself, but not the point here). The response looks like this:
<links_getStats_response xmlns=​"http:​/​/​api.facebook.com/​1.0/​" xmlns:xsi=​"http:​/​/​www.w3.org/​2001/​XMLSchema-instance" xsi:schemaLocation=​"http:​/​/​api.facebook.com/​1.0/​ http:​/​/​api.facebook.com/​1.0/​facebook.xsd" list=​"true">​
<link_stat>​
<url>​godfisk.no/fiskenasjonen​</url>​
<normalized_url>​http://www.godfisk.no/fiskenasjonen​</normalized_url>​
<share_count>​35​</share_count>​
<like_count>​402​</like_count>​
<comment_count>​10​</comment_count>​
<total_count>​447​</total_count>​
<click_count>​0​</click_count>​
<comments_fbid>​676768902366174​</comments_fbid>​
<commentsbox_count>​0​</commentsbox_count>​
</link_stat>​
</links_getStats_response>​
To traverse this tree and get to the text content of the <like_count> element, I'm doing this:
data.firstChild.childNodes[1].childNodes[7].textContent;
This bring me back to the way XML was handled in AS3 prior to E4X. I cannot help but feel that this is pretty vulerable, so I decided it would be a good idea to validate the integrity of the returned data before accessing it. That leaves me with this Christmas tree compound if-statement:
if (data
&& data.childNodes.length > 0
&& data.firstChild.childNodes.length > 1
&& data.firstChild.childNodes[1].childNodes.length > 7
&& data.firstChild.childNodes[1].childNodes[7].textContent) {
// OK, we're good, go ahead..
}
Really??
What you need to do is use XPath, so for example to get to like_count element in your example:
var elem = data.selectSingleNode('/links_getStats_response/link_stat/like_count'); // assign the element
var value = elem.nodeValue; // to get the element value
for more information on XPath, please see the following link
A bit cheeky, but really the better option since I'm already using jQuery:
var numLikes = $('like_count', data).text();
Or if trying to avoid jQuery at all costs:
var numLikes = xml.querySelector('like_count').textContent;

How to know if an element, created dynamically, exist?

I have this simple function:
var x = document.createTextNode("ERROR");
document.body.appendChild(x);
So then I need to create an IF to verify if this message exist [If this message has been created]. This is the problem, I don't know how to do that.
GetElementByID seems to don't work with element created by dynamically.
Any help? Thanks.
You can use document.contains to check if a element is in the DOM
Just a quick example of how it works
document.contains($('<div>')[0]); // FALSE
And
document.contains($('<div>').appendTo('body')[0]); // TRUE
jQuery only used for a shorthand to element creation
This also works for text nodes and you can use contains on any node.
document.body.contains(Node); // Example
The browser support is somewhat very good
Documentation: https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
Question specifics:
var x = document.createTextNode("ERROR");
document.body.appendChild(x);
document.contains(x); // Should be TRUE
You are creating a text node, not an element. You need to create an element and give it an id to be able to use getElementById.
I don't know of any reasonable way to search for a text node, although you could always check the text nodes of the element you attached it to and see if it's there.
var message = "ERROR";
var t = document.createTextNode(message);
var node = document.getElementById('content').appendChild(t);
if (document.getElementById('content').innerHTML !== message) {
console.log('element not added');
} else {
console.log('element added');
}
Here is a fiddle:
http://jsfiddle.net/btipling/rBg4w/
I believe this would work:
var x = document.createTextNode("ERROR");
var element = document.body.appendChild(x); //returns text node
if(!element){
//element was not added
}
although if I were you I might create a span element with an id or a class called error. This way you can apply any css styles to it.
Try this:
var x = document.createTextNode("ERROR");
document.body.appendChild(x);
if (document.body.innerText.indexOf('ERROR')>=0){
alert('"ERROR" found');
}
indexOf doesn't work in all browsers.
As #slowpython said I'd rather create a DOM element with ID or NAME.

HTML DOM element name as a string

Suppose I have the following HTML snippet:
<input type="text" id="myinput" />
Now I want to get that DOM element using JavaScript:
var element = document.getElementById("myinput");
Works fine, no problem so far.
But when I print it inside an alert box using alert(element);, it displays object HTMLInputElement.
Is there a way to get that element name (HTMLInputElement) as a string?
(Notice that when saying "element name" I do not mean the name attribute of an element, but the name how it is displayed when using alert() for example, as described above.
In some browsers, such as Firefox (and Chrome, potentially others) you can do:
element.constructor.name; // => "HTMLInputElement"
But in general it's a bit more complicated, perhaps not even totally reliable. The easiest way might be as such:
function getClassName(o) {
// TODO: a better regex for all browsers...
var m = (o).toString().match(/\[object (.*?)\]/);
return (m) ? m[1] : typeof o;
}
getClassName(element); // => "HTMLInputElement"
getClassName(123); // => "number"
[Edit]
Or, using the "nodeName" attribute, you could write a utility function which should be generally much more reliable:
function getHtmlElementClassName(htmlElement) {
var n = htmlElement.nodeName;
if (n.matches(/^H(\d)$/)) {
return "HTMLHeadingElement";
} else if (/* other exceptional cases? */) {
// ...
} else {
return "HTML" + n.charAt(0) + n.substr(1).toLowerCase() + "Element";
}
}
(Thanks #Esailija for the smarter implementation, #Alohci for pointing out exceptional cases.)
alert(element.nodeName);
https://developer.mozilla.org/En/DOM/Node.nodeName
When passing an object to the alert() function, it implicitly calls .toString() on that object in order to get the text for the alert. You could do something like:
var element = document.getElementById("myInput");
var string = element.toString(); // this will return 'object HTMLInputElement'
then work with the string variable to get only the HTMLInputElement part.
if I've got the question correctly you should try document.getElementById("myinput").toString().
document.getElementById returns the HTML element as an object. Simply get the attribute of the object you want to display in the alert instead (e.g., alert(element.getAttribute('ID'));). Alternatively, if you want '[object HTMLInputElement]' displayed in the alert, simply call the toString() method on the object in the alert (e.g., alert(element.toString());).
Hope this helps,
Pete

Setting properties on anonymous DOM elements through JavaScript?

Let's say I'm generating markup through server-side code. I'm generating a bunch of HTML tags but I want to add custom client-side behavior.
With JavaScript (if I had a reference to the DOM node) I could have written:
var myDOMNode = ...
myDOMNode.myCustomAttribute = "Hi!";
Now the issue here is that I don't want to qualify every element with an unique id just to initialize data. And it's really strange to me, that there's not an easier and unobtrusive way to attach client-side behavior.
If I'm remembing this correctly, this is valid IE stuff.
<div onload="this.myCustomAttribute='Hi!'"></div>
If I was able to do this, I should be able to access it's "data context" though the identifier 'myCustomAttribute', which is really what I want.
The following will work but not validate:
<div myattribute="myvalue"></div>
But if you are injecting it into the HTML with Javascript, then perhaps that's not concern for you. Otherwise, you can use something like jQuery to process the elements before adding them to the DOM:
$(elements).each(function(){
$(this).attr('myattribute','myvalue');
});
First off you should access custom attributes using the getAttribute and setAttribute methods if you want your code to work on other browsers than IE.
As to your event handler question that really depends on how you add the event handler.
Assigning a function directly to the elements onXXXX property would allow you access the the element via this.
If you use IE's attachEvent you can't use this, you can access the element that generated the event using event.srcElementbut that may be child element of the div. Hence you will need to test for the existance of myCustomAttribute and search up the ancestors until you find it.
I do appricate the input but I've finally figured this out and it's the way I go about initialization that has been the thorn in my side.
What you never wan't do is to pollute your global namespace with a bunch of short lived identifiers. Any time you put id="" on an element you're doing exactly that (same thing for any top level function). By relying on jQuery, HTML5 data and CSS there's a solution to my problem which I think is quite elegant.
What I do is that I reserve a CSS class for a specific behavior and then use HTML5 data to parameterize the behavior. When the document is ready, I query the document (using Query) for the CSS class that represents the behavior and initialize the client-side behavior.
I've been doing a lot of ASP.NET and within this context both the id="" and name="" belongs to ASP.NET and is pretty useless for anything else than internal ASP.NET stuff. What you typically find yourself doing is to get at a server-side property called ClientID you can refer to this from client-side JavaScript, it's a lot of hassle. They made it easier in 4.0 but fundamentally I think it's pretty much broken.
Using this hybrid of CSS, HTML5 data and jQuery solves this problem altogether. Here's an example of an attached behavior that uses regular expressions to validate the input of a textbox.
<input type="text" class="-input-regex" data-regex="^[a-z]+$" />
And here's the script:
$(function () {
function checkRegex(inp) {
if (inp.data("regex").test(inp.val()))
inp.data("good-value", inp.val());
else
inp.val(inp.data("good-value"));
}
$(".-input-regex")
.each(function () {
// starting with jQuery 1.5
// you can get at HTML5 data like this
var inp = $(this);
var pattern = inp.data("regex");
inp.data("regex", new RegExp(pattern));
checkRegex(inp);
})
.keyup(function (e) {
checkRegex($(this));
})
.change(function (e) {
checkRegex($(this));
})
.bind("paste", undefined, function (e) {
checkRegex($(this));
})
;
});
Totally clean, no funky id="" or obtrusive dependency.
In HTML5 there are HTML5 data attributes introduced exactly for the case.
<!DOCTYPE html>
<div data-my-custom-attribute='Hi!'></div>
is now corect, validating html. You can use any name starting with data- in any quantity.
There is jQuery .data method for interaction with them. Use .data( key ) to get, .data(key, value) to set data-key attribute. For example,
$('div').each(function () {
$(this).html($(this).data('myCustomAttribute')).data('processed', 'OK');
});
How about this?
<script>
function LoadElement(myDiv)
{
alert(this.myCustomAttribute);
}
</script>
<div onload="LoadElement(this)"></div>
not tested btw
Since you're trying to do this for multiple elements, you may try name attributes and getElementsByName.
<div name="handleonload">...</div>
window.onload = function () {
var divs = document.getElementsByName('handleonload');
for (var i = 0; i < divs.length; i += 1) {
divs[i].foo = 'bar';
}
};
Alternatively, you can use selectors, using libraries (such as jQuery and Prototype) and their respective iterators. This will also allow for you to search by other attributes (such as class).
Though, be cautious with your terminology:
obj.property = value;
<tag attribute="value">
<div style="width:100px;height:100px;border:solid black 1px" myCustomAttribute='Hi!' onclick="alert(myCustomAttribute);"></div>
The onload event is used for server side events. Its not part of the standard html element events.
Take a look at the following functions (especially the walk_the_dom one):
// walk_the_DOM visits every node of the tree in HTML source order, starting
// from some given node. It invokes a function,
// passing it each node in turn. walk_the_DOM calls
// itself to process each of the child nodes.
var walk_the_DOM = function walk(node, func) {
func(node);
node = node.firstChild;
while (node) {
walk(node, func);
node = node.nextSibling;
}
};
// getElementsByAttribute takes an attribute name string and an optional
// matching value. It calls walk_the_DOM, passing it a
// function that looks for an attribute name in the
// node. The matching nodes are accumulated in a
// results array.
var getElementsByAttribute = function (att, value) {
var results = [];
walk_the_DOM(document.body, function (node) {
var actual = node.nodeType === 1 && node.getAttribute(att);
if (typeof actual === 'string' &&
(actual === value || typeof value !== 'string')) {
results.push(node);
}
});
return results;
};
With the above two functions at hand, now we can do something like this:
some link
<script>
var els = getElementsByAttribute('dreas');
if (els.length > 0) {
els[0].innerHTML = 'changed text';
}
</script>
Notice how now I am making finding that particular element (which has an attribute called dreas) without using an id or a class name...or even a tag name
Looks like jQuery is the best bet for this one based on my searching. You can bind an object to a DOM node by:
var domNode = ...
var myObject = { ... }
$(domNode).data('mydata', mymyObj);
then you can call the data back up the same way, using your key.
var myObect = $(domNode).data('mydata');
I assume you could also store a reference to this within this object, but that may be more info then you really want. Hope I could help.

Categories

Resources