tech @ Beacon Deacon

A DataTable with hybrid customized drop-down menus -- manual and alphabetized

Jamie Johnson

January 31, 2020

I recently revisited a project I developed in the past using SpryMedia's DataTables Table plug-in for jQuery. The customer wanted some customizations to their drop-down select menus dynamically created by the plug-in. One was to have the days of the week in the drop-down listed in order. The other was having data, which included linked and unlinked text to display in alphabetical order instead of the randomly created order set up by the plug-in. Well, I made a hybrid customization for the manual part that uses both my own code and the plug-in. And I made a second customization for alphabetizing the mixed content (linked and unlinked text) using my own code. See the implementation below.

Day Activity Location
Sunday Learn TBA
Sunday Worship Church
Sunday Rest/Relaxation/Recreation Home
Monday Work Office
Tuesday Work Office
Tuesday Hockey Gym
Tuesday Trail Life Church
Wednesday Work Office
Wednesday Awana Church
Wednesday Date night! TBA
Thursday Work Office
Thursday Hockey Gym
Thursday Worship Team Practice Church
Friday Work Office
Friday Lunch out TBA
Saturday Fun! TBA
Saturday Chores TBA

Want the code? Here it is (noting that you will need to reference the external JS and CSS differently) with the customizations highlighted:

<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>

<div id="demo"> 
<table> 
    <tr style="width:100%"> 
        <td colspan="3" id="selections"></td> 
    </tr> 
</table>             
<table border="0" cellpadding="0" cellspacing="0" class="datatable display" id="example" summary="Table">
<thead>
    <tr class="dropdown">
        <td class="day"></td>        <td class="activity"></td>        <td class="location"></td>
    </tr>
    
    <tr>
        <th class="day" scope="col">Day</th>        
        <th class="activity" scope="col">Activity</th>
        <th class="location" scope="col">Location</th>
    </tr>

</thead>
<tfoot style="display:table-header-group"> 
<tr> 
 <td></td> 
 <td></td> 
 <td></td> 
</tr> 
</tfoot>  
<tbody>
<tr>
        <td>Sunday</td>
        <td>Learn</td>
        <td>TBA</td>
</tr>
<tr>
        <td>Sunday</td>
        <td>Worship</td>
        <td>Church</td>
<tr>
        <td>Sunday</td>
        <td>Rest/Relaxation/Recreation</td>
        <td>Home</td>
<tr>
        <td>Monday</td>
        <td>Work</td>
        <td>Office</td>
<tr>
        <td>Tuesday</td>
        <td>Work</td>
        <td>Office</td>
<tr>
        <td>Tuesday</td>
        <td>Hockey</td>
        <td>Gym</td>
</tr>
<tr>
        <td>Tuesday</td>
        <td><a href="https://www.traillifeusa.com/">Trail Life</a></td>
        <td>Church</td>
<tr>
        <td>Wednesday</td>
        <td>Work</td>
        <td>Office</td>
<tr>
        <td>Wednesday</td>
        <td><a href="https://www.awana.org/">Awana</a></td>
        <td>Church</td>
<tr>
        <td>Wednesday</td>
        <td>Date night!</td>
        <td>TBA</td>
</tr>
<tr>
        <td>Thursday</td>
        <td>Work</td>
        <td>Office</td>
    </tr> 
<tr>
        <td>Thursday</td>
        <td>Hockey</td>
        <td>Gym</td>
</tr>
<tr>
        <td>Thursday</td>
        <td>Worship Team Practice</td>
        <td>Church</td>
</tr> 
<tr>
        <td>Friday</td>
        <td>Work</td>
        <td>Office</td>
</tr> 
<tr>
        <td>Friday</td>
        <td>Lunch out</td>
        <td>TBA</td>
</tr>
<tr>
        <td>Saturday</td>
        <td>Fun!</td>
        <td>TBA</td>
</tr> 
<tr>
        <td>Saturday</td>
        <td>Chores</td>
        <td>TBA</td>
</tr> 
</tbody>
</table>


