Reputation: 4008
I have an HTML element with a data attribute:
<a href="#" data-trigger="{ "rem": "albatros", "ap":1 }'">Remove</a>
<div data-container>
<p>lorem ipsum<p>
<p data-rem></p>
</div>
1.
in the data-trigger
sometimes(not always) I send a value:
I want to gather all elements that have the attribute data-trigger
:
document.querySelectorAll(['data-trigger']).forEach(function (trigger, index) {
and for each of this trigger
to get the DOM and JSON value and parse it:
dom = trigger
value = JSON.parse(trigger.getAttribute('data-trigger'));
I get the DOM
reference but for the value I always get null
By using getAttribute
do I call again in the DOM ?
Looping thru data-container
search for elements which have the attributes one of the keys found in JSON.parse and set their value, the value of the key.
For example:
<p data-rem>albatros</p>
Upvotes: 0
Views: 1898
Reputation: 3765
This is not valid JSON String
<a href="#" data-trigger="{'rem': 'albatros'}">Remove</a>
Try:
<a href="#" data-trigger='{"rem": "albatros"}'>Remove</a> <!-- Double quotes in JSON -->
Then:
document.querySelectorAll("[data-trigger]").forEach(function (trigger, index) {
var val = JSON.parse(trigger.getAttribute('data-trigger'));
for( key in val){ //Loop through (JSON-)Object
setInnerElements(val[key], key);
}
});
function setInnerElements(val,key){
document.querySelectorAll("[data-container] > [data-"+ key +"]").forEach(function (el, index) {
el.innerHTML = val;
})
}
<a href="#" data-trigger='{"rem": "albatros", "foo":"test1", "bar":"test2"}'>Remove</a>
<div data-container>
<p>lorem ipsum<p>
<p data-rem></p>
<p>lorem ipsum<p>
<p data-foo></p>
<p>lorem ipsum<p>
<p data-bar></p>
</div>
Upvotes: 2
Reputation: 90237
What is currently stopping your script in its tracks is the selector inside querySelectorAll()
.
It should be '[data-trigger]'
, not ['data-trigger']
.
After you fix it, you'll be able to get all elements with a data-trigger
attribute. However, the string you placed in data-trigger
attribute won't parse as a JavaScript object (as you probably expect). Your best bet would be to replace quotes with double quotes and double quotes with quotes, making it a valid JSON string and parse it:
<a href="#" data-trigger='{"rem": "albatros"}'>Remove</a>
JSON.parse(elem.getAttribute('data-trigger')) // where elem is the DOM element above
You haven't been exactly clear on what the purpose of this script is but, assuming you want to find a list of DOM elements having 'data-'+foundKey
equal to foundVal
, you could make the following selector:
document.querySelectorAll('[data-'+foundKey+'="'+foundVal+'"]').forEach(function(el, i){
console.log(el, i);
})
... but in your case that wouldn't do anything, because you don't have any element with
<x data-rem="albatros"></x>
Here's a working example of what I'm talking about, applied to your markup:
document.querySelectorAll('[data-trigger]').forEach(function (trigger, index) {
const triggerProp = JSON.parse(trigger.getAttribute('data-trigger')),
foundKey = Object.keys(triggerProp)[0],
foundVal = triggerProp[Object.keys(triggerProp)[0]],
targets = document.querySelectorAll('[data-'+foundKey+']').forEach(function(target, index) {
console.log(target, 'key:'+foundKey, 'val:'+target.getAttribute('data-'+foundKey));
});
})
<a href="#" data-trigger='{"rem": "albatros"}'>Remove</a>
<div data-container>
<p>lorem ipsum<p>
<p data-rem="test"></p>
</div>
Do note that it only works because the value of data-trigger
is valid JSON. If it were not, it would fail miserably. You could guard your script from this risk by a try/catch function that would test the value as JSON first. Another alternative is to use a library that parses relaxed JSON.
Upvotes: 2