Where Do I Change Cursor To 'Wait' Upon Applying a Filter

Where Do I Change Cursor To 'Wait' Upon Applying a Filter

puffsterpuffster Posts: 61Questions: 22Answers: 0

Hi all,

I've been working on this for about a day and feel like I've thrown the kitchen sink at this, but having no luck. I have a datatable that's loading about 13,000 rows -- no problems at all with that. I have a series of dropdown boxes that let the users filter out particular data. There is a couple of seconds lag for the selection to occur and the table to be reprocessed -- just long enough that I feel I need to change the cursor to let the user know work is being done. This is where the problem comes in, I've tried placing my jquery/cursor command in multiple places, but it doesn't seem to be working. I think it could have something to do with the asynchronous nature of javascript -- that perhaps it's working but it's just a flicker. Anyway, below are my various code snippets that I've applied:

I saw to try adding this CSS in another question asked, but it's not working

    <style type="text/css">
        div.dataTables_processing { 
            z-index: 1; 
        }
    </style>

My table setup:

        <div id="divAttData" class="col-xs-13" style="width:90%;">
            <table id="attDetail" class="table table-striped table-condensed table-responsive display" style="width: 100%">
                <thead>
                    <tr>
                        <th>schoolID</th>
                        <th>School</th>
                        <th>Last Name</th>
                        <th>First Name</th>
                        <th>Grade</th>
                        <th>aolID</th>
                        <th>Academy</th>
                        <th>pwID</th>
                        <th>Pathway</th>
                        <th>Days Enrolled</th>
                        <th>Days Excused</th>
                        <th>Days Unexcused</th>
                        <th>Days Missed</th>
                        <th>Attendance Rate</th>
                    </tr>
                </thead>
                <tfoot style="font-weight: bold">
                    <tr>
                        <td colspan="9" class="text-right">Totals:</td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                </tfoot>
                <tbody></tbody>
            </table>
        </div>

My datatable setup, here you can see where I've added the preInit listener as well as a preInit setting:

            $(document).on('preInit.dt', function (e, settings) {
                $("body").css("cursor", "wait");
            });
            
            attTable = $('#attDetail').DataTable({
                autoWidth: true,
                data: attData,
                pageLength: 20,
                processing: true,
                scrollY: '70vh',
                scrollCollapse: true,
                buttons: [
                        'excelHtml5', 'pdfHtml5', 'print'
                ],
                dom: '<"col-xs-12 col-sm-9"f><"col-xs-12 col-sm-3"B>rt<"col-xs-12 col-sm-7"i><"col-xs-12 col-sm-5"p>',
                columns: [
                    {
                        visible: false,
                        data: 'schoolID',
                        defaultContent: '',
                    },
                    {
                        data: 'schoolName',
                        defaultContent: '',
                    },
                    {
                        data: 'lastName',
                        defaultContent: '',
                    },
                    {
                        data: 'firstName',
                        defaultContent: '',
                    },
                    {
                        className: 'text-center',
                        data: 'grade',
                        defaultContent: '',
                    },
                    {
                        visible: false,
                        data: 'aolAcademyID',
                        defaultContent: '',
                    },
                    {
                        data: 'academyName',
                        defaultContent: '',
                    },
                    {
                        visible: false,
                        data: 'aolPathwayID',
                        defaultContent: '',
                    },
                    {
                        data: 'academyPathway',
                        defaultContent: '',
                    },
                    {
                        className: 'text-center',
                        data: 'daysEnrolled',
                        defaultContent: '',
                    },
                    {
                        className: 'text-center sum',
                        data: 'daysExcused',
                        defaultContent: '',
                    },
                    {
                        className: 'text-center sum',
                        data: 'daysUnexcused',
                        defaultContent: '',
                    },
                    {
                        className: 'text-center sum',
                        data: 'daysMissed',
                        defaultContent: '',
                    },
                    {
                        className: 'text-center',
                        data: 'attRate',
                        defaultContent: '',
                    },
                ],
                drawCallback: function () {
                    var api = this.api();

                    $(api.column(9).footer()).html(formatNumberWithCommas(
                        api.column(9, { 'filter': 'applied' }).data().sum())
                    );

                    $(api.column(10).footer()).html(formatNumberWithCommas(
                        api.column(10, { 'filter': 'applied' }).data().sum())
                    );

                    $(api.column(11).footer()).html(formatNumberWithCommas(
                        api.column(11, { 'filter': 'applied' }).data().sum())
                    );

                    $(api.column(12).footer()).html(formatNumberWithCommas(
                        api.column(12, { 'filter': 'applied' }).data().sum())
                    );

                    $(api.column(13).footer()).html(formatNumberWithCommas(
                        100.0 - Math.round((api.column(12, { 'filter': 'applied' }).data().sum() / api.column(9, { 'filter': 'applied' }).data().sum() * 100) * 10) / 10)
                    );

                    $("body").css("cursor", "default");
                },
                preInit: function () {
                    $("body").css("cursor", "wait");
                },
                initComplete: function (settings, json) {
                    $('#divLoader').remove();
                }
            });

A custom filtering function I saw as an example of how to filter the data, with the cursor function at the beginning of this one -- I'm sure this one is just a 'flicker' as it processes record by record...

/* Custom filtering */
$.fn.dataTable.ext.search.push(
    function (settings, data, dataIndex) {
        $("body").css("cursor", "wait");

        //Schools
        var schoolsSelected = $("#ddSchools :checked").map(function () { return parseFloat(this.value); });
        var school = parseFloat(data[0]);
        //Academies
        var academiesSelected = $("#ddAcademies :checked").map(function () { return parseFloat(this.value); });
        var academy = parseFloat(data[5]);
        //Academies
        var pathwaysSelected = $("#ddPathways :checked").map(function () { return parseFloat(this.value); });
        var pathway = parseFloat(data[7]);
        //Grades
        var gradesSelected = $("#ddGrades :checked").map(function () { return parseFloat(this.value); });
        var grade = parseFloat(data[4]);

        if (($.inArray(school, schoolsSelected) == -1)
            || ($.inArray(grade, gradesSelected) == -1)
            || ($.inArray(academy, academiesSelected) == -1)
            || ($.inArray(pathway, pathwaysSelected) == -1))
            return false;
        else
            return true;
    }
);

The filters are listitem checkboxes inside a dropdown box, the listitems have an onchange command that calls the following code:

function updateSchoolDD(schoolID) {
    var cName = ".ddSchools" + schoolID;
    $("body").css("cursor", "wait");

    $(cName).toggle();
    $.when(attTable.draw()).done(function () {
        $("body").css("cursor", "default");  
    });
}


I'm hoping either fresh eyes or a more knowledgeable soul can help a brother out...

Answers

  • allanallan Posts: 63,464Questions: 1Answers: 10,466 Site admin

    draw() doesn't return a promise, or anything else that will work with $.when that I'm aware of. I think at the moment it is probably executing almost immediately. I'd suggest listening for the draw event:

    attTable
      .one( 'draw', function () {
        $("body").css("cursor", "default");
      } )
      .draw();
    

    You may also want to try putting that into a setTimeout. The will force the browser to 'break' and redraw the page with your wait cursor, and then go and do the draw. Part of the issue might be that the browser is trying to group lots of changes together, so it is only flickering.

    Allan

This discussion has been closed.