tech @ Beacon Deacon

A DataTable with Drop-down Select Menus - Jamie Johnson

Jamie Johnson

September 20, 2017

A few months ago, I wrote an article about A DataTable with AJAX using SpryMedia's DataTables Table plug-in for jQuery. This implementation offers how to add a drop-down select menu. In the example, one can use the drop-down to only see the male or only see the female villains. Check it out:

Alias Name Gender Appeared

The DataTable documentation at https://datatables.net/examples/api/multi_filter_select.html only shows how to do this with the drop-down below the table in the table footer (<tfoot>) and on every column. So, how did I get the drop-down select menu to only show up for the third column above the table header (<thead>)? I used classed cells and some custom JavaScript (In bold in the below code). Here's the code (pay attention to the bold section and comments therein. I have made assets linkable for your convenience):

<script type="text/javascript" src="datatable/jquery-1.12.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="datatable/datatables.min.css"/>
<script type="text/javascript" src="datatable/datatables.min.js"></script>
<table cellpadding="0" cellspacing="0" border="0" class="display datatable">

<thead>
    <tr class="dropdown">
        <td class="first"></td>
        <td class="second"></td>
        <td class="third"></td>
        <td class="fourth"></td>
    </tr>
    
    <tr>
        <th class="first">Alias</th>
        <td class="second">Name</td>
        <td class="third">Gender</td>
        <td class="fourth">Appeared</td>
    </tr>

</thead>
<tbody id="itemsoutput">
</tbody>
</table>
<style type="text/css">
    <!--
.dataTables_filter { position: relative; left: -40px; }
-->
</style>
<script type="text/javascript">
$(document).ready(function() {
    var mesa = $('.datatable').DataTable( { 
        responsive: true,
        ajax: "http://tech.beacondeacon.com/batman.txt",/* It would make since to generate this dynamically from XML 
        with a server-side language like perl. For this example, I am using a static file.  However, here is a 
        perl script to  do it: batmandata.cgi*/
        columns: [
            { data: 'alias' },
            { data: 'name' },
            { data: 'gender' },
            { data: 'appeared' }
        ],

        initComplete: function () { // After DataTable initialized
            this.api().columns([2]).every( function () {
            /* use of [2] for third column.  Leave blank - columns() - for all. 
            Multiples? Use columns[0,1]) for first and second, e.g. */
                 var column = this; 
                 var select = $('<select><option value=""/></select>')
                      .appendTo( $('.datatable .dropdown .third').empty() )
                      .on( 'change', function () {
                           var val = $.fn.dataTable.util.escapeRegex(
                                $(this).val()
                           );
                      /* above - appendTo uses my customized classes instead of doing 
                      .appendTo(columns.header()) or .appendTo(columns.footer()) – Jamie */
                      column
                           .search( val ? '^'+val+'$' : '', true, false )
                           .draw();
                      } );
                 column.data().unique().sort().each( function ( d, j ) {
                      select.append( '<option value="'+d+'">'+d+'</option>' )
                 } );
            } ); // this.api function
        } //initComplete function 

    } );
} );
$( window ).resize(function() { 
  $('.datatable').removeAttr('style');
}); 
</script>
<style type="text/css">
<!--
@media all and (min-width: 120px){
.tabular-row, .tabular-cell { display: block; }
}
@media all and (min-width: 769px){
.tabular-row{ display: table-row; }
.tabular-cell { display: table-cell; }
}
-->
</style>

There are probably some more dynamic things one can do to determine which column to use, etc., but this will get you started. Happy coding!

Reminder

Depending on your server, protocols may be picky when referencing data resources.

Back to top