Search code examples
javascriptjquerytablesorter

JQuery Tablesorter Add Column with Filters


I am using JQuery Tablesorter 2.7.* for a JavaScript table I have. I am also using the Tablesorter Filter widget, in order to have several of my columns have drop-down filtering options. I have a new challenge: I am required to add columns to the table dynamically. I have seen this question: Adding columns dynamically to a table managed with jQuery's tablesorter - which recommends that I remove and recreate the table with each addition/removal of a column. This is fair enough, however this causes a conflict with the Filter Widget.

In order to apply the Filter functions, the JavaScript references the column by index only, as so:

        widgetOptions: {
            filter_reset: '.reset',
            filter_functions: {
                2: true,
                3: true,
            }
        }

This code would cause columns with index 2 and 3 to have the default select Filter. The problem occurs when new columns are added dynamically - the index values of these columns are likely to change.

This brings my question; is there any way to apply widget options to columns named specifically by name? If not, is there some solution I can implement that would achieve the functionality where I can add/remove columns dynamically, without disturbing the filter functions?

Edit: I am also using filter functions.


Solution

  • Update #2: As of tablesorter v2.17.0 a class name* or ID can be used to target a column within the filter_functions option:

    // filter functions
    widgetOptions: {
        filter_functions : {
            ".exact" : function(e, n, f, i) {
                return e === f;
            }
        }
    }
    

    * Note: the class name can not include a selector that uses any kind of indexing, e.g. "th:eq()", ":gt()", ":lt()", ":first", ":last", ":even" or ":odd", ":first-child", ":last-child", ":nth-child()", ":nth-last-child()", etc.


    In the docs, it shows an alternative to using the filter_functions option:

    Alternately, instead of setting the column filter function to true, give the column header a class name of "filter-select". See the demo.

    So, just add a filter-select class name to the column instead.


    Update: Since other filter functions are being used, you can define these functions outside of the initialization code (demo)

    // Add these options to the select dropdown (date example) 
    // Note that only the normalized (n) value will contain
    // the date as a numerical value (.getTime())
    var dateFxns = {
    
        // Add these options to the select dropdown (date example) 
        // Note that only the normalized (n) value will contain
        // the date as a numerical value (.getTime())
        "< 2004": function (e, n, f, i) {
            return n < Date.UTC(2004, 0, 1); // < Jan 1 2004
        },
        "2004-2006": function (e, n, f, i) {
            return n >= Date.UTC(2004, 0, 1) && // Jan 1 2004
            n < Date.UTC(2007, 0, 1); // Jan 1 2007
        },
        "2006-2008": function (e, n, f, i) {
            return n >= Date.UTC(2006, 0, 1) && // Jan 1 2006
            n < Date.UTC(2009, 0, 1); // Jam 1 2009
        },
        "2008-2010": function (e, n, f, i) {
            return n >= Date.UTC(2008, 0, 1) && // Jan 1 2006
            n < Date.UTC(2011, 0, 1); // Jam 1 2009
        },
        "> 2010": function (e, n, f, i) {
            return n >= Date.UTC(2010, 0, 1); // Jan 1 2010
        }
    },
    currentDateColumn = 3,
    filterFxn = {};
    filterFxn[currentDateColumn] = dateFxns;
    
    $('table').tablesorter({
        widgets: ['zebra', 'filter'],
        widgetOptions: {
            filter_functions: filterFxn
        }
    });