Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Set .data() attribute equal to array index

I’m building a table dynamically with jQuery and I want to remove the item from the array when the remove button is clicked on that row. My current approach is to set the data id equal to the current array index and then using that value with the splice() method.

At the moment the remove button removes one or many items, and the last item won’t be removed because it says that the ‘index’ is undefined.

I’m very new at JavaScripr and jQuery so any insight and help will be appreciated.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here is my code.

$('.shoppingCart').ready(function loadCart() {
// Check to see if cart has items loaded
if (sessionStorage.getItem('cartItemsLoaded' === null)) {
    sessionStorage.setItem("shopCart", JSON.stringify(cart));
    sessionStorage.setItem("cartItemsLoaded", true);
} else {
    // Retrieve array from sessionStorage
    cart = JSON.parse(sessionStorage.getItem("shopCart"));
    cart = cart !=null ? cart : [];

    // Declare iterator
    let cartItems;
    // Loop over array objects with forEach and create <tr> for each object.
    $.each(cart, function (index, value) {
        // Create <tr> element to hold items
        cartItems = $("<tr>" +
            "<td>" + value.prod + "</td>" +
            "<td>R" + value.price + "</td>" +
            "<td>" + "<input type='number' class='form-control border border-dark rounded' id='qntCount' data-name=" + value.prod + " value='" + value.count + "'>" + "<label class='form-label' for='qntCount'>Qnt</label>" + "</td>" +
            "<td>" + "<div class='form-group'>" + "<input type='text' inputmode='numeric' class='form-control-plaintext border border-dark rounded' id='total' data-name=" + value.prod + " value='" + value.count * parseFloat(value.price) + "' disabled>" + "<label class='input-label' for='total'>Total</label>" + "</div>" + "</td>" +
            "<td>" + "<button class='btn btn-outline-danger removeBtn' data-id=' " + index + " '>" + "<i class='bi bi-cart-dash'></i>" + "</button>" + "</td>" +
            "</tr>");

// Used to check value of data-id.
            let i = $('.removeBtn').data('id');
            console.log(i);

        // Add eventListener to removeBtn
        $(".removeBtn").on('click', function removeProd() {
            let i = parseInt($(this).data('id'));
            // Remove object from cart at selected index
            cart.splice(i, 1);
            // Store current cart array
            sessionStorage.setItem("shopCart", JSON.stringify(cart));
            // Reload page
            location.reload();
        });

        $("#shpCart").append(cartItems);
        console.log(i);
        $("#shpCart").show();
    })
}
$(".cartTotal").html(cartTotal());

});

>Solution :

You bind the event to all the buttons on every iteration. You bind the event before you add the button to the DOM so it does not find the last one.

Reading your code out loud

  • Loop Start
  • Build TR (1)
  • Select all removeBtn on the page and add event (finds nothing)
  • Add row (1)
  • Show cart
  • Next Iteration
  • Build TR (2)
  • Select all removeBtn on the page and add event (finds 1)
  • Add row (2)
  • Show cart
  • Next Iteration
  • Build TR (3)
  • Select all removeBtn on the page and add event (finds 1, 2)
  • Add row (3)
  • Show cart

So with 3 rows.

  • First button has 2 click events attached
  • Second button has 1 click event attached
  • Third button has 0 click events attached

You need to bind the event AFTER you add all of the rows

$.each(cart, function (index, value) {
  // add the rows
});
$(".removeBtn").on('click', function {});
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading