1

I am printing out an array of products to the screen. There is a delete button being printed along with each product. The code is as follows:-

const output = document.getElementById('output');

function delete_item(){
    var id = $(this).attr('data-id');
    console.log("ID " + id);
}

let productsArray = [];

$.getJSON('/products', products => {
    let outputContent = '';

    productsArray = Object.values(products);

    productsArray.forEach(product => {  
        outputContent += `<div data-id="${ product.ID }">
                          <div id='edit'><i class='fa fa-pencil-square-o' aria-hidden='true'></i></div>
                          <div id='delete'><i class='fa fa-trash-o' aria-hidden='true'></i></div>
                          <div id='product'> <span class='name'> <a href=''>${product.NAME}</a></span>
                          <span class='price'>Price: £${product.PRICE}</span>
                          </div>`;

    });

    $('#delete').click(function(){
        delete_item();
    });

    output.innerHTML = outputContent;
});

Currently, I would just like the delete_item function to print out the correct product id. However, the function is never invoked.

Is my .click() function within the scope of delete div, and why is the click() function not being called when clicking the delete div?

1
  • You also should create html dom elements before attach events to them. Commented Jun 1, 2017 at 11:49

3 Answers 3

3

You're adding multiple elements with the same id. The id should be unique in the document. Instead, use a class:

productsArray.forEach(product => {  
    outputContent += `  <div data-id="${ product.ID }">
                        <div class='edit'><i class='fa fa-pencil-square-o' aria-hidden='true'></i></div>
                        <div class='delete'><i class='fa fa-trash-o' aria-hidden='true'></i></div>
                        <div class='product'> <span class='name'> <a href=''>${product.NAME}</a></span>
                        <span class='price'>Price: £${product.PRICE}</span>
                        </div>`;

});

$('.delete').click(function(){
    delete_item($(this).parent().data("id"));
});

This will send the id to the function:

function delete_item(id){
    console.log("ID " + id);
}
Sign up to request clarification or add additional context in comments.

2 Comments

You didn't handle $(this).attr('data-id') inside delete_item() yet ...
Thanks, added that!
1

1. First of all same id for multiple element will not work when it come to jQuery, so convert id to class like below:-

<div class='delete'>

2. Use Event Delegation:-

$(document).on('click','.delete',function(){
  delete_item($(this).parent().attr('data-id')); // pass data-id to function
});

3. Change function like below:-

function delete_item(id){
    console.log("ID " + id);
}

4. Put delete function outside of $.getJSON().

So the full code is now like this:-

const output = document.getElementById('output');

function delete_item(id){ //change in function
    console.log("ID " + id);
}

let productsArray = [];

$.getJSON('/products', products => {
    let outputContent = '';

    productsArray = Object.values(products);

    productsArray.forEach(product => {  
    outputContent += `<div data-id="${ product.ID }">
                        <div id='edit'><i class='fa fa-pencil-square-o' aria-hidden='true'></i></div>
                        <div class='delete'><i class='fa fa-trash-o' aria-hidden='true'></i></div>
                        <div id='product'> <span class='name'> <a href=''>${product.NAME}</a></span>
                        <span class='price'>Price: £${product.PRICE}</span>
                        </div>`;

    }); // changed id to class
    output.innerHTML = outputContent;
});

$(document).on('click','.delete',function(){ // put click functionality outside
  delete_item($(this).parent().attr('data-id')); // pass data-id to function
});

Comments

1

You have more problems in your concept. The first is the duplicate ID usage and than the click event binding - you should register events to body element to register the event also to newly added elements. Here is a working code:

const output = document.getElementById('output');

function delete_item(id){
  console.log("ID " + id);
}

let productsArray = [];

$.getJSON('/products', products => {
  let outputContent = '';

  productsArray = Object.values(products);

  productsArray.forEach(product => {  
    outputContent += `  <div data-id="${ product.ID }">
                        <div class='edit'><i class='fa fa-pencil-square-o' aria-hidden='true'></i></div>
                        <div class='delete'><i class='fa fa-trash-o' aria-hidden='true'></i></div>
                        <div class='product'> <span class='name'> <a href=''>${product.NAME}</a></span>
                        <span class='price'>Price: £${product.PRICE}</span>
                        </div>`;

});

$('body').on('click', '.delete', function(){
    delete_item($(this).parent().attr('data-id'));
});

output.innerHTML = outputContent;
});

Comments

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.