Wednesday, 18 February 2015

Adding a column with delete button action within HTML table generated with DataTables JQuery plugin

The problem I encountered recently was to add  an action such as a "delete" link/button having a table using Ajax and DataTables JQuery plugin (from http://www.datatables.net/)

Since I may not be the only one having to solve that issue, I decided to make this article to share this solution.

The problem... 

Imagine an HTML table such  as :
 <head>
[...]
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

    <script  type="text/javascript"  src="../js/media/js/jquery.dataTables.min.js"></script> 
[..]
  <script type="text/javascript" src="../js/custom.js"></script>
</head>
  <body>
[..]
 <table  id="tbrefundall">
          <thead>
              <tr>
                 <th>No Order </th>
                 <th>Refund Amount</th>
                 <th>refund Type</th>
                 <th>Date Order</th>
                 <th>Date Refund</th>
               </tr>
           </thead>

           <tfoot>
               <tr>
                 <th>No Order </th>
                 <th>Refund Amount</th>
                 <th>refund Type</th>
                 <th>Date Order</th>
                 <th>Date Refund</th>
               </tr>
          </tfoot>
     </table>   
[..]
  <body>
[..]



And the javascript file, 'custom_delay.js'  with the following content :
var table_blocage_fraud_synchro =  $('#tbblocage_fraud_synchro').dataTable( {
       "language": {
           "url": "http://localhost/DataTables.French.json"  
       },
        "ajax": {
            "url": "http://localhost/table.json",
            "dataSrc": ""
        },
        "columns": [           
            { "data": "No_order" },
            { "data": "Amount_Refund" },
            { "data": "No_transaction_refund" },
            { "data": "Date_Order" },
            { "data": "Date_Refund" }
        ]
    } );

The Solution...

The first thing is to add a new column "head" and "foot" into the HTML file:
 <table  id="tbrefundall">
          <thead>
              <tr>
                 <th>No Order </th>
                 <th>Refund Amount</th>
                 <th>refund Type</th>
                 <th>Date Order</th>
                 <th>Date Refund</th>
                 <th>Action</th>
               </tr>
           </thead>

           <tfoot>
               <tr>
                 <th>No Order </th>
                 <th>Refund Amount</th>
                 <th>refund Type</th>
                 <th>Date Order</th>
                 <th>Date Refund</th>
                 <th>Action</th>
               </tr>
          </tfoot>
     </table>  


The second is to alter the javascript file, by adding the id of the delete action as the new column data in the dataTables (which will here the 'no_commande') and redefining the column content using columnDefs Datatable option :
var table_blocage_fraud_synchro =  $('#tbblocage_fraud_synchro').dataTable( {
       "language": {
           "url": "http://localhost/DataTables.French.json"  
       },
        "ajax": {
            "url": "http://localhost/table.json",
            "dataSrc": ""
        },
        "columns": [           
            { "data": "No_order" },
            { "data": "Amount_Refund" },
            { "data": "No_transaction_refund" },
            { "data": "Date_Order" },
            { "data": "Date_Refund" },
            { "data": "No_order" }
        ]
        "columnDefs":[
            {
                "render": function ( data, type, row ) {
                    var LnkDelete = '<a  href="http://localhost/delete.php?id=' + data + '"> delete' + ' </a>';
                    return lnkDelete;
                },
                "targets": [5]
            }


        ]
    } );

You can notice that, within the "render" function , "data" correspond here to the input data of the sixth column (id for the delete action), being referred by adding this option (0 corresponding to the first column) : "targets":[5];


You can transform a link to a button using bootstrap (cf. http://getbootstrap.com/), by adding this class element to the 'a'  tag :  class="btn btn-danger btn-sm"  role="button"

Redefining the content of an existing column

You can also alter the content of a column by defining a new render function within a new "json" input for "columnDefs" DataTables option; imagine that the No_transaction_refund  (column no 3 equivalent to targets[2])  data is not directly the data you would like to show in the table but the refund type being defined such as this : the refund type equals to "Goodwill Gesture", if No_transaction_refund  data is empty, otherwise, the refund type equals to "Cancellation"

The solution is shown below in Red :

        "columnDefs":[
            {
                "render": function ( data, type, row ) {
                    var LnkDelete = '<a  href="http://localhost/delete.php?id=' + data + '"> delete' + ' </a>';
                    return lnkDelete;
                },
                "targets": [5]
            },
           {"render": function ( data, type, row ) {
                    if (data === undefined || data === null) return '<span  class="label label-warning" > Goodwill Gesture</span>';
                    else return '<span  class="label label-info" > Cancellation</span>';
                },
                "targets": [2]
           }
]

For the use of the class defined above (class = "label .."), Bootstrap is required (cf. http://getbootstrap.com/) ; if  you do not want to depend on Bootstrap, you can just delete it;


Note that we can also use row properties to access column values to do the same thing  :



"render": function ( data, type, row ) {
                    if (row["No_transaction_refund"] === undefined || row["No_transaction_refund"] === null) return '<span  class="label label-warning" > Goodwill Gesture</span>';
                    else return '<span  class="label label-info" > Cancellation</span>';
                },
                "targets": [2]
}
 

Here is the final output :