Datatable with checkbox column and option to select or deselect all

Datatable with checkbox column and option to select or deselect all

AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0
edited September 2018 in Free community support

Hi all,

Is there anyone who have implemented a DataTable with a checkbox column and then when you tick the checkbox on the header it select or deselect all rows in the table?

I've seen quite a few samples including the documentation, but, I was not able to make it working.

It'd be very nice if anyone can post a working sample or point me to the right direction on how to accomplish this.

Also, my last column is a operation column for CRUD operations.

This is what I have done.

$.ajax({
                    url: "http://localhost:52800/api/sample",
                    method: "GET",
                    contentType: 'application/json'
                }).done(function (data) {
                    $('#tblTable').dataTable({
                        lengthChange: false,
                        pageLength: 10,
                        deferRender: true,
                        dom: 'Bfrtip',
                        order: [[1, 'asc']],
                        "aaData": data,
                        "columns": [
                            {
                                targets: 0,
                                data: null,
                                className: 'text-center',
                                searchable: false,
                                orderable: false,
                                render: function (data, type, full, meta) {
                                    return '<input type="checkbox" id="check_' + data.id + '" class="check" name="check" value="' + data.id + '">';
                                },
                                width: "5%"
                            },
                            {
                                data: "email",
                                width: "50%"
                            },
                            {
                                data: "name",
                                width: "30%"
                            },
                            {
                                data: null,
                                className: "text-center",
                                defaultContent: "<a href='#' class='_edit'><span class='glyphicon glyphicon-edit'></a>&nbsp;&nbsp;&nbsp;" +
                                    "<a href='#' class= '_details'><span class='glyphicon glyphicon-eye-open'></a>&nbsp;&nbsp;&nbsp;" +
                                    "<a href='#' class= '_delete'><span class='glyphicon glyphicon-trash'></a>&nbsp;&nbsp;&nbsp;" +
                                    "<a href='#' class= '_invite'><span class='glyphicon glyphicon-envelope'></a>",
                                orderable: false
                            }
                        ],
                        buttons: [
                            {
                                text: 'Create New',
                                action: function () {

                                    let html;
                                    $.get('form.html', function (data) {
                                        html = data.replace("StateControlsPlaceHolder", "value='new'");
                                    }).done(function () {
                                        $('#ActionContainer').html(html);
                                    });
                                }
                            },
                            {
                                text: 'Invite',
                                action: function () {
                                    alert("Invite multiple users at the same time");
                                }
                            },
                            {
                                text: 'Delete',
                                action: function () {
                                    alert("Delete multiple users at the same time");
                                }
                            }
                        ]
                    });
                });

Thank you very much!

