0

What I'm trying to do is add a unique onclick on each button using parameters so I can identify each of the buttons when they are clicked, using function parameters.

function createProducts() {
    for(var i = 0; i < products.length;i++) {
        var li = document.createElement("li");
        li.className = "products";
        li.onclick = "purchase(" + i + ")";
        li.innerHTML = products[i][0] + "<span class=\"price\"> Klikk/s: " + products[i][1] + " Pris: " + products[i][2] + "</span>";
        document.getElementById("list").appendChild(li);
    }
}

function purchase(id) {
    alert(id);
}

I've tried

li.onclick = purchase(i);

And

li.onclick = "purchase(" + i + ")";

But none of these work.

0

2 Answers 2

2

You have a couple of choices. You can create a variable for your handler to close over that doesn't change (like i does). You can do that in your case with Function#bind:

function createProducts() {
    for(var i = 0; i < products.length;i++) {
        var li = document.createElement("li");
        li.className = "products";
        li.onclick = purchase.bind(li, i); // <====
        li.innerHTML = products[i][0] + "<span class=\"price\"> Klikk/s: " + products[i][1] + " Pris: " + products[i][2] + "</span>";
        document.getElementById("list").appendChild(li);
    }
}

Function#bind returns a function that, when called, will call the original with a specific this value (we're setting it to the element reference) and any arguments you passed bind (in our case, i). Since the value that gets bound is the value of i when we call bind, not when the click occurs, it doesn't change like i would.

Alternately, you can store the id on the element itself as an attribute, and then use that in your handler:

function createProducts() {
    for(var i = 0; i < products.length;i++) {
        var li = document.createElement("li");
        li.className = "products";
        li.setAttribute("data-id", i);
        li.onclick = purchase;
        li.innerHTML = products[i][0] + "<span class=\"price\"> Klikk/s: " + products[i][1] + " Pris: " + products[i][2] + "</span>";
        document.getElementById("list").appendChild(li);
    }
}

function purchase() {
    // Use this.getAttribute("data-id") here to get the value
}

Note that in both cases, we're using real function references, not strings. You can use functions with the onXyz properties on elements, or of course use the standard addEventListener (or attachEvent on old IE).

Sign up to request clarification or add additional context in comments.

1 Comment

I like the bind suggestion.
0

Try this in the li creation loop:

li.onclick = purchase;
li.dataset.index = i;

In the purchase event:

function purchase(id) {
    var index = this.dataset.index;
}

More about data attributes(dataset) here and here.

1 Comment

@timzand As TJ explained, you store the index in loop-time to an attribute called data attribute on your element. It will be available to reading anywhere, anytime in your element. So, inside the click event function you just read it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.