npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sv-filtable

v2.3.0

Published

A simple JavaScript library to filter HTML tables

Downloads

13

Readme

SV-Filtable

sv-filtable-js is a vanilla JavaScript library for filtering a table. Give it a set of input fields and it will automagically filter the table when the user interacts with those inputs, such as typing in a text field. Filtering can also be performed programatically if desired, and there are events that can be hooked into for custom behaviour. It's lightweight and fast!

Note: this library used to be a jQuery plugin - if you are looking for that, grab it from the v1.2 tag.

If you're looking for table sorting as well, check out SV-Sortable. Both libraries are independent but work nicely in tandem.

Installation

Filtable can be installed via npm:

npm install sv-filtable

Then use the file node_modules/sv-filtable/src/sv-filtable.js in your project - either directly in a <script> tag, or passing into your bundler/task runner.

Alternatively, you can download or link to a minified version via jsDelivr.

Auto-filter mode

The main mode of Filtable is automatic filtering of the table. Simply pass in the table element and wrapper containing input fields, and Filtable will bind events to those inputs and filter the table whenever text is typed or options selected. Here's a quick step-by-step guide:

  1. Start with a standard HTML data table:

    <table id="data">
    <thead>
    	<tr>
    		<th>First name</th>
    		<th>Last name</th>
    		<th>City</th>
    		<th>Country</th>
    	</tr>
    </thead>
    <tbody>
    	<tr>
    		<td>Homer</td>
    		<td>Simpson</td>
    		<td>Springfield</td>
    		<td>USA</td>
    	</tr>
    	<!-- ...and so on -->
    </tbody>
    </table>
  2. Add some basic CSS. Filtable adds a hidden class to unmatched rows, so the only required CSS is:

    tr.hidden {
    	display: none;
    }
  3. Add your filter, e.g. a basic text input. Here we put it in a wrapper div:

    <div id="table-filters">
    	<label for="filter-country">Country:</label>
    	<input type="text" id="filter-country" data-filter-col="3">
    </div>

    The data-filter-col attribute states which column will get filtered (zero-indexed). See below for all options.

  4. Include the Filtable script in your page's <head>. For performance reasons we are using the defer attribute:

    <script defer src="/path/to/sv-filtable.js"></script>
  5. Call SV.Filtable with HTMLElement objects for the table and form wrapper (such as those returned from document.querySelector), and any options (see below). As we are deferring script loading, we must run this after page load:

    <script>
    // Run on page load
    document.addEventListener('DOMContentLoaded', function() {
    	const table = document.querySelector('#data');
    	const controlPanel = document.querySelector('#table-filters');
    	new SV.Filtable(table, controlPanel, {zebraStriping: true});
    });
    </script>

Voila! Typing in the text box will now filter the table on the fourth column.

Supported filters & options

Filtable supports text inputs, select dropdowns, and checkboxes. Text inputs can be either <input type="text"> or <input type="search"> (the latter helpfully adds an X to clear the input).

For text inputs, the search value is taken from whatever is typed in the box, and a fuzzy search is used (i.e. 'a' matches all rows containing the letter a somewhere). For the others, the value is taken from the value attribute of the selected option or checkbox, and an exact match is used.

data-filter-col

For all inputs, the data-filter-col attribute can be used to specify which column(s) to filter. Columns are zero-indexed, i.e. the first column is 0 and the fourth is 3. Multiple columns can be specified by delimiting with commas e.g. 0,1 to match either of the first two columns. If the attribute is omitted, all columns are searched.

data-filter-type

Table cells may also specify the data-filter-value attribute, which is used to override the cell's text value when filtering. This is useful when cells contain non-textual content such as images. For example if our table contained a tick or cross depending on some attribute, we can set the attribute to Y or N accordingly, and use a checkbox with a value of Y:

<!-- in the filters -->
<label><input type="checkbox" id="filter-europe" value="Y" data-filter-col="4"> Europe</label>

<!-- in the table, an extra column with a tick for Europe -->
<tr>
	<td>Basil</td>
	<td>Brush</td>
	<td>London</td>
	<td>UK</td>
	<td data-filter-value="Y"><img src="tick.png"></td>
</tr>

