Assigning value from JSON attribute to innerHTML of an element - javascript

Hi guys i got an <a> tag which look like this:
<a class="js-swatch-item-link swatch__item-inner-image" data-layer-click="{"event":"interaction","interaction":{"category":"colorPattern","action":"Select","label":"DARK GREY MELANGE","value":"DARK GREY MELANGE"}}}" href="#">DARK GREY MELANGE</a>
I am trying to fetch the value of the interaction section of the JSON string, and then afterwards assigning this value to the innerHTML of the <a> tag.
My JavaScript code looks like this:
var SWATCH_COLOR_LINK = '.swatch.colorpattern a';
var swatchColorLink = document.querySelectorAll(SWATCH_COLOR_LINK);
var swatchColorTitle = JSON.parse(swatchColorLink.getAttribute('data-layer-click')).interaction.value;
for (var i = 0; i < swatchColorLink.length; i++) {
swatchColorLink[i].innerHTML = swatchColorTitle;
}
The function is giving me the following error: swatchColorLink.getAttribute is not a function
However if I try to just select the first element like this: document.querySelectorAll(SWATCH_COLOR_LINK)[0]
The function works fine and sets the right value from the JSON string to the innerHTML of the <a> tag.
Im guessing im doing something wrong in my loop to go over all <a> tags and assigning them the value of their JSON string.

Your mistake is laying in swatchColorLink.getAttribute(). Because your swatchColorLink's value is a NodeList which is returned from querySelectorAll() method. When you are doing document.querySelectorAll(SWATCH_COLOR_LINK)[0] you are getting the first element from this NodeList so in this case your swatchColorLink is the single node.
var SWATCH_COLOR_LINK = '.swatch.colorpattern a';
var swatchColorLink = document.querySelectorAll(SWATCH_COLOR_LINK);
for (var i = 0; i < swatchColorLink.length; i++) {
var swatchColorTitle = JSON.parse(swatchColorLink[i].getAttribute('data-layer-click')).interaction.value;
swatchColorLink[i].innerHTML = swatchColorTitle;
}

Correct your JSON string {"event":"interaction","interaction":{"category":"colorPattern","action":"Select","label":"DARK GREY MELANGE","value":"DARK GREY MELANGE"}}}
you should escape the quotes " in the string and remove the last }
<a class="js-swatch-item-link swatch__item-inner-image" data-layer-click="{\"event\":\"interaction\",\"interaction\":{\"category\":\"colorPattern\",\"action\":\"Select\",\"label\":\"DARK GREY MELANGE\",\"value\":\"DARK GREY MELANGE\"}}"href="#">DARK GREY MELANGE</a>

Related

How to get value of Paragraph element contained in <div> in HTML using JavaScript

I know this can be very basic but I'm very poor in using JavaScript.
Following is my HTML Code :
<div class="request">
<h4>Request a Free Consultation</h4>
<p>XXX-XXX-XXXX</p>
</div>
Using JavaScript, I want to get text contained in <p> element.
I am trying in the following way, but it's giving me undefined error.
var x = document.getElementsByClassName("request");
var pText = x.getElementsByTagName("P").innerHTML;
alert(pText);
Can anyone lead me in the right direction?
EDIT : Here is the fiddle link to try above code :
http://jsfiddle.net/Scoobler/ua9zN/
getElementsByClassName and getElementsByTagName return arrays. So you need to add indexes as well:
var x = document.getElementsByClassName("request");
var pText = x[0].getElementsByTagName("P")[0].innerHTML;
^ ^
alert(pText);
You can simply use querySelectorAll.
var pText = document.querySelectorAll('.request p')[0];
var x = document.getElementsByClassName("request");
The above line returns NodeList. It's like an Array, whose elements can be retrieved using the index. getElementsByTagName too returns the same.
for(var i = 0; i < x.length; i++)
alert(x[i].getElementByTagsName('p')[0].innerHTML); // [0] to get <p>

Replace string of text javascript

