Gene
Gene

Reputation: 134

Dynamically created buttons, need to pass in different value to onlick function in foreach loop

What I am doing:

I am looping through an array jsarray and creating buttons that will be a delete button (one button created for each element in the array). I am incrementing a variable i in each loop, which will be the value of the index of the array for that button. For example, the second button created in the loop should get the value 2 passed into its onclick function parameters and so on.

Background on the code:

jsarray contains id's of Tweets which will later be embedded into my webpage. The tweets are being embedded in a forEach loop and I want to create the buttons in the same loop.

The buttons' onclick call a function deleteTweet() that takes in a jsarray's index, so that the next loop to embed will not have the deleted tweet in it.

Here is my deleteTweet() function:

          function deleteTweet(x)
          {
            console.log("deleteTweet was called"+x)
            var index = jsarray.indexOf(x);
            jsarray.splice(index, 1);
            console.log(jsarray[x] + "was deleted");
            return jsarray;
          }

Here is the function that embeds the tweets and creates the delete buttons:

          function embedTweets()
          {
            console.log("the embed tweets function has been called.")
            var i = 0;
            var docFrag = document.createDocumentFragment();
            jsarray.forEach(function(id)
            {

              twttr.widgets.createTweet(
                id, document.getElementById('container'),
                {
                  conversation : 'none',    // or all
                  cards        : 'hidden',  // or visible
                  linkColor    : '#' + background_color, // default is blue
                  theme        : 'light',    // or dark
                  align        : 'center'
                }
              );
              var delButton = document.createElement('button');
              docFrag.appendChild(delButton);
              delButton.innerHTML = "DELETE TWEET"+i;
              delButton.onclick = function(){
                deleteTweet(i);
              }
              i++;
            });
            document.body.appendChild(docFrag);
          }

My problem:

For all of the buttons created in this loop, they all pass index 50 to the deleteTweets function on their click action. I know this is happening because the definition passes i and when it's done it is equal to 50.

How do I give each button the parameter value i at the current loop. As in, button: "DELETE TWEET9" actually passed in the value 9 to deleteTweet() instead of always the last item in the array.

Simplified:

array = ['1', '2', '3', '4']

    var i = 0;
    docFrag = document.createDocumentFragment();

    array.forEach(function(id)
    {
      var delButton = document.createElement('button');
      docFrag.appendChild(delButton);
      delButton.innerHTML = "DELETE TWEET" + i

      //This is the problem area:
      delButton.onlick = function(){
        deleteTweet(i);
      }
      i++;
    });
    document.body.appendChild(docFrag);

To reiterate, all of the buttons I create in this loop execute deleteTweet(*max of array*) I want it to be the value of i at the time of the loop.

Upvotes: 2

Views: 2188

Answers (1)

b-frid
b-frid

Reputation: 108

I believe this is due to a closure issue. You don't need to create your own indexer(i.e. var i). You can instead pass a second variable to forEach which will be the index into the array at each iteration (see forEach). Try this instead:

array = ['1', '2', '3', '4']

docFrag = document.createDocumentFragment();

array.forEach(function(id, i)
{
  var delButton = document.createElement('button');
  docFrag.appendChild(delButton);
  delButton.innerHTML = "DELETE TWEET" + i

  //This is the problem area:
  delButton.onlick = function(){
    deleteTweet(i);
  }
});
document.body.appendChild(docFrag);

Upvotes: 1

Related Questions