Search code examples
phpjqueryajaxdatatablessweetalert2

Creating Dynamic Table using PHP and Ajax to insert data into table, unable to use buttons if not within view or first page


Lets Get straight to the point:

I have created a data table using dynamic data from the DB. i call the data using php and insert it into the table.

<?php
$getAttendance = $functions->runSQL("dynamic data sql query ");
$getAttendance->execute();
$attendance = $getAttendance->fetchAll(PDO::FETCH_ASSOC);

foreach ($attendance as $key => $data) {
  $getEmployeeName = $functions->runSQL("another sql query to call firstname and last name");
  $getEmployeeName->execute() ;
  $employeeName = $getEmployeeName->fetchAll(PDO::FETCH_ASSOC);
  foreach ($employeeName as $key => $name) {
?>
                  <tr>
                    <td><?= $data['date']; ?></td>
                    <td><?= $data['employee_id']; ?></td>
                    <td><?= $name['firstname'] . " " . $name['lastname']; ?></td>
                    <td><?= $data['clock_in']; ?></td>
                    <td><?= $data['clock_out']; ?></td>
                    <td>
                      <button class="btn btn-warning editAttendance" id="editAttendance-<?= $data['id']; ?>"  data-id="<?= $data['id']; ?>"><i class="fa fa-edit"></i>&nbsp;EDIT</button>
                      <button class="btn btn-danger deleteAttendance" id="deleteAttendance-<?= $data['id']; ?>" data-id="<?= $data['id']; ?>"><i class="fa fa-trash"></i>&nbsp;DELETE</button>  
                    </td>
                  </tr>

<?php
  }
}
?>

The table works exactly how i expected it to output and display. Although the edit and delete buttons work ONLY on the first page, after the user displays the second page and any page after that, the "Tools" button become non-existent.

GIF Displaying Page 2 edit/delete not working

As you can see in the above GIF, the edit and delete functions work perfectly until the second page of the pagination is loaded.

This goes for all my tables. if the table is not fully visible the buttons (edit/delete) do not work as well. Im not to sure if its the way the buttons interact with the table or sweetalert.

Not Visible Not Visible

Visible but unable to work or interact with sweetalert and ajax edit or delete calls (both work as demonstrated in the first GIF) Visible

<script>

