How to update a server side datatable on change a checkbox from outside of datatable

2.3k views Asked by At

I am using data table with Grails. I have a check box outside the data table and on its event I want to load the table again with the check box value. Here are my attempts below :

In my view where the check box is >>

<g:checkBox id="wrapCheck" name="wrapCheck"/> Wrapped

Here is my attempts in view where I am calling server method >>

$('#wrapCheck').on('click', function (e) {
    setWrapActiveStatus();
    var referenceId = $('#callForWrap').val();
    jQuery.ajax({
        type: 'POST',
        dataType: 'JSON',
        url: "${g.createLink(controller: 'androidGame',action: 'ajaxAndroidGameList')}?wrapCheck=" + referenceId,
        %{--url: "${g.createLink(controller: 'androidGame',action: 'ajaxListByWrapActiveStatus')}?wrapCheck=" + referenceId,--}%
        success: function (data, textStatus) {
            if (data.isError == false) {
                $('#example').DataTable().ajax.reload();
            } else {
                alert(data.message);
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
        }
    });
});

here is my setWrapActiveStatus() function >>

function setWrapActiveStatus(){
    if($("#wrapCheck").prop('checked') == true){
        $('#callForWrap').val("1");
    }else{
        $('#callForWrap').val("");
    }
}

And here is my Controller Action >>

def ajaxAndroidGameList() {
    LinkedHashMap gridData
    String result
    LinkedHashMap resultMap = androidGameService.androidGamePaginateList(params)
    if(params.wrapCheck == "1"){
        resultMap = androidGameService.androidGamePaginateListByWrapStatus(params)
    }

    // LinkedHashMap resultMap = androidGameService.androidGamePaginateList(params)

    if(!resultMap || resultMap.totalCount== 0){
        gridData = [iTotalRecords: 0, iTotalDisplayRecords: 0, aaData: []]
        result = gridData as JSON
        render result
        return
    }
    int totalCount = resultMap.totalCount
    gridData = [iTotalRecords: totalCount, iTotalDisplayRecords: totalCount, aaData: resultMap.results]
    result = gridData as JSON
    render result
}

My action is response well only wrapped list but data table does not update.

EDIT - Data table Initialization

$('#example').dataTable({
                "sPaginationType": "full_numbers",
                "bAutoWidth": true,
                "bServerSide": true,
                "iDisplayLength": 10,
                "deferLoading": ${totalCount?:0},
                "sAjaxSource": "${g.createLink(controller: 'androidGame',action: 'ajaxAndroidGameList')}",
                "fnRowCallback": function (nRow, aData, iDisplayIndex) {
                    if (aData.DT_RowId == undefined) {
                        return true;
                    }
                    $('td:eq(4)', nRow).html(getStatusIcon(nRow, aData[4])).css({textAlign: 'center'});
                    $('td:eq(5)', nRow).html(getStatusIcon(nRow, aData[5])).css({textAlign: 'center'});
                    $('td:eq(6)', nRow).html(getActionBtn(nRow, aData)).css({textAlign: 'center'});
                    return nRow;
                },
                "aoColumns": [
                    null,
                    { "bSortable": false },
                    { "bSortable": false },
                    { "bSortable": false },
                    { "bSortable": false },
                    { "bSortable": false },
                    { "bSortable": false }
                ]
            });
1

There are 1 answers

3
Gyrocode.com On BEST ANSWER

In your DataTables initialization code you need to use option fnServerParams to modify data sent to the server.

I have also corrected deferLoading which should be iDeferLoading, see iDeferLoading.

Below is modified DataTables initalization code:

$('#example').dataTable({
    "sPaginationType": "full_numbers",
    "bAutoWidth": true,
    "bServerSide": true,
    "iDisplayLength": 10,
    "iDeferLoading": ${totalCount?:0},
    "sAjaxSource": "${g.createLink(controller: 'androidGame',action: 'ajaxAndroidGameList')}",
    "fnServerParams": function (aoData){
       aoData.push({ 
          "name": "wrapCheck", 
          "value": $("#wrapCheck").prop('checked') ? "1" : "" 
       });
    },
    "fnRowCallback": function (nRow, aData, iDisplayIndex) {
        if (aData.DT_RowId == undefined) {
            return true;
        }
        $('td:eq(4)', nRow).html(getStatusIcon(nRow, aData[4])).css({textAlign: 'center'});
        $('td:eq(5)', nRow).html(getStatusIcon(nRow, aData[5])).css({textAlign: 'center'});
        $('td:eq(6)', nRow).html(getActionBtn(nRow, aData)).css({textAlign: 'center'});
        return nRow;
    },
    "aoColumns": [
        null,
        { "bSortable": false },
        { "bSortable": false },
        { "bSortable": false },
        { "bSortable": false },
        { "bSortable": false },
        { "bSortable": false }
    ]
});

Then for checkbox click event handler all you need to do is:

DataTables 1.10

$('#wrapCheck').on('click', function (e) {
    $('#example').DataTable().ajax.reload();
});

DataTables 1.9

$('#wrapCheck').on('click', function (e) {
    $('#example').dataTable().fnDraw();
});

NOTE:

Please note, that your DataTables initialization code and server-side code are using older naming conventions for DataTables 1.9. DataTables 1.10 is backward compatible, meaning that it supports both new and old naming conventions. But with the release of new versions, the compatibility may be dropped, and you may want to consider updating your code according to 1.9 to 1.10 upgrade guide and Converting 1.9 naming to 1.10.