简体   繁体   中英

Adding button with onclick event in .append() with JQuery/JavaScript

I want to add delete button to every row where status is ORDERED. I have tried different variations. This solution could work without error "Cannot read property 'id' of undefined" even though data[i] is not undefined. Alert before .click() gives right id. What is wrong here? Can I do something differently or better here?

).done( (data, status, jqXHR) => {
        if(data[0].order_username != undefined) {
            $("#orders_table").empty();
            for(var i = 0; i < data.length; i++) {
                var button = "";
                if(data[i].status == "ORDERED") {
                    button = "<td><button class='delete'>Delete</button></td>";

                }

                $("#orders_table").append(
                    "<tr>" +
                    "<td>" + data[i].order_username + "</td>"+
                    "<td>" + data[i].work_description + "</td>" +
                    "<td>" + dateFormatter(data[i].orderdate) + "</td>" +
                    "<td>" + dateFormatter(data[i].startdate) + "</td>" +
                    "<td>" + dateFormatter(data[i].readydate) + "</td>" +
                    "<td>" + dateFormatter(data[i].accepteddate) + "</td>" +
                    "<td>" + dateFormatter(data[i].denieddate) + "</td>" +
                    "<td>" + data[i].comment_of_work + "</td>" +
                    "<td>" + data[i].hours + "</td>" +
                    "<td>" + data[i].approx_budget + "</td>" +
                    "<td>" + data[i].status + "</td>" +
                    button + 
                    "</tr>"
                )

                alert(data[i].id);
                $(".delete").click(() => {
                    deleteUser(data[i].id);
                })
            }
        }

        function deleteUser(key) {
            $.ajax(
            {
                url: "http:localhost:3001/workorders_delete/"+key,
                method: 'delete'
            }).done( (data, status, jqXHR) => {

            }).fail( (jqXHR, status, errorThrown) => {
                console.log("Call failed: "+errorThrown);
            });
    }

You can set unique data attributes to the delete buttons using the the ids from the response data as follows:-

 if(data[i].status == "ORDERED") {
     button = "<td><button class='delete' data-deleteId = 
              "+data[i].id+">Delete</button></td>";
 }

and then you can write a single click event listener for the delete buttons as follows:-

$(".delete").click(function(){
    var id = $(this).data("deleteId");
    deleteUser(id);
});

In your code :-

  $(".delete").click(() => {
    deleteUser(data[i].id);
  });

the function deleteUser() is being called or executed on click and at the point data[i].id will not be defined.

Why is data[i] undefined ?

In the loop, i is a reference to the same variable that has the value data.length after the loop.

As expected, data[data.length] is undefined . Check this with alert(i) inside .click() .

$(".delete").last().click(() => {
    alert(i);
    deleteUser(data[i].id);
})

A simplified example:

 (function wrong() { var array = []; for (i = 0; i < 2; i++) { array.push(() => { console.log(i); }); } array.forEach(click => click()); })(); 

The solution is to create a new const in the loop:

 (function right() { var array = []; for (i = 0; i < 2; i++) { const constI = i; array.push(() => { console.log(constI); }); } array.forEach(click => click()); })(); 

In addition...

$(".delete") refers to all delete buttons that exist at the point you register .click() .

You should register only on the last delete button:

const constI = i;
$(".delete").last().click(() => {
    deleteUser(data[constI].id);
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM