table.reload(function()) with columns[ {data, render}]

table.reload(function()) with columns[ {data, render}]

marywellmarywell Posts: 9Questions: 2Answers: 0

Hi,

I have this datatable:

dataTableName = '#datatable-account_addressbook';
  table = $(dataTableName).DataTable({
    "paging": true,
    "lengthChange": true,
    "searching": true,
    "ordering": true,
    "info": true,
    "autoWidth": false,
    "responsive": true,
    "ajax":{
      "url":"lib/php/tanto.php",
      "type":"POST",
      "data":{"formname":"account_addressbook"},
      "dataSrc": function(res){
        var count = res.data.length;
        $('#num_addressbook').html(count);
        return res.data;
      }
    },
    "columns": [
      { data: 'address_id', "defaultContent": "", class: "text-center", orderable: false, render: function(data, type, row, meta) {
          return (type === 'display' && data !== '') ?
            '<a class="launch_edit" data-id="'+data+'" data-toggle="tooltip" title="Edit"><i class="fas fa-edit text-warning"></i></a>'
          : data;
        }
      },
      { data: 'firstname',"defaultContent": "" },
      { data: 'lastname',"defaultContent": "" },
      { data: 'email',"defaultContent": "" },
      { data: 'birth_date', "defaultContent": "", render: function(data, type, row, meta){
          if(type === 'display' && data !== '') {
            if(data === '0000-00-00'){
              return '';
            }
            else {
              var date = new Date(data);
              var year = date.getFullYear();
              if(year==0){
                year = '';
              }
              var month = months[date.getMonth()];
              var day = date.getDate();
              //return date.toDateString().replace('0000','');
              return day+' '+month+' '+year;
            }
          }
          else {
            return data;
          }
        }
      },
      { data: 'birthday_reminder', "defaultContent": "", class: "text-center", orderable: false, render: function(data, type, row, meta) {
          return (type === 'display' && data !== '') ?
            (data === '1') ? '<i data-toggle="tooltip" title="Remind me?" class="fas fa-check text-success"></i>' : '<i data-toggle="tooltip" title="Remind me?" class="fas fa-times text-danger"></i>'
          : data;
        }
      },
      { data: 'address_id', "defaultContent": "", orderable: false, render: function(data, type, row, meta) {
          return (type === 'display' && data !== '') ?
            '<a class="launch_dele" data-toggle="tooltip" title="Delete" data-id="'+data+'"><i class="fas fa-ban text-danger"></i></a>'
          : data;
        }
      }
    ],
    "order": [[1, "asc"]],
    "initComplete": ajaxTable,
    "deferRender": true,
    "select": false
  });

And the following function:

var ajaxTable = function() {

    // Activate tooltips
    $('[data-toggle="tooltip"]').tooltip();

    // Edit address
    $('.launch_edit').on('click',function(e){
      e.preventDefault();
      var address_id = $(this).data('id');
      var formData = new FormData();
      formData.append('formname','account_addressbook');
      formData.append('address_id',address_id);
      $.ajax({
        url: "lib/php/tanto.php",
        type: 'POST',
        dataType: "JSON",
        processData: false,
        contentType: false,
        data: formData,
        cache: false,
        mimeType: 'multipart/form-data',
        beforeSend: function(){
          showLoading();
        },
        success: function (data) {
          hideLoading();
          if(data.error){
            // Toaster con error message
            $('#toast_error').data('toast-message',data.message);
            $('#toast_error').click();
          }
          else {
            var address = data.data[0];
            // Build the modal ...
            // Show the modal form
            $('#newModal').modal('show');
          }
        },
        fail: function(a,b,c) {
          hideLoading();
          toastr.error(b);
        }
      });
    });
    // Delete click
    $('.launch_dele').on('click',function(e){
      e.preventDefault();
      var address_id = $(this).data('id');
      $('#confirmation-modal').modal('show').on('click','#confirm-delete-yes',function(e){
        var formData = new FormData();
        formData.append('formname','delete_address');
        formData.append('address_id',address_id);
        $.ajax({
          url: "lib/php/tanto.php",
          type: 'POST',
          dataType: "JSON",
          processData: false,
          contentType: false,
          data: formData,
          cache: false,
          mimeType: 'multipart/form-data',
          beforeSend: function(){
            showLoading();
          },
          success: function (data) {
            hideLoading();
            if(data.error){
              // Toaster con error message
              $('#toast_error').data('toast-message',data.message);
              $('#toast_error').click();
            }
            else {
              // Toaster con success message
              $('#toast_success').data('toast-message',data.message);
              $('#toast_success').click();
              table.ajax.reload(ajaxTable);
              $('#confirmation-modal').modal('hide');
            }
          },
          fail: function(a,b,c) {
            hideLoading();
            // Toaster con error message
            $('#toast_error').data('toast-message',b);
            $('#toast_error').click();
          }
        });
      });
    });
  };

