Adding dynamic ajax data to DataTable, a jQuery Table Plugin

via Axiom Zen

Recently on PedeDelivery I’ve been working with some loads of data to display on admin panels, and it can be pretty boring to make custom searches and sorts on the server side (as well as expensive up from some rates).

In order to counter this issues, I am using the DataTable jQuery plugin, which is able to deal with some huge amount of data, and is extremely featured and at the same time, customizable.

On a client that have to deal with server updating data IRT, reloading all the rows is very undesirable to happen all over again on a AJAX callback. So instead, lets just require from the server new content, in JSON format.

pd web app

The PROBLEM here are the arguments .fnAddData() is able to take: a Array OR a Array of Arrays. But I need to add class to the TD Element and still bind with some events! For this purpose I made the function tidy_up_row(), see below.

oh, cut the crap! Snippet/Solution

Data request is made periodically to the server, that returns a JSON array with all the new content (that’s server responsibility I am using Rails for the task).

  // Initialize with all ids from the server in a hash
  $orders = ( { 10 : true,
                     11: true
                     // and so on
                   } )

  function periodic_update_DataTable(){
    j.ajax({

        url: "painel_restaurante/sync_data",
        success:
          function(data, status, xhr){
            add_multiple_rows( data );
          },
        complete:
          function(a,b,c){
            setTimeout( periodic_update_DataTable, 30*1000)
          },
        dataType: 'json'
      }
    )
    return true;
  }

  function add_multiple_rows( arr_arr ){

    var added = new Array();
    var count = 0;

    for (var i=0; i < arr_arr.length; i++) {
      var id = arr_arr[i].pop();

      // only add order if not found in table
      if( !$orders[id] ){

        // see http://www.datatables.net/api
        var added_aoData =  j('.data_table').dataTable().fnAddData( arr_arr[i] )[0];

        var row = j('.data_table').dataTable().fnSettings().aoData[ added_aoData ].nTr;

        tidy_up_row(row, id);

        $orders[id] = true

        count++;
      }

    };

    console.log( 'Added rows', count );

  }

  function tidy_up_row(row, id){
    var jrow = j(row).attr('data-order-id', id);

    jrow.children('td:eq(0)').addClass('order_cell1').click( click_order_detail );
    jrow.children('td:eq(1)').addClass('order_cell2').click( click_order_detail );
    jrow.children('td:last').addClass('order_actions');
  }

j(document).ready(function(){

    // Initialize the table just the way you do normally. (in my case I18n to Portuguese-BR)
    j('table.data_table').dataTable({ // http://datatables.net/examples/basic_init/filter_only.html
      "aaSorting": [[ 0, "desc" ]],
      "iDisplayLength": 50,
      "bAutoWidth": true,
      "oLanguage": {
        "sLengthMenu": "_MENU_ entradas por página",
        "sZeroRecords": "Vazio!",
        "sInfo": "Exibindo de _START_ até _END_. Total de: _TOTAL_ entradas",
        "sInfoEmpty": "Nenhuma entrada",
        "sInfoFiltered": "(total de _MAX_ entradas)",
        'sSearch' : "Busca"
      }
    });

   setInterval(function(){ j("td.order_cell1").updatePrettyTime(); }, 30*1000);

  // Other inits ...
  })

Discussion

It is very important to notice that I haven’t done anything new, its just that, this exact mode of use I haven’t found anywhere else.

I see no downsides on this method, just go ftw! 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s