Reputation: 87
I'm having a problem in understanding how to get attributes in this situation. Imagine I have an UL of images and buttons in this markup. Note that the idea would be for these items to be dynamically generated from a mysql database.
<div id="div-items">
<ul>
<li name="add" data-price="20"><figure><img src="images/Desert.jpg" width="50%" height="50%"><figcaption><button class="btn btn-primary">Add Item</button></figcaption></figure></li>
<li name="add" data-price="10"><figure><img src="images/Penguins.jpg" width="50%" height="50%"><figcaption><button class="btn btn-primary">Add Item</button></figcaption></figure></li>
<li name="add" data-price="15"><figure><img src="images/Jellyfish.jpg" width="50%" height="50%"><figcaption><button class="btn btn-primary">Add Item</button></figcaption></figure></li>
</ul>
I am setting an eventListener to each button for each li item as so:
var addItems = document.getElementsByTag('button');
addItemsLen = addItems.length;
var mycount = 0;
for (var i=0; i < addItemsLen; i++)
{
var thisitem = addItems[i];
thisitem.addEventListener("click", getPrice, false);
};
So, when a button click event is fired I want to be able to access the details of the li items. For instance I would like to be able to get the img src or the data-price. The getPrice function is this
function getPrice(e)
{
//I know this is the button but I want the li ???
var el = e.target;
var price = el.getAttribute("data-price");
alert(price);
}
But that does not work. I can see that the target is the button what I want is the li but is this a childNode or sibling of the button. I have tried a couple of things but can't work out what is needed in getPrice to get the data-price in the li...
NOTE: For all those JQuery gurus - Yes I know it can be done in JQuery...Please don't suggest JQuery I want a pure JavaScript solution
Hopefully someone can set me right here.
Upvotes: 1
Views: 368
Reputation: 1711
To solve this in pure JavaScript, you can try the following. You already have the button, so you need to find the nearest ancestor 'li' element:
var findParent = function(el, nodeName) { while (el !== null) { if (el.nodeName.toLowerCase() == nodeName) { return el; } el = el.parentNode; } return null; };
Then, rewrite the getPrice
function to find the ancestor li:
var getPrice = function(event) { var button = event.target; var li = findParent(button, 'li'); var price = li.getAttribute('data-price'); alert(price); };
EDIT: from here, if you need to access the image, you can use various techniques. If you are not concerned about compatibility with old IE (see http://caniuse.com/queryselector for more information), you can use querySelector
to find the child image:
var getPrice = function(event) { var button = event.target; var li = findParent(button, 'li'); var price = li.getAttribute('data-price'); alert(price); var image = li.querySelector('img'); var imageSource = img.getAttribute('src'); alert(imageSource); };
Upvotes: 1
Reputation: 2379
It's kind of hokey but this will work...
function getPrice(e)
{
var el = e.target;
var price = el.parentNode.parentNode.parentNode.getAttribute("data-price");
console.log(price);
}
In this case e.target
is the button which is nested a few layers deep in the <li>
tag. Since you're generating this list from the server, my personal preference would be to, change your HTML to be...
<div id="div-items">
<ul>
<li name="add" data-price="20"><figure><img src="images/Desert.jpg" width="50%" height="50%"><figcaption><button class="btn btn-primary" data-price="20">Add Item</button></figcaption></figure></li>
<li name="add" data-price="10"><figure><img src="images/Penguins.jpg" width="50%" height="50%"><figcaption><button class="btn btn-primary" data-price="10">Add Item</button></figcaption></figure></li>
<li name="add" data-price="15"><figure><img src="images/Jellyfish.jpg" width="50%" height="50%"><figcaption><button class="btn btn-primary" data-price="50">Add Item</button></figcaption></figure></li>
</ul>
If you do that you can keep your javascript the way you have it.
Upvotes: 0