1

I'm trying to implement multiple row selection using checkboxes in my datatable and can't seem to get the checkbox to appear.

I followed this article word for word http://www.gyrocode.com/articles/jquery-datatables-how-to-add-a-checkbox-column/ and it's been helpful but i'm not sure what to do from here.

Beforehand I was using the innerHTML of a column to hold a checkbox for each row but now that I need to be able to select multiple rows I think it's better to use something proven to work like the example in the article.

Anyway, what I had before was this:

    $(document).ready(function () {
        var userData = @Html.Raw(Model.EditUserGroupListJson);
        var table = $('#viewUsers').DataTable({
            "data": userData,
            "columns": [
                { "title": "Email" },
                { "title": "Full Name" },
                { "title": "Member" }
            ],

            "fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
                var tblTds = $('>td', nRow);
                $(nRow).attr("id", 'tblRow_' + aData[2]);

                if (aData[3] == '0')
                {
                    tblTds[2].innerHTML = '<td><input type="checkbox" name="enrolstatus" value="' + aData[2] + '" id="' + aData[2] + '" onclick="Member(' + aData[2] + ')" /><label for="' + aData[2] + '"></label></td>';
                }
                else
                {
                    tblTds[2].innerHTML = '<td><input type="checkbox" name="enrolstatus" value="' + aData[2] + '" id="' + aData[2] + '" checked="checked" onclick="Member(' + aData[2] + ')" /><label for="' + aData[2] + '"></label>></td>';
                }
            }
        })
    });

and now:

    $(document).ready(function () {
        var userData = @Html.Raw(Model.EditUserGroupListJson);
        var table = $('#viewUsers').DataTable({
            'data': userData,
            'columnDefs': [{
                'targets': 0,
                'searchable': false,
                'orderable': false,
                'className': 'dt-body-center',
                'render': function (data, type, full, meta){
                    return '<input type="checkbox" name="id[]" value="'+ $('<div/>').text(data).html() + '">';
                }
            }],
            'order': [[1, 'asc']],

            'fnRowCallback': function(nRow, aData, iDisplayIndex, iDisplayIndexFull){
                var tblTds = $('>td', nRow);
                $(nRow).attr("id", 'tblRow_' + aData[3]);
            }
        });

        //handle click on 'select all' control
        $('#example-select-all').on('click', function(){
            //get all rows with search applied
            var rows = table.rows({ 'search': 'applied' }).nodes();
            //check or uncheck boxes for all rows in the table
            $('input[type="checkbox"]', rows).prop('checked', this.checked);
        });

        //handle click on checkbox to set state of 'select all' control
        $('#example tbody').on('change', 'input[type="checkbox"]', function(){
            //if checkbox is not checked
            if(!this.checked){
                var el = $('#example-select-all').get(0);
                // if 'select all' control is checked and has indeterminate property
                if (el && el.checked && ('indeterminate' in el)){
                    //set visual state of 'select all' control as indeterminate
                    el.indeterminate = true;
                }
            }
        });

        //handle form submission event
        $('#frm-example').on('submit', function(e){
            var form = this;

            //iterate over all checkboxes in the table
            table.$('input[type="checkbox"]').each(function(){
                //if checkbox doesnt exist in DOM
                if(!$.contains(document, this)){
                    //if checkbox is checked
                    if(this.checked){
                        //create hidden element
                        $(form).append(
                            $('<input>')
                                .attr('type', 'hidden')
                                .attr('name', this.name)
                                .val(this.value)
                            );
                    }
                }
            });
        });
    });

My html:

    <table id="viewUsers" class="display table table-bordered" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th><input name="select_all" value="1" id="example-select-all" type="checkbox"></th>                  
                <th>Email</th>
                <th>Full Name</th>
                <th>Member</th>
            </tr>
        </thead>
    </table>

Json:

select new string[] {"", user.Email, user.Forename + ' ' + user.Surname, user.UserID.ToString(), user.CategoryMaps.Where(c => c.CategoryID == id).Count().ToString() };

// if ticked, AddUser, otherwise RemoveUser
function Member(userID) {
    var fullURL = document.URL;
    var url = fullURL.split('EditUserGroup/');
    var categoryID = url[1];
    var postData = { 'userId': userID, 'categoryID': categoryID };
    if ($("#" + userID).is(':checked')) {
        $.post('/Admin/AddCategoryUser/', postData, function (data) {});
    }
    else {
        $.post('/Admin/RemoveCategoryUser/', postData, function (data) {});
    }
};

I've also put a blank " " at the start of my JSON to allow for the checkbox (I think) and i'm quite stuck at the moment.

Any help would be greatly appreciated, thank you.

Newest code

JS:

