Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Jquery DataTable with Custom Filter with Materialize CSS

5.00/5 (6 votes)
12 Oct 2016CPOL2 min read 47.2K   1.9K  
Jquery Datatable already provides individual column filters. However, we can leverage that to create our custom filter that works similar to Excel filter.

Introduction

Jquery datatable provides individual column filtering but not on group of columns. Moreover, we can only select one item from each column. This article actually demonstrates how we can leverage the column level filtering to create a custom filter that just works like Excel filter, i.e., user can type to filter items and those items will be slected on the main grid.

Background

This article uses Jquery Datatable for the grid and filter API. Please have a look at the actual documentation here.

Using the Code

This code uses the basic initialization of Jquery Datatable with a static Json dataset. However, the dataset can be pulled via a webservice easily and integrated.

Once the table is initailized, it calls configFilter function with the desired column numbers passed as an input array. This function actually loops through the data of each column passed, and creates a filter dialog with individual data listed under one column.

Example: If the input array passed as [1,2], then it will create two filter popups/dialogs with the data of column 2 and column 3 (array is zero index based).

The actual source code is listed below:

JavaScript
//This function initializes the content inside the filter modal
function configFilter($this, colArray) {
            setTimeout(function () {
                var tableName = $this[0].id;
                var columns = $this.api().columns();
                $.each(colArray, function (i, arg) {
                    $('#' + tableName + ' th:eq(' + arg + ')').append
                    ('<img src="http://www.icone-png.com/png/39/38556.png" 
                    class="filterIcon" onclick="showFilter(event,\'' + 
                    tableName + '_' + arg + '\')" />');
                });

                var template = '<div class="modalFilter">' +
                                 '<div class="modal-content">' +
                                 '{0}</div>' +
                                 '<div class="modal-footer">' +
                                     '<a href="#!" 
                                     onclick="clearFilter(this, {1}, \'{2}\');"  
                                      class=" btn left waves-effect waves-light">Clear</a>' +
                                     '<a href="#!" 
                                     onclick="performFilter(this, {1}, \'{2}\');" 
                                      class=" btn right waves-effect waves-light">Ok</a>' +
                                 '</div>' +
                             '</div>';
                $.each(colArray, function (index, value) {
                    columns.every(function (i) {
                        if (value === i) {
                            var column = this, content = '<input type="text" 
                            class="filterSearchText" 
                            onkeyup="filterValues(this)" /> <br/>';
                            var columnName = $(this.header()).text().replace(/\s+/g, "_");
                            var distinctArray = [];
                            column.data().each(function (d, j) {
                                if (distinctArray.indexOf(d) == -1) {
                                    var id = tableName + "_" + columnName + "_" + j; 
                                    content += '<div><input type="checkbox" value="' + 
                                    d + '"  id="' + id + '"/>
                                    <label for="' + id + '"> ' + 
                                    d + '</label></div>';
                                    distinctArray.push(d);
                                }
                            });
                            var newTemplate = $(template.replace('{0}', content).replace
                            ('{1}', value).replace('{1}', value).replace('{2}', tableName).replace
                            ('{2}', tableName));
                            $('body').append(newTemplate);
                            modalFilterArray[tableName + "_" + value] = newTemplate;
                            content = '';
                        }
                    });
                });
            }, 50);

The filter actually looks like this:

Once the filters are initialized based upon the desired columns, the filter popups can be clicking the filter icons of the column header. User can now type in the textbox or click on the checkbox and press 'OK'. The filter will now be applied on the grid and matching rows will be selected. The 'Clear' button. The actual source code can be found out in the zipped folder.

JavaScript
//Execute the filter on the table for a given column
        function performFilter(node, i, tableId) {
            var rootNode = $(node).parent().parent();
            var searchString = '', counter = 0;

            rootNode.find('input:checkbox').each(function (index, checkbox) {
                if (checkbox.checked) {
                    searchString += (counter == 0) ? checkbox.value : '|' + checkbox.value;
                    counter++;
                }
            });
            $('#' + tableId).DataTable().column(i).search(
                searchString,
                true, false
            ).draw();
            rootNode.hide();
            $('#mask').hide();
        }

Conclusion

Currently, this does filtering upon group of columns with the records filtered from selected columns. We can easily extend it to support cascading filter (the column filters only contain the data filtered by other active filters if any).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)