Im trying to replace a string of text for another string of text here is my code plus js fiddle
HTML
<div class="label">Rating:</div>
<div class="data rating">****</div>
Javascript
var str=document.getElementsByClassName("data" ,"raiting").innerHTML;
var n=str.replace(/\*/g,"star");
document.getElementsByClassName("data", "raiting").innerHTML=n;
Demo
http://jsfiddle.net/sgGQz/1/
document.getElementsByClassName() method returns, as its name suggests, a collection (HTMLCollection) of elements, not a single one -even if there's just a single element with the given classname(s) in DOM.
You need to go through each of them in order to make such a replacement. For example:
var elements = document.getElementsByClassName("data rating");
for (var i = 0, l = elements.length; i < l; i++) {
elements[i].innerHTML = elements[i].innerHTML.replace(/\*/g, 'star');
}
JSFiddle.
Alternatively, if you know for sure that there should be only a single element, you can assign it directly:
var elementToAdjust = document.getElementsByClassName("data rating")[0];
// ...
If you only have one occurrence of the element this will work:
var str=document.getElementsByClassName("data rating")[0].innerHTML;
var n=str.replace(/\*/g,"star");
document.getElementsByClassName("data rating")[0].innerHTML=n;
If multiple data rating elements exist use:
var elems =document.getElementsByClassName("data rating");
for(var i = 0; i < elems.length; i++){
elems[i].innerHTML = elems[i].innerHTML.replace(/\*/g,"star");
}
Both method correct some flaws in the original code.
First, rating was misspelled in the argument passed to getElementsByClassName. Second, getElementsByClassName() uses class names delimited by spaces to select elements with multiple classes, instead of multiple arguments. Get elementsByClassName returns an array of elements which must be iterated through.
JS Fiddle: http://jsfiddle.net/sgGQz/5/
You need to check again for getElementsByClassName,It returns node-List, so you can do like this and You can loop through then after each element and set your value
var str=document.getElementsByClassName("data" ,"raiting")[0].innerHTML;
var n=str.replace(/\*/g,"star");
document.getElementsByClassName("data", "raiting")[0].innerHTML=n;
Here is the example as you have only one occurance

Javascript innerHTML updating issue

I have the following JavaScript line:
<div id="box" name="1" margin="4px" padding="4px" onclick="memory(1)"></div>
With the associated memory() function being:
function memory(a) {
var tmpDar = a-1;
var m = document.getElementsByName(tmpDar);
m.innerHTML = arrA[tmpDar];
}
However, when I try executing the code, the HTML doesn't alter... Can somebody please help me?
document.getElementsByName() returns a NodeList and not a single element!
So in order to set the innerHTML of your div, you have to reference an entry inside that array, e.g., like this:
function memory(a) {
var tmpDar = a-1;
var m = document.getElementsByName(tmpDar);
m[0].innerHTML = arrA[tmpDar];
}
In your code you set the innerHTML property for the NodeList object, which has no (visual) effect in the document.
In general it would be better to use id instead of name. Then you could use document.getElementById() in a way like this:
function memory(a) {
var tmpDar = a-1;
var m = document.getElementById(tmpDar);
m.innerHTML = arrA[tmpDar];
}
document.getElementsByName returns an array. So if the element that you want is unique with this name, you should replace your code by :
function memory(a) {
var tmpDar = a-1;
var m = document.getElementsByName(tmpDar);
m[0].innerHTML = arrA[tmpDar]; // Here I have added index 0
}
your trying to find all elements with a name of 0 as far as I can tell. And there is no 0 name.
Also what the other two said, it returns an array you need to call an index on that array.

Javascript regex to replace text div and < >