$(document).ready(function () { var userData = @Html.Raw(Model.EditUserGroupListJson);

    var table = $('#viewUsers').DataTable({
        'data': userData,
        'columnDefs': [{
            'targets': 0,
            'searchable': false,
            'orderable': false,
            //'className': 'dt-body-center',
            'render': function (data, type, full, meta) {
                return '<input type="checkbox" name="id[]" value="'
                   + $('<div/>').text(data).html() + '">';
            }
        }],
        'order': [1, 'asc'],
        "createdRow": function (row, data, dataIndex) {
            $(row).attr("id", "tblRow_" + data[0]);
        }
    });

    // handle select all click control
    $('#example-select-all').on('click', function () {
        // check/uncheck all checkboxes in the table
        var rows = table.rows({ 'search': 'applied' }).nodes();
        $('input[type="checkbox"]', rows).prop('checked', this.checked);
    });

    // handle click on checkbox to set state of select all control
    $('#example tbody').on('change', 'input[type="checkbox"]', function () {
        // if checkbox is not checked
        if (!this.checked) {
            var el = $('#example-select-all').get(0);
            // if select all control is checked and has 'indeterminate' property
            if (el && el.checked && ('indeterminate' in el)) {
                // set visual state of select all control as interminate
                el.indeterminate = true;
            }
        }
    });

    $('#frm-example').on('submit', function (e) {
        var form = this;

        // iterate over all checkboxes in the table
        table.$('input[type="checkbox"]').each(function () {
            // if checkbox doesn't exist in DOM
            if (!$.contains(document, this)) {
                // if checkbox is checked
                if (this.checked) {
                    // create a hidden element
                    $(form).append(
                        $('<input>')
                            .attr('type', 'hidden')
                            .attr('name', this.name)
                            .val(this.value)
                    );
                }
            }
        });

        //testing only

        // output form data to console
        $('#example-console').text($(form).serialize());
        console.log("Form submission", $(form).serialize());

        // prevent actual form submission
        e.preventDefault();
    });
});

HTML:

User Group Membership

        <form id="frm-example" @*action="path/to/script"*@ method="post">
        <table id="viewUsers" class="display table table-bordered" cellspacing="0" width="100%">
            <thead>
                <tr>
                    <th><input name="select_all" value="1" id="example-select-all" type="checkbox"></th>
                    <th>Email</th>
                    <th>Full Name</th>
                </tr>
            </thead>
        </table>
        <p>Press <b>Submit</b> to add selected users to user group.</p>
            <p><button>Submit</button></p>

            <pre id="example-console"></pre>
        </form>
2
  • Can you attach the JSON that you receive? Commented Mar 1, 2016 at 11:55
  • done, thanks @Stargazer Commented Mar 1, 2016 at 12:42

2 Answers 2

1

Here is working fiddle

I've changed only var userData. It should be like this. ID is necessary.

var userData = [
      [
         "1",
         "Tiger Nixon",
         "System Architect",
         "Edinburgh"
      ],
      [
         "2",
         "Garrett Winters",
         "Accountant",
         "Tokyo"
      ],
      [
         "3",
         "Ashton Cox",
         "Junior Technical Author",
         "San Francisco"
      ]
]
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the fiddle, it's helped a lot. Just one question about the form action: <form id="frm-example" action="/path/to/your/script" method="POST"> what path is this referring to? Should I give my entire datatables function a name starting from $(document).ready(function () { var userData = @Html.Raw(Model.EditUserGroupListJson); var table = $('#viewUsers').DataTable({ 'data': userData, 'columnDefs': [{......... ....... and call it like javascript:functionName() ?
1. action="/path/to/your/script" - this is the path to the script which will process the data from your form. Here is in details w3schools.com/tags/att_form_action.asp 2. $(document).ready - it means that the script start working only after DOM were loaded. You need the DOM to be loaded to find such element, for example, as $('#viewUsers'), and other elements. While DOM is not loaded you will not find them. More details w3schools.com/jquery/event_ready.asp
Thanks for the reading, I get it now. My issue now is getting the checkbox to appear in the header, i've tried all afternoon and haven't been able to manage it. Based on my latest code update in my question is there anything you can see that might explain why? Thanks for the help
Here, in this example gyrocode.com/articles/… there is also a checkbox in the header - this checkbox selects all rows in your table. Don't you need this feature?
I haven't found appropriate option here datatables.net/manual/options to disable the header checkbox (and I don't think it is good idea) but if you need you can do it with .css - look here jsfiddle.net/HellLena/hayd86mn/4
|
0

Mos likely your JSON response is incorrect. With your table structure it should be:

var userData = [
   [ "UserId", "Email", "Full Name", "Member" ],
   [ "UserId", "Email", "Full Name", "Member" ]
];

First value UserId will be used as value for checkboxes.

To assign ID to tr elements, use the code below instead:

"createdRow": function(row, data, dataIndex){
   $(row).attr("id", "tblRow_" + data[0]);
}

See this jsFiddle for code and demonstration.

7 Comments

thanks a lot, I don't know how I missed the userid corresponding to ID. as for assigning id to tr elements, could you maybe explain that chunk of code to me in plain english?
@bjjrolls, I'm the author of the article you've mentioned. See this jsFiddle for code and demonstration.
also, i've been using a onclick on the checkbox before that calls a JS function which splits the url to glean userID and categoryID, and basically if the box is checked go to an AddUser controller otherwise RemoveUser. I'll edit my original question to include this function now. By the way it's pretty cool that the author of the website I've been working off has replied directly.
@bjjrolls, There is a change handler for each checkbox already in the code. Just call Member(this.value) inside this handler $('#example tbody').on('change', 'input[type="checkbox"]', function(){.
Brilliant, thank you. The thing that i'm confused about is the syntax (and the use) of <form id="frm-example" action:"/path/to/your/script/" ... /> which script does this refer to, and how is it called?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.