With server-side processing, Select All doesn't work

With server-side processing, Select All doesn't work

klee777klee777 Posts: 12Questions: 2Answers: 0

As I have about half-million rows, first I tested without server-side processing. It took more than 30 sec to display the data. For searching (by typing a character), or changing page also took more than 20 sec.
To be able to select a multiple rows, I added the control-click and created 2 buttons: one with "Select all" (to select the entire table) and the other with "Deselect all" (to deselect the entire table) with this:

function selectAll() {
    var table = $('#myTable').DataTable();
    table.rows({ search: 'applied' }).select();
};
function deselectAll() {
    var table = $('#myTable').DataTable();
    table.rows({ search: 'applied' }).deselect();
};

// mimic ctrl+click
$("#myTable").on('click', 'tr', function (event) {
    var selRows = table.rows('.selected').indexes();
    if ($(this).hasClass('selected')) {
        if (event.ctrlKey) {
            $(this).removeClass('selected');
        } else {
            if (selRows.length > 0) {
                table.rows(selRows).deselect();
                $(this).addClass('selected');
            } else {
                $(this).removeClass('selected');
            }
        }
    }
    else {
        if (!event.ctrlKey) {
            if (selRows.length > 0) {
                table.rows(selRows).deselect();
            }
        }
        $(this).addClass('selected');
    }
});

Despite the unacceptable performance, these 2 functions worked perfectly: "selectAll()" selected all rows from the 1st page all the way to the last page. Any selected & unselected rows were remembered: for example, I selected only 2 rows in Page 1, changed to Page 2, and came back to Page 1, Those 2 rows are still selected.

So, I changed it to Server-side processing. The result was unbelievably fast: less than 2 second!!!

However, there are some problems with selecting the rows. "selectAll()" only selects all rows in the current page (e.g. Page 1), and when I change to Page 2, none of them are selected. When I come back to Page 1, those previously selected rows in Page 1 are all unselected.

Here are my questions.
1. How to make "selectAll()" to select the entire rows in the table?
2. How to remember the selected rows when navigating the pages?

Thank you in advance.

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    Datatables doesn't have any built in features to select server side rows nor keep track of what has been selected on page navigation.

    1. How to make "selectAll()" to select the entire rows in the table?

    I would look at using a global variable as a flag to keep track of the select all state. Use the draw event to use the flag to determine the need to select or deselect all on the page. You may need three states; one for select all, one for deselect all, and one for partial/user selected rows.

    1. How to remember the selected rows when navigating the pages?

    One option is to use the Gryrocode select checkboxes plugin. You will see that page navigation keeps the user selected rows. The select all/deselect all checkbox doesn't keep track.

    Or you can implement your own solution using the select and deselect and maybe the user-select events. Like the Gyrocode solution this will require keeping track of a unique ID for the table.

    Another consideration is if a user selects all then deselects one row how to keep track.

    The best way for us to help is if you start a SSP test case with one of these templates. Probably best to use ids-objects.php to have a unique id.

    Kevin

  • allanallan Posts: 61,667Questions: 1Answers: 10,096 Site admin

    I think this is to be expected - the row selection is a client-side construct, and with server-side processing only the rows shown are actually present at the client-side. Select them all, and you've got "all" 10 which are currently shown.

    If you want to actually select all rows, there are two options:

    1. Make row selection a server-side thing - i.e. each row selection / deselection will make an Ajax request (or socket, or whatever) to say that a row is selected. That way you can also tell it that you want to select all rows.
    2. On the client-side you'd need to do some sort of "exclude" option - i.e. all rows are selected (as a boolean flag) and then an array of rows which are deselected from that. There is a bit of logic needed for that, but it should be possible. This pull request attempts to do that. I haven't been able to review it yet.

    Allan

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    This has been asked before so you might find some threads on the forum to help.

    Kevin

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    Thank you @kthorngren and @allan .
    I will study further!

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    I had a bit of time to work up a simple demo. It was more complex than I thought. Keeping track of select/deselect all by itself wouldn't be too bad nor would keeping rack of the user selected rows. But together it gets a bit complex.
    http://live.datatables.net/pijefuze/1/edit

    I've only done some basic testing and it seems to work. It doesn't support the users being able to select multiple rows at once with shift nor does it keep track of using the row().select() APIs. I didn't do anything to update the info element. Getting the selected rows via rows( { selected: true} ) will only get the rows on the page.

    The example uses the following:

    Kevin

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    I updated the test case to keep the select info element updated. I used the select.info option to remove the default select info element. I replicated the select info element display in the select / deselect event.
    http://live.datatables.net/bejuqido/1/edit

    Kevin

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Nice, Kevin, that works well!

    Colin

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    Wow. Fantastic~~!!!! I can't believe it~~~!!! Thank you very much @kthorngren

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    I just want to say "Thank you" again. I just confirmed it is working.

  • klee777klee777 Posts: 12Questions: 2Answers: 0
    edited June 2022

    Hi @kthorngren,
    With server-side off, I used the send the selected data to the server. As the 1st column is the ID of the table in the database, I only saved them as an array, like this:

    function make_list_selected() {
        var table = $('#example').DataTable();
        var arrTmp = table.rows('.selected').indexes().toArray();
        var arrData = new Array();
        $.each(arrTmp, function (idx, val) {
            arrData.push(val[0]);
        });
    
        $.ajax({
            type: "POST",
            url: "/testUrl/DoTest",
            contentType: "application/json;",
            data: JSON.stringify(arrData)
        });
    };
    

    How can I achieve this with your implmentation?
    Sorry, I couldn't understand page.info() or '.select-info' etc.

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765
    Answer ✓

    The userSelected variable is used to keep track of all the user selections even on different pages. When select all is clicked userSelected is cleared and rowsToSelect holds the row id's of the current page rows on the page. The userUnselected keeps track of the user deselected rows, for example use select all the click one row to deselect. Both userSelected and userUnselected are cleared when Select All or Deselect All are clicked. I added a button you can use to see this:
    http://live.datatables.net/bejuqido/3/edit

    This solution keeps track of the row ID's not the row indexes like you have above.

    Hopefully this explains the options available for sending the selected rows to the server. If you want to keep track of selecta ll then you may need to include a select all flag and the user unselected rows. just depends on what you need to keep track of.

    Kevin

  • klee777klee777 Posts: 12Questions: 2Answers: 0

    @kthorngren Thank you Kevin! After posting the last question, I kind of figured it out, and your answer with the sample makes it all clear. I truly appreciate it.

Sign In or Register to comment.