Search code examples
htmltablesorter

tablesorter select box with a custom match function


I have an HTML table with a column, in which an unordered list of strings is present. I am using tablesorter with the filter plugin to interact with the list. I want each string in all cells of the column to be present in a select filter in the header of the table. If the user selects an option, those rows should be displayed, where this string appears in the unordered list of the particular column cell.

Let me give you an example. I have the following list:

<table>
    <thead>
        <tr>
            <th>name</th>
            <th>profession</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Carl</td>
            <td>
                <ul>
                    <li>Builder</li>
                    <li>Professor</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td>Lisa</td>
            <td>
                <ul>
                    <li>Programmer</li>
                    <li>Professor</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

In the table header, I want tablesorter to display a select box with the three professions. If, say, professor is selected, both rows should be shown. If programmer is selected, only Lisa would appear. How would I reach that?


Solution

  • Use the filter_functions widget option as follows (demo):

    $(function () {
    
        $('table').tablesorter({
            theme: 'blue',
            widgets: ['filter'],
            widgetOptions: {
                filter_functions: {
                    1: {
                        "Programmer": function (e, n) { return /programmer/.test(n); },
                        "Professor" : function (e, n) { return /professor/.test(n); },
                        "Builder"   : function (e, n) { return /builder/.test(n); } 
                    }
                }
            }
        });
    
    });
    

    Update: If you don't want to hardcode because the professions vary, then you can use the filter_selectSource option to grab all of the column text, extract out each item from the list then return it as an array (demo):

    HTML (make sure to include these class names)

    <th class="filter-select filter-match">profession</th>
    

    Script

    $(function () {
    
        $('table').tablesorter({
            theme: 'blue',
            widgets: ['filter'],
            widgetOptions: {
                filter_selectSource: function (table, column, onlyAvail) {
                    // get an array of all table cell contents for a table column
                    var arry = [],
                        array = $.tablesorter.filter.getOptions(table, column, onlyAvail);
                    // split content if multiple professions are encountered
                    $.each( array, function(i, n){
                        // look for carriage returns; split into two separate professions
                        if (/\n/.test(n)) {
                            n = n.split(/\n/);
                        }
                        arry.push(n);
                    });
                    // flatten array
                    return $.map(arry, function(n){ return n; });
                }
            }
        });
    
    });