var text='<div id="main"><div class="replace">< **My Text** ></div><div>Test</div></div>'
I want to replace div with class="replace" and html entities < > comes inside that div with some other text.
I.e the output :
'<div id="main"> Hello **My Text** Hello <div>Test</div> </div>'
I've tried
var div = new RegExp('<[//]{0,1}(div|DIV)[^><]*>', 'g');
text = text.replace(div, "Hello");
but this will replace all div.
Any help gratefully received!
If a Jquery solution is acceptable:
text = $(text) // Convert HTML string to Jquery object
.wrap("<div />") // Wrap in a container element to make...
.parent() // the whole element searchable
.find("div.replace") // Find <div class="replace" />
.each(function() // Iterate over each div.replace
{
$(this)
.replaceWith($(this).html() // Replace div with content
.replace("<", "<sometext>")
.replace(">", "</sometext>")); // Replace text
})
.end().html(); // return html of $(text)
This sets text to:
<div id="main"><sometext> My Text </sometext><div>Test</div></div>
And to replace it back again:
text = text.replace('<sometext>', '<div class="replace"><')
.replace('</sometext>', '></div>');
http://api.jquery.com/jquery/#jQuery2
http://api.jquery.com/each/
http://api.jquery.com/find/
http://api.jquery.com/html/
In pure JS it will be something like this:
var elements = document.getElementsByClassName('replace');
var replaceTag = document.createElement('replacetext');
for (var i = elements.length - 1; i >= 0; i--) {
var e = elements[i];
e.parentNode.replaceChild(replaceTag, e);
};​
Here is one crazy regex which matches what you want:
var text='<div id="main"><div class="replace">< **My Text** ></div><div>Test</div></div>'
var r = /(<(div|DIV)\s+class\s*?=('|")\s*?replace('|")\s*?>)(\s*?<)(.*?)(>\s*?)(<\/(div|DIV)\s*?>)/g;
The whole replacement can be made with:
text.replace(r, function () {
return 'Hello' + arguments[6] + 'Hello';
});
Please let me know if there are issues with the solution :).
Btw: I'm totally against regexes like the one in the answer...If you have made it with that complex regex there's probably better way to handle the problem...
Consider using the DOM instead; you already have the structure you want, so swap out the node itself (borrowing heavily from #maxwell's code, but moving children around as well):
var elements = document.getElementsByClassName('replace');
for(var i = elements.length-1; i>= 0; --i) {
var element = elements[i];
var newElement = document.createElement('replacetext');
var children = element.childNodes;
for(var ch = 0; ch < children.length; ++i) {
var child = children[ch];
element.removeChild(child);
newElement.appendChild(child);
}
element.parentNode.insertBefore(newElement,element);
element.parentNode.removeChild(element);
}
For each element of the given class, then, it will move each of its children over to the new element before using that element's position to insert the new element and finally removing itself.
My only questionmark is whether the modification of items in the array return by getElementByClassName will cause problems; it might need an extra check to see if the element is valid before processing it, or you may prefer to write this as a recursive function and process the tree from deepest node first.
It may seem like more work, but this should be faster (no re-parsing of the html after you've changed it, element moves are just reference value assignments) and much more robust. Attempting to parsing HTML may damage your health.
Rereading the question (always a good plan), you begin with the text in a string. If that is truly the start point (i.e. you're not just pulling that out of an innerHTML value), then to use the above just create a temporary parent element:
var fosterer = document.createElement('div');
fosterer.innerHTML = text; // your variable from the question
And then proceed using fosterer.getElementsByClassName.

Get element by id with regex

I had a quick question regarding RegEx...
I have a string that looks something like the following:
"This was written by <p id="auth">John Doe</p> today!"
What I want to do (with javascript) is basically extract out the 'John Doe' from any tag with the ID of "auth".
Could anyone shed some light? I'm sorry to ask.
Full story:
I am using an XML parser to pass data into variables from a feed. However, there is one tag in the XML document () that contains HTML passed into a string. It looks something like this:
<item>
<title>This is a title</title>
<description>
"By <p id="auth">John Doe</p> text text text... so on"
</description>
</item>
So as you can see, I can't use an HTML/XML parser for that p tag, because it's in a string, not a document.
Here's a way to get the browser to do the HTML parsing for you:
var string = "This was written by <p id=\"auth\">John Doe</p> today!";
var div = document.createElement("div");
div.innerHTML = string; // get the browser to parse the html
var children = div.getElementsByTagName("*");
for (var i = 0; i < children.length; i++)
{
if (children[i].id == "auth")
{
alert(children[i].textContent);
}
}
If you use a library like jQuery, you could hide the for loop and replace the use of textContent with something cross-browser.
No need of regular expressions to do this. Use the DOM instead.
var obj = document.getElementById('auth');
if (obj)
{
alert(obj.innerHTML);
}
By the way, having multiples id with the same value in the same page is invalid (and will surely result in odd JS behavior).
If you want to have many auth on the same page use class instead of id. Then you can use something like:
//IIRC getElementsByClassName is new in FF3 you might consider using JQuery to do so in a more "portable" way but you get the idea...
var objs = document.getElementsByClassName('auth');
if (objs)
{
for (var i = 0; i < objs.length; i++)
alert(obj[i].innerHTML);
}
EDIT: Since you want to parse a string that contain some HTML, you won't be able to use my answer as-iis. Will your HTML string contain a whole HTML document? Some part? Valid HTML? Partial (broken) HTML?
Perhaps something like
document.getElementById("auth").innerHTML.replace(/<^[^>]+>/g, '')
might work. innerHTML is supported on all modern browsers. (You may omit the replace if you don't care about removing HTML bits from the inner content.)
If you have jQuery at your disposal, just do
$("#auth").text()
What I want to do (with javascript) is
basically extract out the 'John Doe'
from any tag with the ID of "auth".
You can't have the same id (auth) for more than one element. An id should be assigned once per element per page.
If, however, you assign a class of auth to elements, you can go about something like this assuming we are dealing with paragraph elements:
// find all paragraphs
var elms = document.getElementsByTagName('p');
for(var i = 0; i < elms.length; i++)
{
// find elements with class auth
if (elms[i].getAttribute('class') === 'auth') {
var el = elms[i];
// see if any paragraph contains the string
if (el.innerHTML.indexOf('John Doe') != -1) {
alert('Found ' + el.innerHTML);
}
}
}
Assuming you only have 1 auth per string, you might go with something like this:
var str = "This was written by <p id=\"auth\">John Doe</p> today!",
p = str.split('<p id="auth">'),
q = p[1].split('</p>'),
a = q[0];
alert(a);
Simple enough. Split your string on your paragraph, then split the second part on the paragraph close, and the first part of the result will be your value. Every time.
If the content of the tag contains only text, you could use this:
function getText (htmlStr, id) {
return new RegExp ("<[^>]+\\sid\\s*=\\s*([\"'])"
+ id
+ "\\1[^>]*>([^<]*)<"
).exec (htmlStr) [2];
}
var htmlStr = "This was written by <p id=\"auth\">John Doe</p> today!";
var id = "auth";
var text = getText (htmlStr, id);
alert (text === "John Doe");

Categories

Resources