'Do something' after draw() has completed, but outside of drawCallback()

'Do something' after draw() has completed, but outside of drawCallback()

mihomesmihomes Posts: 150Questions: 19Answers: 0

Here is my situation, and while I have a solution I've been using for a few years now, I would like to revisit this to see if anything else has been made available.

    "dom":
        "<'dtSelections'lf>"+
        "<'dtButtons'>"+
        "<'dtAlert'>"+
        "r"+
        "<'dtTable table-responsive't>"+
        "<'dtFooter'ip>",

I insert alerts in the 'dtAlert' div after actions have happened such as deleting an entry, updating it, and so on. More often that not I need to call table.draw() after these actions happen as well.

table.draw();
--insert my alert into the div--

The problem has always been the alert is inserted before the draw completes. Since I clear alerts on each draw in drawCallback() they never display. My current solution is to save the 'state'... set it to 1 when I add an alert then in the drawCallback() if it is 1 I do nothing and set it to 0... if 0 I clear the alerts. This basically tells it to leave the alerts for 1 redraw then clear afterwards.

Has there been anything new added which would allow me to accomplish this differently? Like a callback in table.draw() or something using promises?

Answers

  • allanallan Posts: 61,726Questions: 1Answers: 10,109 Site admin

    Hi,

    Could you show me a complete example of your code please? I’m not quite getting this bit:

    The problem has always been the alert is inserted before the draw completes. Since I clear alerts on each draw in drawCallback() they never display

    Your pseudo code above shows it being inserted after you call draw() (although if you are using server-side processing, then the actual draw might happen later). But you say here that you clear alerts on drawCallback.

    I’m also not clear on what is triggering the alert - does it happen on every draw, or is it adding a click event handler in the table or something else.

    I’d need an example showing the issue to be able to help much I think.

    Allan

  • mihomesmihomes Posts: 150Questions: 19Answers: 0

    Yes, this is server-side processing. I can't provide an entire example, but here is a condensed version which shows what is happening :

    var alertCount = 0,
        card = $("#tab_table"),
        dataTable = card.find('.dt'),
        dateStart = $('#dateRange .start'),
        dateEnd = $('#dateRange .end');
    
    var dt = dataTable.DataTable({
        "dom":
            "<'dtSelections'lf>"+
            "<'dtButtons'>"+
            "<'dtAlert'>"+
            "r"+
            "<'dtTable table-responsive't>"+
            "<'dtFooter'ip>",
        "processing": true,
        "serverSide": true,
        "ajax":
            {
                "url": "/assets/datatables/logs.php",
                "type": "POST",
                "data": function ( d ) {
                    d.date_start = dateStart.text();
                    d.date_end = dateEnd.text();
                }
            },
        "drawCallback": function() {                        
            // alert should only show for one draw
            if (alertCount == 1)
            {
                alertCount = 0;
            }
            else if (alertCount == 0)
            {                   
                card.find('.dtAlert').html('');
            }
        }       
    });
    
    //some trigger happens somewhere in the code
    ...
    
        $.ajax({
            type: 'post',
            url: '/assets/process/p_delete.php',
            data: data,
            dataType : 'json'
        }).done(function (response) {
    
            if (response.success)
            {
                dt.draw();
        
                //show alert after redraw or not? 1 = yes, 0 = no
                alertCount = 1;
            
                App.alert({
                    ... this is basically
                    card.find('.dtAlert').html('some alert goes in here');
                });
            }
                ...other conditions and alerts
        });
    

    In this example, table loads with server-side processing. Some trigger happens which modifies the database (delete in this case) with ajax. Upon return I redraw the table to show 'current' information and show an alert to the user (what you did was a success, it errored, etc).

    This also shows my current working solution to this problem. The alert is added to the html before the redraw is complete so alertCount = 1 tells it to leave the alert alone when the redraw actually completes. On the next redraw, assuming another alert has not replaced it and set alertCount = 1 again, the alert wrapper is cleared.

    In cases where I show an alert without a redraw 'with it' I set alertCount = 0. That way the alert is added and shows to the user and whenever the next draw happens it is cleared.

    It works fine and just like I want it to, but has always felt like a hack. Making sure the alertCount value is set correctly for every alert is a pain when dealing with lots of code and lots of alerts in it.

This discussion has been closed.