Search code examples
javascriptjqueryajaxwordpressdatatables

Problems understanding how .when works with nested ajax calls (jquery/datatables/wordpress)


I am trying to make a website, where I load page content via ajax calls. The problem occurs to me when within the pages, I load other content again via ajax calls as tables with the DataTables library, but I can't reinitialize some other scripts, such as tooltips

This is the function of how I call the main ajax call to load the new page when the link is clicked.

$(document).on('click', '.ajax-link', function(event){ //Caricamento contenuto pagina nuova
   event.preventDefault();
   var link = $(this).attr('href');
   refresh_content(link, "newstate");
})

This is the function that is responsible for retrieving the contents of the new page. Upon the success of the ajax call, if there are any tables in the content, I call a function that takes care of loading and rendering the table with DataTable. Following that I re-initialize tooltip() because there are buttons in the tables with info inserted in the tooltips, but unfortunately it not works properly. I think because the reinitialization happens before the table is rendered.

function refresh_content(newUrl, status) {
        $.ajax({
            type: "POST",
            url: myAjax.ajax_url,
            data: {
                action: "refresh_content",
                nonce: myAjax.nonce,
                newUrl: newUrl,
            },
            beforeSend: function () {
                
            },
            success: function (response) {
                if(response.status == 200) {
                    var table = $('<div/>').html(response.content).find('.datatable');

                    if(table.length) {
                        $(table).each(function(index){
                            var typeTable = $(this).data('table');
                            loading_table(typeTable);
                        })
                         $('[data-bs-toggle="tooltip"]').tooltip();
                    }

                    var index = {
                        newUrl: newUrl,
                    }; 
        
                    if (status == "newstate") {
                        history.pushState(index, null, newUrl);
                    } else if (status == "popstate") {
                        history.replaceState(index, null, newUrl);
                    }
                } else {
                    console.log('ERRORE: '+response.status);
                    console.log('ERRORE: '+response.message);
                }
            },
            complete: function(){
                $('[data-bs-toggle="tooltip"]').tooltip();
            }
        });
    }

And this function takes care of retrieving the necessary data and creating the table and its rows.

function loading_table(typeTable) {
        switch(typeTable) {
            case 'clienti':
                // DataTable Customer with buttons
                var dt_basic_table_customer = $('.datatables-basic-customer');

                if (dt_basic_table_customer.length) {
                    var customer_table = dt_basic_table_customer.DataTable({
                    //processing: true,
                    //serverSide: true,
                    ajax:{
                        url: myAjax.ajax_url + '?action=tabella_clienti',
                        cache: false,
                    },
                    columns: [
                        //set columns
                    ],
                    columnDefs: [
                       // columns definitions
                    ],
                    // other options
                    });
                }
            break;
        }
    }

I think I have to work with promises using the .when() and .done() or .then() functions, but I admit my ignorance having never worked with them and I can't understand how it works. I have tried various things, but with no result. I am definitely missing some basic concepts.

I try something like

if(table.length) {
       $(table).each(function(index){
               var typeTable = $(this).data('table');
              var tableResult = loading_table(typeTable);
              $.when(tableResult).done(function() {
                   console.log('Loading table ended');
                   $('[data-bs-toggle="tooltip"]').tooltip();
             })
       })
}

Meanwhile, I thank you in advance to those who will help me better understand where I am wrong.


Solution

  • If you want to catch all jQuery.ajax completed calls, you can use the ajaxComplete event.

    $(document).on("ajaxComplete", () => {
        //Do some stuff...
    });