1

I am using a DataTable from bootstrap 4 and has successfully loaded data on it but the problem is that whenever I click a row action button (delete or edit) it does not open their respective modal.

Here's the current output of my data table:

Output

Here's my HTML code for the DataTable and Modals for Edit and Delete (index.php):

<div class="col-md-12">
                                <table id="jobtitlesdatatable" class="table table-bordered table-striped">
                                    <thead>
                                        <tr>
                                            <th>#</th>
                                            <th>Job Title</th>
                                            <th>Date Created</th>
                                            <th>Action</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                    </tbody>
                                </table>
</div>
<!-- Edit Job Title Modal -->
<form action="<?= base_url('jobtitle/editJobTitle') ?>" method="post">
    <div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
        <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Edit Job Title</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="modal-body">
         
            <div class="form-group">
                <label>Job Title</label>
                <input type="text" class="form-control job_title" name="job_title" placeholder="Job Title" required>
            </div>
             
        </div>
        <div class="modal-footer">
            <input type="hidden" class="form-control job_id" name="job_id" class="jobID">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
        </div>
    </div>
    </div>
</form>
<!-- End Modal Create Job Title -->

<!-- Modal Delete Job Title -->
<form action="<?= base_url('jobtitle/deleteJobTitle') ?>" method="post">
    <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
        <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Delete Job Title</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="modal-body">
         
           <h4>Are you sure want to delete this Job Title?</h4>
         
        </div>
        <div class="modal-footer">
            <input type="hidden" name="job_id" class="jobID">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">No</button>
            <button type="submit" class="btn btn-danger">Yes</button>
        </div>
        </div>
    </div>
    </div>
</form>
<!-- End Modal Delete Product-->

Here's my JQuery part (index.php):

<script>
$(document).ready(function(){
    $('#jobtitlesdatatable').DataTable({
        serverSide: true,
        searching: true,
        ajax: {
            url : "<?php echo base_url("jobtitle/jobtitles_page") ?>",
            type : 'post'
        },
    });
     // get Edit Product
    $('.btn-edit').on('click',function(){
        // get data from button edit
        const id = $(this).data('id');
        const title = $(this).data('name');
        console.log("JOBID: " + id);
        console.log("JOBTITLE: " + title);
        // Set data to Form Edit
        $('.job_id').val(id);
        $('.job_title').val(title);
        // Call Modal Edit
        $('#editModal').modal('show');
    });

    $('.btn-delete').on('click',function(){
        // get data from button edit
        const id = $(this).data('id');
        // Set data to Form Edit
        $('.jobID').val(id);
        // Call Modal Edit
        $('#deleteModal').modal('show');
    });
    
});

Here's my code for jobtitles_page() from the Controller file:

public function jobtitles_page()
 {
      $draw = intval($this->input->get("draw"));
      $start = intval($this->input->get("start"));
      $length = intval($this->input->get("length"));

      $jobtitles =  $this->JobTitleModel->get_all('jobtitle', null);

      $data = array();

      foreach($jobtitles as $jobTitle) {

           $data[] = array(
                $jobTitle->JOBID,
                $jobTitle->JOBTITLE,
                $jobTitle->CREATEDDATE,
                $jobTitle->href = '<a href="#" class="btn btn-warning btn-sm btn-edit" data-id="'.$jobTitle->JOBID.'" data-name="'.$jobTitle->JOBTITLE.'"><span class="fa fa-edit"></span></a>
                <a href="#" class="btn btn-danger btn-delete" data-id="'. $jobTitle->JOBID.'"><span class="fa fa-trash"></span></a>'
           );
      }

      $output = array(
           "draw" => $draw,
             "recordsTotal" => count($jobtitles),
             "recordsFiltered" => count($jobtitles),
             "data" => $data
        );
      echo json_encode($output);
      exit();
 }

And when I check its Element in Dev Console it shows this:

Dev Console

It correctly passes the ID and JOBTITLE.

What might be the cause of this problem and What are the ways to fix it?

Denzell
  • 309
  • 9
  • 17
  • 1
    Instead of using direct event handlers (for example `$('.btn-edit').on('click',function(){...});`, use delegated event handlers: `$('tbody').on('click', '.btn-edit', function(){...});`. See [Direct vs. Delegated - jQuery .on()](https://stackoverflow.com/questions/8110934/direct-vs-delegated-jquery-on) for a discussion and an explanation. Basically, you are trying to attach an event to something which does not (yet) exist in the page - either because the DataTable is still in the process of being initialized, or you are accessing a subsequent page of table results. – andrewJames Dec 05 '21 at 18:25

1 Answers1

1

As @andrewJames commented, you are trying to attach listeners to elements that do not yet exist. You can go with a delegate per their suggestion, or you can use initComplete, an event in DataTable.

$(document).ready(function(){
    $('#jobtitlesdatatable').DataTable({
        serverSide: true,
        searching: true,
        ajax: {
            url : "<?php echo base_url("jobtitle/jobtitles_page") ?>",
            type : 'post'
        },
        initComplete: function(settings, json) {
             console.log( 'DataTables has finished its initialisation.' );
             doInit();
         }
    });   
});

function doInit() {
     // get Edit Product
    $('.btn-edit').on('click',function(){
        // get data from button edit
        const id = $(this).data('id');
        const title = $(this).data('name');
        console.log("JOBID: " + id);
        console.log("JOBTITLE: " + title);
        // Set data to Form Edit
        $('.job_id').val(id);
        $('.job_title').val(title);
        // Call Modal Edit
        $('#editModal').modal('show');
    });

    $('.btn-delete').on('click',function(){
        // get data from button edit
        const id = $(this).data('id');
        // Set data to Form Edit
        $('.jobID').val(id);
        // Call Modal Edit
        $('#deleteModal').modal('show');
    });
}
Kinglish
  • 23,358
  • 3
  • 22
  • 43
  • I think `initComplete` may be a problem, because it only has access to buttons on the currently drawn page - hence my comment about accessing a subsequent page of table results. If the DataTable is destroyed and re-initialized every time you change pages, then you are OK - but that is typically not necessary (and I think relatively expensive). – andrewJames Dec 05 '21 at 19:43