g3blv
g3blv

Reputation: 4377

Use tablesorter to filter selected items in options list chosen

I have table that is filtered with the help of Tablesorter. Each column have a search box on he top. In one of the columns I have an options list that is based on the Chosen JavaScript. I like to be able to filter this column based on what have been selected in the option list. I have tried using the textExtraction function triggering on the span tag that surrounds the selected item but I can't get it to work. Any suggestions are welcome.

I have a setup in this JSFiddle

<body>
<table class="tablesorter">
    <thead>
        <tr>
            <th class="title" data-placeholder="">Title</th>
            <th class="tags" data-placeholder="">Tags</th>
            <th class="date" data-placeholder="">Date</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Fish</td>
            <td>
                <select data-placeholder="Choose Tags" class="chosen-select" multiple>
                    <option value=""></option>
                    <option value="Option1">Sweden</option>
                    <option value="Option2">Norway</option>
                    <option value="Option3">Finland</option>
                </select>
            </td>
            <td>2012-12-03</td>
        </tr>
        <tr>
            <td>Boat</td>
            <td>
                <select data-placeholder="Choose Tags" class="chosen-select" multiple>
                    <option value=""></option>
                    <option value="Option1">Sweden</option>
                    <option value="Option2">Norway</option>
                    <option value="Option3">Finland</option>
                </select>
            </td>
            <td>2012-12-15</td>
        </tr>
    </tbody>
</table>

$(document).ready(function () {

$("table").tablesorter({
    theme: 'blue',
    textExtraction: {
        1: function (node, table, cellIndex) {
            return $(node).find("span").text();
        }
    },
    widthFixed: true,
    widgets: ["zebra", "filter"],
    widgetOptions: {
        filter_childRows: false,
        filter_columnFilters: true,
        filter_cssFilter: 'tablesorter-filter',
        filter_functions: null,
        filter_hideFilters: false,
        filter_ignoreCase: true,
        filter_reset: 'button.reset',
        filter_searchDelay: 300,
        filter_startsWith: false,
        filter_useParsedData: false

    }

});
});

Upvotes: 1

Views: 2634

Answers (1)

Mottie
Mottie

Reputation: 86433

Well there are just a few things missing to make it all work.

First, here is an updated demo.

To start, the value of the option should match the text, or you can modify the parser to instead find the selected options and get their text.

<select data-placeholder="Choose Tags" class="chosen-select" multiple>
    <option value=""></option>
    <option value="Sweden">Sweden</option>
    <option value="Norway">Norway</option>
    <option value="Finland">Finland</option>
</select>

Next, include a parser to get the selected options and also update the table cache:

$.tablesorter.addParser({
    id: "select",
    is: function () {
        return false;
    },
    format: function (s, table, cell) {
        // since the select can get multiple results in an array,
        // we combine all the values using join(',')
        return ($(cell).find('select').val() || []).join(',') || s;
    },
    type: "text"
});

// this flag prevents the updateCell event from being spammed
// it happens when you modify input text and hit enter
var alreadyUpdating = false;
$('table').find('tbody').on('change', 'select', function (e) {
    if (!alreadyUpdating) {
        var $tar = $(e.target),
            $table = $tar.closest('table');
        alreadyUpdating = true;
        $table.trigger('updateCell', [$tar.closest('td')]);
        setTimeout(function () {
            alreadyUpdating = false;
        }, 10);
    }
});

Now, make sure the header option is set (or add a "sorter-select" class to the th):

$("table").tablesorter({
    theme: 'blue',
    headers: {
        1: {
            sorter: 'select'
        }
    },
    // ....
 });

Lastly, set the header class name to only look for parsed data for that column (filter-parsed); the data-value was added to show that initial filters can also be set. This is also where the sorter-select class name could have been added instead of adding a headers option.

<th class="tags filter-parsed" data-value="sweden" data-placeholder="">Tags</th>

And all done!

Upvotes: 1

Related Questions