boony
boony

Reputation: 87

Accessing a childNode or sibling attributes after click event fired on button in JavaScript NOT JQuery

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

Answers (2)

Tim Heap
Tim Heap

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

kberg
kberg

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

Related Questions