Mottie/tablesorter

External select

Tedd22 opened this issue · 11 comments

Hi,

I'd like to use external select (dropdown list), like external input. The select should work exactly the same way select does inside the table. It should list all the values of the column.

Is it a way to do this ?

Thanks in advance !

Ted

Hi @Tedd22!

You can use the internal filter widget $.tablesorter.filter.getOptions(); function (ref) to obtain all of the values from a selected column. These values are not sorted and not reduced to only include unique entries, so you'll have to do that yourself.

// get an array of all table cell contents for a table column
var table = $('table')[0],
    column = 1,
    array = $.tablesorter.filter.getOptions(table, column);

// get unique elements and sort the list
arry = $.grep(arry, function(value, indx) {
    return $.inArray(value, arry) === indx;
}).sort();

Then you can apply that to your select and bind to it using the filter_external option.

Thanks for your instructions Mottie !

I have prepared the ground here http://jsfiddle.net/Ted22/LR3sX/58/ but I need your help to make it working...

Many thanks in advance Mottie, you're the king ! And in my country, Belgium, we know what it is ;-)

Ted

Hi Ted!

Sorry, I forgot there are two functions:

  • $.tablesorter.filter.getOptions(table, column); returns ALL raw column data from the table
  • $.tablesorter.filter.getOptionSource(table, column); returns unique & sorted column values based on the column parser (not documented).

I should probably rename those functions so they can better describe what they do.

Anyway, here is a working demo:

$(function () {

    var $t = $("#myTable").tablesorter({
        theme: 'blue',
        widgets: ['filter'],
        widgetOptions: {
            filter_columnFilters: false,
            filter_external: $('#select1')
        }
    });

    // get an array of all table cell contents for a table column
    var arry = $.tablesorter.filter.getOptionSource($t[0], 1);
    $('#select1').append('<option>' + arry.join('</option><option>') + '</option>');

});

Also note that I had to modify the external selector by adding a data-column attribute and adding an empty string value to the first option:

<select id="select1" data-column="1">
    <option value="">First Name</option>
</select>

It works like a charm, many thanks Mottie !

Now, I try to freeze the external selects with stickyheaders, but I don't know the right way.

See it here : http://jsfiddle.net/Ted22/LR3sX/62/

Thanks in advance !

Ted

Now it's getting a bit more complicated.

If you use the stickyHeaders widget, it only makes the table header & caption sticky. It doesn't work on an external div. Additionally, that widget needs to duplicate any bindings to the cloned table header, which is done automatically for built-in options.

If you don't plan on supporting older browsers (IE9+), the easiest solution would be to use the css3StickyHeaders widget and move the external selectors into the caption (demo):

HTML

<table id="myTable" class="tablesorter">
    <caption class="menubar">
        <select id="select1" data-column="0">
            <option value="">–Last Name–</option>
        </select>
        <select id="select2" data-column="1">
            <option value="">–First Name–</option>
        </select>
    </caption>
    <thead>
    <!-- ... -->
    </thead>
    <tbody>
    <!-- ... -->
    </tbody>
</table>

Script

$(function () {

  var $t = $("#myTable").tablesorter({
    theme: 'blue',
    widgets: ['filter', 'cssStickyHeaders'],
    widgetOptions: {
      filter_columnFilters: false,
      filter_external: $('#select1, #select2'),
      cssStickyHeaders_addCaption: true,
    }
  });

  function getSource(indx) {
    var arry = $.tablesorter.filter.getOptionSource($t[0], indx);
    return arry.map(function(obj) {
      return obj.text;
    });
  }

  // get an array of all table cell contents for a table column
  $('#select1').append('<option>' + getSource(0).join('</option><option>') + '</option>');

  // get an array of all table cell contents for a table column
  $('#select2').append('<option>' + getSource(1).join('</option><option>') + '</option>');

});

If that doesn't work for you, then maybe we can think of something different.

Updated (2018-07-20) because getOptionSource (undocumented function) is returning an object with text and parsed.

Thanks Mottie. I finally found a solution with css positionning properties.

See it here : http://jsfiddle.net/Ted22/LR3sX/65/

Not better than your solution but it works with old browsers.

Ted

I'm guessing this issue has been resolved, so I'm going to close it. If you continue to have problems, please feel free to continue this discussion.

Please see issue #702 & update to v2.17.7 if you are seeing this break in v2.17.6.

Hey @Mottie it looks like your fiddle is broken. It is pulling all of the items from the column as [Object object] which is a rather unhelpful datatype for sorting. Shouldn't be too bad of a fix.

The getOptionSource function isn't documented, so I forgot about this issue. I'll add documentation for it in the next update.