Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTables set aoColumns after getting server data

I'm using DataTables with server side data to display several tables with details (expanding sub tables). There are two types of sub tables one with three columns one with 7 columns.

I would like to set the value of aoColumns after I have retrieved data from the server and before the row is displayed but Im having a hard time doing it. Here is what I have so far.

self.createDataTable = function(identifier, source, rowCallback, initCallback) {
var columnsA = [
        { "mDataProp": "index", "sClass": "index", "bSortable": false },
        { "mDataProp": "text", "sClass": "top-dd", "bSortable": false },
        { "mDataProp": "stats", "sClass": "top-dd stats", "bSortable": false }
    ];
var columnsB = [
        { "mDataProp": "index", "sClass": "index", "bSortable": false },
        { "mDataProp": "check-box", "sClass": "check-box" },
        { "mDataProp": "foundDate", "sClass": "date" },
        { "mDataProp": "pageLink", "sClass": "link" },
        { "mDataProp": "linkText", "sClass": "text" },
        { "mDataProp": "ipAddress", "sClass": "ip" },
        { "mDataProp": "otherLinks", "sClass": "more dd-second-" + thisTR.id }
    ];

$(identifier).dataTable({
    "bPaginate": false,
    "bLengthChange": false,
    "bFilter": false,
    "bSort": true,
    "bInfo": false,
    "bAutoWidth": false,
    "oLanguage": { "sEmptyTable": 'No patterns found' },
    "bProcessing": true,
    "bServerSide": true,
    "sAjaxSource": source,
    "fnServerParams": function(aoData) {
        aoData.push({ "name": "uniqueid", "value": self.uniqueid },
                    { "name": "basedomain", "value": basedomain },
                    { "name": "return_this", "value": $(this).data('returnid') });
    },
    "aoColumns": columnsA,
    "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {                
        return rowCallback(nRow, aData);
    },
    "fnInitComplete": function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
        initCallback();
    }

});

Basically I would like to catch data from the server, look at a flag passed from the server, set aoColumns and then continue as normal. Any ideas? Im looking through the callback functions http://datatables.net/usage/callbacks but Im having a hard time setting the columns once Im in a callback.

I'm also reading the following but Im not getting the desired results.

  • Altering jquery datatables aoColumns
  • http://www.datatables.net/usage/columns
like image 700
RachelD Avatar asked May 03 '13 14:05

RachelD


1 Answers

Ok I found a solution though its a little round about. Basically I create a columns variable with all possible columns. I set aoColumns using this variable and I also add the variable to my aoData and send it to the server.

Here's my server side PHP code:

$returnArray = $patternHandler->getGroupsForSection($_GET['return_this']);

if(count($returnArray) > 0) {
    $hiddenCoulumns = array();
    $columns = json_decode($_GET['columns'], true);
    $testRow = $returnArray[0];

    for($i = 0; $i < count($columns); $i++) {
        if(!isset($testRow[$columns[$i]['mDataProp']])) {
            foreach($returnArray AS &$row) {
                $row[$columns[$i]['mDataProp']] = '';
                $hiddenCoulumns[] = $i;
            }
        }
    }
}

echo json_encode(array(
            'sEcho' => intval($_GET['sEcho']),
            'iTotalRecords' => count($returnArray),
            'iTotalDisplayRecords' => count($returnArray),
            'aaData' => $returnArray,
            'hiddenColumns' => $hiddenCoulumns));

You see that I get the $returnArray (my formatted associative array representing data table rows) as normal. Then I loop through my columns variable that I passed. If a value for mDataProp isn't in my return array I just add a blank string to make data tables happy.

So if I stopped here I would have a bunch of blank columns in each row for my data table. To hide the empty columns I return a array of $hiddenColumns back to the "fnServerData" function which is the callback for the ajax call that gets the data. Here I just loop through my returned hiddenColumns and hide them. The user is none the wiser :)

Here's my JavaScript:

self.createDataTable = function(identifier, source, rowCallback, initCallback) {
    var columns = [
        { "mDataProp": "index", "sClass": "index", "bSortable": false },
        { "mDataProp": "text", "sClass": "top-dd", "bSortable": false },
        { "mDataProp": "stats", "sClass": "top-dd stats", "bSortable": false },
        { "mDataProp": "check-box", "sClass": "check-box" },
        { "mDataProp": "foundDate", "sClass": "date" },
        { "mDataProp": "pageLink", "sClass": "link" },
        { "mDataProp": "linkText", "sClass": "text" },
        { "mDataProp": "ipAddress", "sClass": "ip" },
        { "mDataProp": "otherLinks", "sClass": "more dd-second-" }
    ];

    var patternsTable = $(identifier).dataTable({
        "bPaginate": false,
        "bLengthChange": false,
        "bFilter": false,
        "bSort": true,
        "bInfo": false,
        "bAutoWidth": false,
        "oLanguage": { "sEmptyTable": 'No patterns found' },
        "bProcessing": true,
        "bServerSide": true,
        "sAjaxSource": source,
        "fnServerData": function (sSource, aoData, fnCallback) {
            /* Add some extra data to the sender */
            aoData.push( { "name": "more_data", "value": "my_value" } );
            $.getJSON( sSource, aoData, function (json) { 
                    /* Get server data callback */
                    for(var i = 0; i < json.hiddenColumns.length; i++) {
                        patternsTable.fnSetColumnVis(json.hiddenColumns[i], false);
                    }
                    fnCallback(json)
            } );
        },
        "fnServerParams": function(aoData) {
            aoData.push({ "name": "uniqueid", "value": self.uniqueid },
                        { "name": "basedomain", "value": basedomain },
                        { "name": "return_this", "value": $(this).data('returnid') },
                        { "name": "columns", "value": JSON.stringify(columns)});
        },
        "aoColumns": columns,
        "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {                
            return rowCallback(nRow, aData);
        },
        "fnInitComplete": function(oSettings, iStart, iEnd, iMax, iTotal, sPre) {
            initCallback();
        }

    });
}
like image 89
RachelD Avatar answered Nov 15 '22 07:11

RachelD