Buttons in <tr> not working after search is finished ASP.NET Core 3.1

Viewed 181

I've just implemented search in a sample web app that I'm working on. Search works fine and here is how I've done that:

Typecript Search function

    private search(keyword) {
        try {
            if (keyword === '' || keyword === undefined) {
                $('employees_list tbody').empty();
            } else { const data = { keyword: keyword };

                Util.request(this.urlSearchEmployee, 'GET', 'html', (response) => {
                    const currentKeyWord = $('#keyword').val();
                    if (currentKeyWord === keyword) {
                        $('#employees_list tbody').empty();
                        $('#employees_list tbody').append(response);
                    }
                }, function () {
                        $.notify('Failed to get data. Please try again.');
                        console.error('Failed to get data #T09576. Please try again.');
                }, data);
            }
        } catch (e) {
            console.error(e);
        }
    }

Search function in controller

                var employees = await _db.Employees.Where(e => 
                e.LastName.ToLower().Contains(keyword.ToLower()) ||
                e.FirstName.ToLower().Contains(keyword.ToLower()) ||
                e.Position.ToLower().Contains(keyword.ToLower())
                ).ToListAsync();

                //Console.WriteLine(employees);
                ViewData["EmployeesList"] = employees;
                return PartialView("~/Views/Employee/_TableData.cshtml");

Table View file

@{
    List<Employee> EmployeeList = (List<Employee>)ViewData["EmployeesList"];
}

@if (EmployeeList.Count > 0)
{
    foreach (var employee in EmployeeList)
    {
        <tr class="employees-row" style="width: 20%; text-align:center;">
            <td>@employee.FirstName</td>
            <td>@employee.LastName</td>
            <td>@employee.Position</td>
            <td>@employee.Department</td>
            <td>@employee.Salary</td>
            <td>@employee.DateJoined</td>
            <td>@employee.LastUpdated</td>
            <td>
                <button type="button" class="btn btn-sm btn-dark employee-edit" data-id="@employee.EmployeeId">
                    <i class="fa fa-edit"></i>
                </button>
                <button type="button" class="btn btn-sm btn-danger employee-delete" data-id="@employee.EmployeeId">
                    <i class="fa fa-trash"></i>
                </button>
            </td>
        </tr>
    }
}

The search works fine. But when the search result is loaded there are two buttons to edit or delete. And when I click these buttons they don't do anything. The same buttons work when the table rows are normal meaning when table rows are not search results.

Update
Here is the delete button click events:
Typescript:

                $('.employee-delete').click((e) => {
                    alert("Delete Button Clicked");
                    const id = $(e.currentTarget).data('id');
                    const data = {
                        id: id
                    };

                    this.delete(data);
                });

Then the delete() method in typscript:

    private delete(data) {
        try {
            if (confirm("Are you sure you want to delete this employee?") == true) {

                Util.request(this.urlDeleteEmployee, 'post', 'json', () => {
                    $.notify(`Employee deleted successfully.`);
                    location.reload();
                }, () => {
                    $.notify(`Failed to delete Employee. Please try again`);
                }, data);
            }
        } catch (e) {
            console.error(e);
        }
    }

This after search result the delete button nor edit button doesn't work. enter image description here

1 Answers

Your issue seems to be when you search the table, it will rebinding the DOM. So your previous click bindings of buttons will be vanished.

So rather than using $('.employee-delete').click(...) use delegate type bindings with $(document).on("click", ".employee-delete", (e) => { ... }.

It will assigned to dynamically created objects also. Update it like below.

$(document).on("click", ".employee-delete", (e) => {

   const id = $(e.currentTarget).data('id');
   const data = { id: id };
   this.delete(data);

});
Related