Jason Mort
Jason Mort

Reputation: 69

How can I get something inside elements with same class?

I have basically this code. I'm adding buttons in a loop, and I want that when I click the button, it shows me the number that it's written. So, to do that I want to get the position of the button, for example if I click the first button it returns 0 so I can use this number to acess my array and get the number. How can I do that?

    var ar = [1,2,3];
    for(i = 0; i < 3; i++) {
        $("#add").append(
         '<div>'+
         'Hello ' +
         ar[i] +
         '<button class ="addx"> B </button>'+
         '</div>'
        )
    }

    $(".addx").click(function(){
    	alert($(this).text());
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="add"></div>

Upvotes: 2

Views: 53

Answers (5)

Tibrogargan
Tibrogargan

Reputation: 4603

The most straight forward way to do it would be to use Data Attributes, for example:

$(function() {
    var ar = [1,2,3];

    var html = "";
    for(i = 0; i < ar.length; i++) {
        html += `<div>Hello ${ar[i]}`+
        // using a data attribute called "num"
        `<button data-num=${ar[i]} class="addx">`+
        ` B </button></div>`;
    }
    $("#add").append($(html));

    $(".addx").click(function() {
        // "num" is available in the dataset property of the DOM element:
        console.log(this.dataset.num);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="add"></div>

Upvotes: 0

Roko C. Buljan
Roko C. Buljan

Reputation: 206024

Here's a nicer approach using functional programming (instead of manipulating DOM constantly inside a for loop)

const arr = [1, 2, 3];

const toElement = arrVal => $('<div/>', {
  text: `Hello ${arrVal}`,
  append: $('<button/>', {
    text: 'B',
    on: {
      click: function() {
        alert( arrVal );
      }
    }
  })
});

// Append once a collection of elements returned by mapping over an array
$("#add").append( arr.map(toElement) );
<div id="add"></div>

<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

Above we're passing a function toElement inside arr.map().
Map will create new elements for the length of the array, passing the currently iterating arrVal.
toElement will than implicitly return a jQuery DIV element with a BUTTON element as child, with a click handler assigned at creation. The entire array-collection of new elements is than .added to #add - once.


PS: Using other suggested solutions what happens is: on every loop iteration - go find #add element in DOM. Append a DIV. Relayout. Repaint. And again, for the length of your array. Once that's done go back find in the entire document elements with .addx class (which might not be the ones you expect) and attach a click event, which might happen to attach the same (duplicate) listener on the same element (in case of a repetitive operation).

Upvotes: 2

Taplar
Taplar

Reputation: 24965

You could potentially use the index of where the element is in relation to all the elements with the same class.

var ar = [1, 2, 3];
//using map to only append once.
$('#add').append($.map(ar, function(element){
  return `<div>Hello ${element} <button class ="addx"> B </button></div>`;
}));

var $addx = $('.addx');

$addx.click(function() {
  alert(ar[$addx.index(this)]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="add"></div>

Upvotes: 0

P.S.
P.S.

Reputation: 16384

If still following your way, we can give the data attribute to these buttons and add i from the loop as value, for example:

'<button class="addx" data-index="'+i+'"> B </button>'

This way your buttons will keep the index, which they had inside the loop, so you can easilly use this index to access array items at specific index. You can get the existing data from attribute like this (based on my HTML example earlier):

$(this).data('index')

Here is the working demo:

var ar = [1,2,3];
for(i = 0; i < 3; i++) {
$("#add").append(
    '<div>'+
    'Hello ' +
    ar[i] +
    '<button class="addx" data-index="'+i+'"> B </button>'+
    '</div>'
  )
}

$(".addx").click(function(){
  var index = $(this).data('index');
  alert($(this).text() + ", index is " + index + ". Arr value at this index is " + ar[index]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="add"></div>

Upvotes: 0

Jordan Soltman
Jordan Soltman

Reputation: 3873

You could store the button's index in the data attribute, and then when the button is clicked, fetch that index and go back to your original array to get the value.

var ar = [1, 2, 3];
for (i = 0; i < 3; i++) {
  $("#add").append(
    '<div>' +
    'Hello ' +
    ar[i] +
    '<button class ="addx" data-index='+i+'> B </button>' +
    '</div>'
  )
}

$(".addx").click(function() {
  const index = $(this).data('index');
  alert(ar[index]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="add"></div>

Upvotes: 0

Related Questions