Replies

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

    Hi @AlexanderLamas ,

    You can do this easily with the Select extension - see the example here.

    Cheers,

    Colin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0
    edited September 2018

    Hi Colin,

    Thank you very much. Much appreciated your help. :)

    Based on your answer I have question.

    It looks like when you use var table ... is more flexible and you can manipulate the dataTable easier, is that correct?

    If I user the var table ... how can I populate this table from an ajax call?

    Is it better to use table the way you did in your sample

    =====================================================
    var table = $('#example').DataTable({
                                    columnDefs: [{
                                        orderable: false,
                                        className: 'select-checkbox',
                                        targets: 0
                                    }],
                                    select: {
                                        style: 'os',
                                        selector: 'td:first-child'
                                    },
                                    order: [[1, 'asc']]
                                });
    =====================================================
    

    or this way, getting the data from the server as json format

    =====================================================
    $.ajax({
                                    url: "http://localhost:8888/myapi",
                                    method: "GET",
                                    contentType: 'application/json'
                                }).done(function (data) {
                                    $('#tblTable').dataTable({
                                        lengthChange: false,
                                        pageLength: 10,
                                        deferRender: true,
                                        dom: 'Bfrtip',
                                        order: [[1, 'asc']],
                                        "aaData": data,
                                        "columns": [
                                            {
                                                targets: 0,
                                                data: null,
                                                className: 'text-center',
                                                searchable: false,
                                                orderable: false,
                                                render: function (data, type, full, meta) {
                                                    return '<input type="checkbox" class="_check" name="check" value="' + data.id + '">';
                                                },
                                                width: "5%"
                                            },
                                            {
                                                data: "email",
                                                width: "50%"
                                            },
                                            {
                                                data: "name",
                                                width: "30%"
                                            },
                                        ],
                                        buttons: [
                                            {
                                                text: 'Create New',
                                                action: function () {
    
                                                    let html;
                                                    $.get('form.html', function (data) {
                                                        html = data.replace("StateControlsPlaceHolder", "value='new'");
                                                    }).done(function () {
                                                        $('#ActionContainer').html(html);
                                                    });
                                                }
                                            },
                                            {
                                                text: 'Invite',
                                                action: function () {
                                                    alert("Invite multiple users at the same time");
                                                }
                                            },
                                            {
                                                text: 'Delete',
                                                action: function () {
                                                    alert("Delete multiple users at the same time");
                                                }
                                            }
                                        ]
                                    });
                                });
    =====================================================
    

    Thank you very much in advance.

    Regards,
    Alex

  • allanallan Posts: 61,611Questions: 1Answers: 10,089 Site admin

    Hi Alex,

    Colin asked me to take a look at your follow up questions:

    It looks like when you use var table ... is more flexible and you can manipulate the dataTable easier, is that correct?

    Yes - because you can manipulate the DataTable through its API. You don't have to do it that way, you can access the API other ways, but that is the most common.

    If I user the var table ... how can I populate this table from an ajax call?

    Make your Ajax call (using fetch or $.ajax or whatever) and use rows.add() to add the rows to the table based on the return from the server.

    Is it better to use table the way you did in your sample
    or this way, getting the data from the server as json format

    It depends :). You might already have an Ajax library for handling security etc, that you want to use rather than using $.ajax. Or perhaps you just want the complete control that using $.ajax directly gives you. If so, then doing it that way is absolutely fine.

    For me, I tend to use the ajax option because then you can use the DataTables Ajax API methods (e.g. ajax.reload()) which you couldn't do if you were making the Ajax calls yourself.

    Allan

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Hi Allan,

    Thank you very much your reply and explanation.

    Can I ask you please to post a sample of using datatable API with ajax Option and ajax reload() as you mentioned?

    Also, would you have a sample when using var table = ...dataTable being populated via a ajax call?

    Thank you so much for your time!

    Regards,
    Alex

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

    Hi @AlexanderLamas ,

    This example here is a good one. It shows serverSide processing, ajax, and with two types of ajax.reload(),

    Cheers,

    Colin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Thank you very much Colin!

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Hi Colin,

    I've used the var table = ... It worked really well. So, thank you very much for that.

    Sorry, I've got one more question for you.

    I've implemented the multiple selection in the dataTable.

    The header checkbox is selecting and deselecting all items, but, it does not really select the rows.

    To select the rows I have to click on anywhere in the row but not in the checkbox.
    Do you have any idea why that is happening? Do I have to implement anything else to help the dataTable API to be able to make that work?

    Please post some sample if you have or send me a link with a multiple selection option.

    Thank you so much again.

    Regards,
    Alex

  • kthorngrenkthorngren Posts: 20,247Questions: 26Answers: 4,761

    How are you selecting the rows when using the header checkbox?

    Are you using the rows().select() and rows().deselect() API's?

    Kevin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    I didn't use anything, I mean, I didn't implement anything.

    I'm just using the dataTable API.

    Where and when should I implement the selecting and deselecting for one item and all items?

    Thanks a lot Kevin!

    Regards,
    Alex

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

    Hi @AlexanderLamas ,

    If you didn't implement anything, that's probably the issue :) If you do what Kevin said in a click event that should do the trick, something like this.

    Cheers,

    Colin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0
    edited October 2018

    Hi Colin,

    Thank you very much for your help.

    It works as a charm now. Thanks to you guys!

    Can I ask you if this code is optimal, by that I mean, if is running the fastest possible way and retrieving the data from the ajax call in the best way? Feel free to suggest improvements.

    table = $("#tblIndex").DataTable({
                    processing: true,
                    lengthChange: false,
                    pageLength: 10,
                    deferRender: true,
                    dom: 'Bfrtip',
                    ajax: {
                        url: 'myapi',
                        dataSrc: ''
                    },
                    columnDefs: [
                        {
                            targets: 0,
                            data: "select",
                            searchable: false,
                            orderable: false,
                            className: 'select-checkbox'
                        },
                        {
                            targets: 1,
                            data: "email",
                            width: "50%"
                        },
                        {
                            targets: 2,
                            data: "name",
                            width: "30%"
                        },
                        {
                            targets: 3,
                            data: null,
                            render: function (data) {
                                let invite = "";
                                if (!data.deviceid)
                                    invite = "<a href='#' class= '_invite'><span class='SDGbtn-Function SDGbtn-Function_License'></a>";
    
                                return "<a href='/" + egateid + "/app/user-details/" + data.id + "' class='_details'><span class='SDGbtn-Function SDGbtn-Function_Ref'></a>&nbsp;&nbsp;&nbsp;" +
                                    "<a href='/" + egateid + "/app/user-edit/" + data.id + "' class='_edit'><span class='SDGbtn-Function SDGbtn-Function_Edit'></a>&nbsp;&nbsp;&nbsp;" +
                                    "<a href='/" + egateid + "/app/user-delete/" + data.id + "' class= '_delete'><span class='SDGbtn-Function SDGbtn-Function_Delete'></a>&nbsp;&nbsp;&nbsp;" +
                                    invite;
                            },
                            searchable: false,
                            orderable: false,
                            width: "15%"
                        }
                    ],
                    select: {
                        style: 'os',
                        selector: 'td:first-child'
                    },
                    order: [[1, 'asc']],
                    buttons: [
                        {
                            tag: 'a',
                            className: 'SDGbtn-Function SDGbtn-Function_License',
                            action: function () {
                                User.inviteMultipleUsers(table, egateid, function (result) {
                                    if (result)
                                        Message.successMessage('All selected users were invited successfully!');
                                });
                            },
                            init: function (api, node, config) {
                                $(node).removeClass('dt-button')
                            },
                            titleAttr: 'Invite selected users'
                        },
                        {
                            tag: 'a',
                            className: 'SDGbtn-Function SDGbtn-Function_Delete',
                            action: function () {
                                alert('Function is not yet implemented!');
                                //User.deleteMultipleUsers(table, egateid);
                            },
                            init: function (api, node, config) {
                                $(node).removeClass('dt-button')
                            },
                            titleAttr: 'Delete selected record(s)'
                        },
                        {
                            tag: 'a',
                            className: 'SDGbtn-Function SDGbtn-Function_Delete',
                            action: function () {
                                window.open("/" + egateid + "/app/user-create/", "_self")
                            },
                            init: function (api, node, config) {
                                $(node).removeClass('dt-button')
                            },
                            titleAttr: 'Create new record'
                        }
                    ]
                });
    

    Thank you so much!

    Regards,
    Alex

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

    Looks good to me, happy to have helped!
    C

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Hi Colin,

    I don't want to abuse, but, I've got another question.
    How can I make the information example: "Showing 1 to 10 of 47 entries" and pagination in the same line and keep the information aligned to the left?

    I've got the below sample,

    dom: "Bfrtip <'row'<'col-sm-12'tr>> <'row'<'col-sm-4'l><'col-sm-4'i><'col-sm-4'p>>",

    but it's not really working.

    is there a place to find all the possible settings for the 'dom' to help on this matter?

    Thank you again!

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

    Hi @AlexanderLamas ,

    See dom for the settings, and this thread here will help too, since it's showing how to move elements with CSS,

    Cheers,

    C0lin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Hi Colin,

    Thank you very much for replying my last question, I've not defined the final result yet, but, I've been playing with the settings and I think I should be fine. It's quite powerful. So, well done job to you guys.

    I've another question for you.

    I have add a rendered column in the table, and I wonder if it's possible to change the value of the column, like change the value='1' if I click on the column and if I click again it changes to value='0'. Like change to true to false and vice-versa.

    I've added a CSS class in the column with an image to change to ON/OFF if I click on, the image is changing with no problem, but I could not get the click to change the column value.

    Is there any way I can accomplish that?

    Again, thank you very much!

    Cheers,
    Alex

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

    Hi @AlexanderLamas ,

    Yep, if you click on the age column in this example here, you'll see it incrementing on each click, it'll be trivial to change to a boolean.

    Cheers,

    Colin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0
    edited October 2018

    Hi Colin,

    Thanks for your help and sending the link.
    It helped me a lot.
    I just had to do a little tweak in my case to be able to trigger the event.

    The only thing now is how I can't get the row ID in that event?

    This is my event.

    $('#myTable tbody').on('change', ' td:nth-child(3) > label > input', function (e) {
    }
    

    I actually created a function to get the row ID, but I think it just work in the row level.

    TableFeatures.getTableRowId = function (obj) {
        let tr = $(obj.closest('tr'));
        let table = $(obj.closest('table'));
        let data = table.DataTable().row(tr).data();
        return data.id;
    }
    

    but the function doesn't work inside of the event.

    Can you please help me on how to retrieve the row ID in the column event?

    Thank you very much!

    Regards,
    Alex

  • kthorngrenkthorngren Posts: 20,247Questions: 26Answers: 4,761
    edited October 2018

    In looking at your above code it doesn't look like you have a column defined for id using columns.data. Do you have one?

    After this line let data = table.DataTable().row(tr).data(); I would use console.log(data); to see if you are getting the row data. Looks like you should have the row data. return data.id; should return the value of the id column assuming you have one defined. Otherwise please describe what you are expecting as the row 'ID'.

    Kevin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Hi Kevin,

    Thanks for your reply.

    Actually, the column is a radio input, so, I had to inject the ID in the value of the radio to be able to get the original ID of the record.

    Before I tried to get the ID by looking at the table API, but, as its a radio it was changing the row order after clicking on the radio, then I was losing the row ID.

    That's why the injection worked better as I can keep the ID no matter the radio input's behavior.

    The sample you sent me, didn't really work, and the ID was nested very deep inside of the table row and I could not make it clear to retrieve.

    Is there any other way to do that without injecting the ID in the input's value?

    Thank you!

    Regards,
    Alex

  • kthorngrenkthorngren Posts: 20,247Questions: 26Answers: 4,761

    Does your data returned from the AJAX request contain the ID for each row? It doesn't have to be a column but you should be able to access it.

    Assuming this line is working:
    let data = table.DataTable().row(tr).data();

    You should be able to access the ID data object in the return data.id; line. Just change id to the object key name you want to retrieve.

    Maybe you can put together a simple example using an example of some data retrieved in the AJAX response and your table. For me it would be easier to help if I could work with your specific data and code.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Hi Colin and Kevin,

    Thank you very much for your help so far, I really appreciate the time and effort.

    Regards,
    Alex

  • AlexanderLamasAlexanderLamas Posts: 58Questions: 1Answers: 0

    Hi Colin and Kevin,

    Do you guys know how to style the checkbox in the datatable?

    I don't know if it's possible to change the style of a checkbox, but if it is not, is it possible to wrap the checkbox in a DIV tag for example?

    Like <td><div><input type='checkbox'/></div></td>
    

    Thank you!

    Regards,
    Alex

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

    Hi @AlexanderLamas ,

    Yep, possible to do both. If you can post a test case, we can make suggestions on your setup.

    Cheers,

    Colin

  • alexjorgemotaalexjorgemota Posts: 1Questions: 0Answers: 0

    Boa tarde. Estou usando o datatable-checkbox e uma das colunas da tabela é uma DATA (Y-m-d), porém ela sempre inicia a listagem ordenando da DATA mais antiga para a DATA mais atual, e eu gostaria de colocar como padrão que ela iniciasse sempre da DATA mais atual para a DATA mais antiga, como faço?

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

    Hi @alexjorgemota ,

    That is a different issue, so please post in a new thread with a test case. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

This discussion has been closed.