Everything works well for data loading, display of the 3 icons rendered, the tooltip display and the edit address on a modal. However I'm having an issue with delete action button on the last column:

When I click on delete button of a row, it does its action and send a jquery ajax to the server, the server responds, a toastr is displayed and the table is reloaded, removing the deleted row. All good up to here. However, if I click on a second Delete, I send 2 ajax calls to the server, one returns ok, and one return error as the address_id was deleted before and no longer exists. If I click again on a delete button, I'll send 3 ajax calls to the server, with 2 errors, and 1 success... and so on...

The delete button action is handled by a jquery class name such as:

$('.launch_dele').on('click',function(e){...});

and after a success return from the server, the table is ajax.reloaded, calling the ajaxTable function again to activate the buttons actions and tooltip:

table.ajax.reload(ajaxTable);

Do you have an idea of what can be causing this repeated ajax calls when I click the Delete button more than once without refresing the page?.

In the following pictures you can see how it looks, I have already deleted 2 rows from the table, and I click to delete another:



The table reloads well, but I send 3 ajax calls to the server, instead of one, so the server responds 2 errors (no id on database), and 1 success (id deleted). If I click again I'll send 4 calls to the server, 3 will return error, 1 success, and so on...

Any help?

Thank you in advance.

Answers

  • kthorngrenkthorngren Posts: 21,169Questions: 26Answers: 4,922

    I line 76 you have table.ajax.reload(ajaxTable);. This is running your ajaxTable again which is introducing another set of click events. So each time you delete you are appending another set of click events. Why are you calling ajaxTable with ajax.reload()?

    If you want to continue doing this you can use jQuery off() to remove the previous click event before using on().

    Kevin

  • marywellmarywell Posts: 9Questions: 2Answers: 0

    If I replace line 76 with:

                  //table.ajax.reload(ajaxTable);
                  table.row($(this).parents('tr')).remove().draw();
    

    I'm not calling the ajaxTable function, but the same thing persists... The row gets removed, the table redraw... but more than 1 ajax is sent to the server after 2ns delete click..

    I think I like more to do a row().remove() as I don't have to reload all data from the server, but same mistake happens,,, on a 2nd delete click, I send 2 ajax to the server, 1 success, 1 error... on a 3rd delete click, I send 3 ajax to the server, 1 success, 2 errors...

  • kthorngrenkthorngren Posts: 21,169Questions: 26Answers: 4,922

    There is nothing else obvious to me in the code that would cause additional click events to be added each time you lick the delete button. Can you post a link to your page or a test case so we can take a look?
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • marywellmarywell Posts: 9Questions: 2Answers: 0

    Also if I remove the ajaxTable function from the table.ajax.reload() the tooltips and button actions are not active and available to the browser...

  • kthorngrenkthorngren Posts: 21,169Questions: 26Answers: 4,922
    edited March 2020

    Looks like what you need for that is this code:

        // Activate tooltips
        $('[data-toggle="tooltip"]').tooltip();
    

    Move it to a different function and call that instead. You will need to call that function in initComplete also.

    Kevin

  • marywellmarywell Posts: 9Questions: 2Answers: 0

    Hi,

    This is what finally worked for me. It seem that the modal button $('#confirm-delete-yes').on('click'... was beign called everytime after a click, I don't know why, but the following works (after line 76):

                  //table.ajax.reload(ajaxTable);
                  var row = $(this).parents('tr');
                  table.row(row).remove().draw();
                  $('#confirmation-modal').modal('hide').off('click','#confirm-delete-yes');
    

    Now I dont't send repeated calls to the server on every '.launch_dele' click, and also I don't reload the table averytime I delete a row... much better this way..

    Thanks for the support.

  • marywellmarywell Posts: 9Questions: 2Answers: 0
    edited March 2020

    Thanks to point me to the jQuery.off() function

This discussion has been closed.