<!-- end DataTables plug-in --> 
<style type="text/css"><!-- 
.dataTables_filter { position: relative; left: -40px; } 
--></style> 
<style type="text/css"><!--
.dataTables_filter { position: relative; left: -40px; }
--></style>
<script type="text/javascript">// <![CDATA[
var used=''; // johns2ja 
var xd=''; //johns2ja
$(document).ready(function() {
    var sels=0;
    var seltxt='';
    var mesa = $('.datatable').DataTable( {  
        responsive: true, 
        ordering: false, 
        pageLength: 150, 
        //"search": { "search": searchquery }, 
        "bAutoWidth": false, // toggle this depending on how wide you want the table 
        columns: [ 
            { data: 'day' }, 
            { data: 'activity' }, 
            { data: 'location' } 
        ], 
 
        initComplete: function () { // After DataTable initialized 
            this.api().columns().every( function () { 
            /* use of [1,2,3] for second, third and fourth column.  Leave blank - columns() - for all.  
            Multiples? Use columns([0,1]) for first and second, e.g. */ 
                 var column = this;  
                 sels++;
                 if(sels==1){seltxt='Day';}
                 if(sels==2){seltxt='Activity';}
                 if(sels==3){seltxt='Location';}
                 // start manual drop-down customization
                 if(sels==1){ //scope for manual customization for days of week drop-down select menu 
                    select = $('<select id="sel'+sels+'"><option value="">'+seltxt+'</option><option>Sunday</option><option>Monday</option><option>Tuesday</option><option>Wednesday</option><option>Thursday</option><option>Friday</option><option>Saturday</option></select>') 
                      .appendTo( $('#selections') )  
                      .on( 'change', function () { 
                           var val = $.fn.dataTable.util.escapeRegex( 
                                $(this).val() 
                           );  
                      column 
                           .search( val ? '^'+val+'$' : '', true, false ) 
                           .draw(); 
                      } ); 
                 } else {
                     // end manual drop-down customization
                    select = $('<select id="sel'+sels+'"><option value="">'+seltxt+'</option></select>') // id used for customization
                      //.appendTo( $(column.footer()).empty() ) // an option not used 
                      .appendTo( $('#selections') )  
                      .on( 'change', function () { 
                           var val = $.fn.dataTable.util.escapeRegex( 
                                $(this).val() 
                           ); 
                      column 
                           .search( val ? '^'+val+'$' : '', true, false ) 
                           .draw(); 
                      } ); 
                 column.data().unique().sort().each( function ( d, j ) { 
                     if(d.indexOf('href')!=-1){// conditional functionality to remove link markup code from options
                         dRA=d.split('>');// gets string after the <a href....>
                         d=dRA[1];
                         d=d.substr(0,d.length-3); // takes off last 3 characters: /a>
                     }
                     xd='~'+d;
                     if(used.indexOf(xd)==-1){//conditioned to prevent duplicates
                        select.append( '<option value="'+d+'">'+d+'</option>' )
                     }
                     used+=xd;
                 } ); 
                 } // close scope for manual drop-down customization 
            } ); // this.api function 
        } //initComplete function  
    } );
});
$( window ).resize(function() { 
  $('.datatable').removeAttr('style');
});
// start alphabetical customization on Activity column 
$(document).ready(function(){
    // sort Activity list drop-down select menu 
    var activity_options = $("#sel2 option");
    activity_options.sort(function(a,b) {
        if(a.text != 'Activity' && b.text != 'Activity'){ // don't include the generic Activity in the list re-ordering -- keep it first 
            if (a.text > b.text) return 1;
            else if (a.text < b.text) return -1;
            else return 0
        }
})
$("#sel2").empty().append(activity_options);
$("#sel2 option").each(function(){
    if($(this).html()=='Activity'){
        $(this).attr('selected','selected'); // set the generic Activity option as the selected one.
    }
});
});
// end alphabetical customization on Activity column
// ]]></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; }
}
@media all and (max-width:640px){
    #example_length { padding-bottom: 1em; }
}
#selections select { margin: 0px 5px;  }
--></style>
</div>

Back to top


Other DataTable Articles:

A Basic DataTable

Making Tables Responsive

A Filtered DataTable

A DataTable with an Initial Search Value

A DataTable with Initial Column Search Values

A DataTable with AJAX

A DataTable with Drop-down Select Menus

A DataTable with Multiple Drop-down Select Menus

A DataTable with customized drop-down menus