data-filter-hash

Filtering can also use "hash URLs", which allows linking to a page with a pre-filled filter. A filter can be named using the data-filter-hash attribute on an input element, and whenever the table is filtered the URL will be changed to match. For example, if data-filter-hash="year" is specified on a <select> element and the year 2012 is selected, the URL will be updated to #year=2012.

It's recommended to only use select fields and checkboxes with this feature, as they have specific and limited values.

Constructor options

The third argument to the constructor is an options object, which can be used to override the default options. Possible options are:

zebraStriping

This option will add alternating odd and even classes to the remaining visible table rows (default: false). This avoids zebra-striping problems in CSS when using the nth-child selector - for example if rows 2 and 4 are filtered out, rows 1, 3 and 5 would normally end up with the same colour. Example usage:

new SV.Filtable(table, controlPanel, {zebraStriping: true});

You can start with odd/even classes on your table in the HTML, or even use nth-child in the CSS (for brevity) with odd/even overrides. Here's some example CSS, for a table with class data-table. The nth-child rule will be used on the default table set up, while the .odd and .even rules will be used when the table is filtered.

.data-table tr:nth-child(odd) > td {
	background-color: #ffffff;
}
.data-table tr:nth-child(even) > td {
	background-color: #f4f4f2;
}
.data-table tr.odd > td {
	background-color: #ffffff;
}
.data-table tr.even > td {
	background-color: #f4f4f2;
}

locale

This option sets the locale used for converting strings to lowercase for comparison. The default is English (en) which works for the vast majority of cases, but some languages such as Turkish have slightly different rules for conversion. Example usage:

new SV.Filtable(table, controlPanel, {locale: 'tr'});

Methods

The Filtable object contains some public methods, which can be used to manually apply filtering.

.applyFilters(filters)

The applyFilters method allows you to explicitly filter a table whenever you like. The automatic filtering should be fine in most cases (and it's easier), but this mode allows more control where necessary. An array of filters must be passed into the function - a filter is an object containing columns and value properties. The columns property must be an array, with the column numbers being zero-indexed. For example, this represents a search of the first column for the string "test":

[{ columns: [0], value: 'test' }]

While this combines two filters:

[
	{ columns: [0], value: 'foo' },
	{ columns: [1], value: 'bar' }
]

Here's the equivalent of the auto-filter from the previous section:

const table = document.querySelector('#data');
const filtable = new SV.Filtable(table);
document.querySelector('#filter-country').addEventListener('keyup', function () {
	let search = this.value;
	let filter = {columns: [3], value: search};
	filtable.applyFilters([filter]);
});

.buildFilters()

The buildFilters method returns an array of filters based on the current state of the filter elements. This is useful if you want to apply custom filters as above, but base them on the current state.

.restripeTable()

Filtable can automatically add zebra striping to the table (see above), however it only works during Filtable's own operations. The restripeTable method can be used if you changed the table rows externally in some way, for example using my other plugin, SV-Sortable. In this example we hook into an event from that plugin to reset the striping when a table is sorted:

const sortable = new SV.Sortable(table);
const filtable = new SV.Filtable(table, controlPanel, {zebraStriping: true});

table.addEventListener('sv.sortable.after', function() {
	filtable.restripeTable();
});

Events

Filtable supports two custom events: sv.filtable.before and sv.filtable.after, which are called respectively (can you guess?) before the table filtering begins and after filtering is finished. This allows you to, for example, display a message like "Processing..." while the filtering is occurring. The events are triggered on the table element itself.

The event object passed to sv.filtable.after contains a detail property which includes the properties visibleRows, the number of rows that matched the filter, and totalRows, the total number of rows in the table.

const table = document.querySelector('#data');
const controlPanel = document.querySelector('#table-filters');
const consoleMsg = document.querySelector('#console-msg');

table.addEventListener('sv.filtable.before', function() {
	consoleMsg.textContent = 'Filtering table...';
});
table.addEventListener('sv.filtable.after', function(ev) {
	consoleMsg.textContent = `Done filtering! Showing ${ev.detail.visibleRows} of ${ev.detail.totalRows} rows.`;
});

new SV.Filtable(table, controlPanel);