$(document).ready(function(e) {
  $('[id^=editAttendance]').on('click', function(e) {
    e.preventDefault();
    var id = $(this).data('id');
    swal.showLoading();
    $.ajax({
        type: "POST",
        url: "<?= $site->baseURL; ?>/",
        dataType: "json",
        data: { id: id},
        success: function(response) {
            Swal.fire({
                title: "<div style='color:orange;'>Update Attendance</div>",
                html: "<div><label>Date</label>&nbsp;<input class='form-control' type='date' value='" + response[0]['date'] + "' id='attendanceDate'  placeholder=" + response[0]['date'] + " /></div><br />" +
            "<div><label>Clock In</label>&nbsp;<input class='form-control' id='attendanceClockIn' type='time' value='" + response[0]['clock_in'] + "'  placeholder='" + response[0]['clock_in'] + "' /></div><br />" +
            "<div><label>Clock Out</label>&nbsp;<input class='form-control' id='attendanceClockOut' type='time' value='" + response[0]['clock_out'] + "'  placeholder='" + response[0]['clock_out'] + "' /></div><br />",
                icon: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#3085d6',
                cancelButtonColor: '#d33',
                confirmButtonText: 'YES, EDIT IT!',
                cancelButtonText: 'CANCEL'
              }).then((result) => {
                if (result.isConfirmed) {

                    var attendanceDate = $('#attendanceDate').val();
                    var attendanceClockIn = $('#attendanceClockIn').val();
                    var attendanceClockOut = $('#attendanceClockOut').val();
                    if ( attendanceDate == "" || attendanceClockIn  == "" || attendanceClockOut  == "") {
                      Swal.fire({
                        icon: 'error',
                        text: 'please enter a value in either inputs'
                        });
                    } else {
                      Swal.fire({
                        title: "<div style='color:red;'>Are You Sure ?</div>",
                        icon: 'question',
                        showCancelButton: true,
                        confirmButtonColor: '#3085d6',
                        cancelButtonColor: '#d33',
                        confirmButtonText: 'YES!',
                        cancelButtonText: 'CLOSE'
                      }).then((result) => {
                        if (result.isConfirmed) {
                            $.ajax({
                              type: "POST",
                              url: "<?= $site->baseURL; ?>/",
                              dataType: "json",
                              data: {
                                  id:id,
                                  dates: attendanceDate,
                                  clockIn: attendanceClockIn,
                                  clockOut: attendanceClockOut 
                              },
                              success: function(data) {
                                 Swal.fire({
                                    icon: data.success,
                                    title: 'Attendance Edited!',
                                    confirmButtonColor: '#28a745',
                                    confirmButtonText: 'CLOSE!',
                                    text: 'Click CLOSE to continue.',
                                  }).then((result) => {
                                    if (result.isConfirmed) {
                                      location.reload();
                                    }
                                 });
                              },
                              error: function(data) {
                                console.log(data);
                              }
                            });

                            
                        }
                      });
                    }

                    
                }
              });
        },
        error: function (response) {
            swal.fire(
            "Internal Error",
            "Oops, Something Happened, contact webmaster", // had a missing comma
            "error"
            );
        }
    });
  });

    $('[id^=deleteAttendance]').on('click', function(e) {
        e.preventDefault();
        var id = $(this).data('id');
            $.ajax({
                type: "POST",
                url: "<?= $site->baseURL; ?>/",
                dataType: "json",
                data: { id:id },
                success: function(data) {
                  Swal.fire({
                    title: "<div style='color:red;'>Delete Attendance</div>",
                    icon: 'question',
                    showCancelButton: true,
                    confirmButtonColor: '#3085d6',
                    cancelButtonColor: '#d33',
                    confirmButtonText: 'YES!',
                    cancelButtonText: 'CLOSE',
                    html: "<strong>You are about to remove <h4 style='color:red;'>" + data[0]['employee_id'] + " :: " + data[0]['date'] + " : " + data[0]['clock_in'] + "</h4></strong>"
                  }).then((result) => {
                    if (result.isConfirmed) {
                        $.ajax({
                          type: "POST",
                          url: "<?= $site->baseURL; ?>/",
                          dataType: "json",
                          data: {id: id},
                          success: function(data){
                              Swal.fire({
                                  icon: data.success,
                                  title: 'Attendance Deleted!',
                                  confirmButtonColor: '#28a745',
                                  confirmButtonText: 'CLOSE!',
                                  text: 'Click CLOSE to continue.'
                                }).then((result) => {
                                  if (result.isConfirmed) {
                                    location.reload();
                                  }
                               });
                          },
                          error: function(data){
                            swal.fire(
                            "Internal Error",
                            "Oops, Something Happened, contact webmaster.", // had a missing comma
                            "error"
                            );
                          }
                        });
                    }
                  }); 

              },
              error: function(data){
                console.log(data);
              }
            });
    });

    
    $('#add-new-attendance').on('click', function(e) {
    
        e.preventDefault();
        Swal.fire({
                title: "<div style='color:green;'>Add Attendance</div>",
                html: "<div><label>Employee ID</label>&nbsp;<input class='form-control' type='text'  id='attendanceEmployeeID'  placeholder='EG: FSJXXXX' required autofocus /></div><br />" +
            "<div><label>Date</label>&nbsp;<input class='form-control' id='attendanceDate' type='date'  placeholder='100' required /></div><br />" +
            "<div><label>Clock In</label>&nbsp;<input class='form-control' id='attendanceClockIn' type='time'  placeholder='100' required /></div><br />" +
            "<div><label>Clock Out</label>&nbsp;<input class='form-control' id='attendanceClockOut' type='time'  placeholder='100' required /></div><br />",
                icon: 'info',
                showCancelButton: true,
                confirmButtonColor: '#3085d6',
                cancelButtonColor: '#d33',
                confirmButtonText: 'YES, ADD IT!',
                cancelButtonText: 'CANCEL'
              }).then((result) => {

                if (result.isConfirmed) {
                    var description = $('#deductionDescription').val();
                    var amount = $('#deductionAmount').val();
                    if (description == "" || amount == "") {
                      Swal.fire({
                        icon: 'error',
                        text: 'please enter a value in either inputs'
                        });
                    } else {
                            $.ajax({
                              type: "POST",
                              url: "<?= $site->baseURL; ?>/",
                              dataType: "json",
                              data: {
                                  description: description,
                                  amount: amount
                              },
                              success: function(data) {
                                 Swal.fire({
                                    icon: data.success,
                                    title: 'Deduction Added!',
                                    confirmButtonColor: '#28a745',
                                    confirmButtonText: 'CLOSE!',
                                    text: 'Click CLOSE to continue.',
                                  }).then((result) => {
                                    if (result.isConfirmed) {
                                      location.reload();
                                    }
                                 });
                              },
                              error: function(data) {
                                console.log(data);
                              }
                            });
                    }
                }

              });
    });

});
</script>

Anyone else have this issue using datatables js ? Is this a glitch in datatables or an error on my side for not including anything to handle the next page or when the buttons are not visible?

What i have tried: - Redesign the entire table (did not work) - Changed All the jquery and ajax call (simplified but still did not work)

What did work: - Displaying the full table without the pagination seems to solve this issue. Although it would not be wise to load 100's of pages and display them in one page (cannot use as a fix).

Thank You for taking the time to read and help me asses the situation as this is the first time this has occurred. Never happened before with datatables.


Solution

  • You should replace every jQuery click event listener with a click listener on the body filtered by a selector.

    Instead of:

    $('[id^=editAttendance]').on('click', function(e) {...});

    Try:

    $('body').on('click', '[id^=editAttendance]', function(e) {...});

    In this way it will work also for buttons that are attached to the DOM after the initial rendering of the page.

    See here for the docs: https://api.jquery.com/on/