Examples
<!-- HTML -->
<!--
For each button:
"data-filter-in" tells where to filter
"data-filter" tells what to filter
"data-filter-keycode" defines a keyboard shortcut (optional)
-->
<button data-filter-in="items" data-filter="all" class="selected_filter">All</button>
<button data-filter-in="items" data-filter="tech" data-filter-keycode="49">Technology</button>
<button data-filter-in="items" data-filter="phil" data-filter-keycode="50">Philosophy</button>
<!-- The collection of elements to filter -->
<ul data-collection="items">
<!-- Elements to filter have a data-filter attribute -->
<li data-filter="phil">Link</li>
<li data-filter="phil tech">Link</li>
<li data-filter="tech">Link</li>
<li data-filter="tech">Link</li>
<li data-filter="phil">Link</li>
</ul>
<!-- Include filtreur.js -->
<script type="text/javascript" src="filtreur.js"></script>
/* CSS */
.selected_filter{
/* styling for the selected filter button */
color: #fff;
background: #f65858;
}
.filtered_out{
/* styling for elements that do not match the filter */
display: none;
}
Example with select
<!-- HTML -->
<select>
<option data-filter-in="items" data-filter="all">All</option>
<option data-filter-in="items" data-filter="science">Science</option>
<option data-filter-in="items" data-filter="education">Education</option>
</select>
<ul data-collection="items">
<li data-filter="science">Link</li>
<li data-filter="education">Link</li>
<li data-filter="science">Link</li>
<li data-filter="science">Link</li>
<li data-filter="education">Link</li>
</ul>
<script type="text/javascript" src="filtreur.js"></script>
/* CSS */
.filtered_out{
display: none;
}
Usage
Include the JavaScript file in HTML:
<script type="text/javascript" src="filtreur.js"></script>
Filtreur.js starts automatically. The remainder of the setup is done with HTML and CSS.
Controls
A control is what the user selects to filter elements. A control can be any HTML element, but it is recommended to use a semantically relevant element such as button
or select
. Example:
<button data-filter-in="items" data-filter="1" data-filter-keycode="49">1</button>
-
data-filter-in
The name of the collection to filter.
-
data-filter
The filter to match against.
A value of "all" cancels filtering. -
data-filter-keycode
(optional)The keycode for a keyboard shortcut. Find keycodes at keycode.info.
The same keycode declared several times will only call the first control it’s declared on.
Collections
A collection contains the elements to filter. A collection can be any HTML container. Example:
<ul data-collection="items">
<li data-filter="2">2</li>
<li data-filter="1">1</li>
<li data-filter="1 2">1 and 2</li>
</ul>
-
data-collection
The name of the collection. Naming a collection allows to have multiple collections on one page, each targetted by different controls.
-
data-filter
Filters are user-defined data. The filtering operation is matched against this filter. Multiple filters should be space separated.
CSS
Filtreur shows the result of the filtering by applying CSS classes:
.selected_filter{
/* styling for the selected filters, applied to all corresponding controls */
}
.filtered_out{
/* styling for filtered out elements */
}
.filtered_in{
/* styling for filtered in elements */
}
Options
Filtreur does not require to write JavaScript code. However, some settings, API customization, and methods can be accessed with JavaScript.
Settings
Default settings can be modified inside filtreur.js or by making dedicated JavaScript calls:
//////////////////////////////////////////////////////////////////
//
// Default settings
//
//////////////////////////////////////////////////////////////////
// Default data-filter value to cancel filtering
filtreur.all = 'all';
// CSS class applied to elements which do not match a filter
filtreur.filtered_out = 'filtered_out';
// CSS class applied to elements which match a filter
filtreur.filtered_in = 'filtered_in';
// CSS class applied to all controls with the selected filter
filtreur.selected_filter = 'selected_filter';
// Calling the same filter twice in a row cancels filtering.
// Default is false. Set to true to enable
filtreur.toggle = false;
// Hitting Escape cancels filtering on the last filtered collection.
// Default is true. Set to false to disable
filtreur.escape = true;
API
The name of the dedicated data attributes can be customized by changing the values of the following variables inside filtreur.js:
//////////////////////////////////////////////////////////////////
//
// HTML API
//
//////////////////////////////////////////////////////////////////
// HTML5 conventions require data attributes to begin with "data-"
var data_attribute_filter = 'data-filter';
var data_attribute_filter_in = 'data-filter-in';
var data_attribute_collection = 'data-collection';
var data_attribute_keycode = 'data-filter-keycode';
Methods
Filtreur provides the following JavaScript methods:
// Filtering
// Takes a collection and a filter
filtreur.filter({
collection: 'items',
filter: '1'
});
// Unfiltering
// Filtering with filter: "all" is equivalent to unfiltering.
// The value "all" can be changed in settings
filtreur.filter({
collection: 'items',
filter: 'all'
});
// Execute a function after filtering
filtreur.callback_start = myFunction();
// Execute a function after unfiltering
filtreur.callback_end = myFunction();
// Tell the current selected filter
filtreur.current_filter;
// Tell the last filtered collection
filtreur.collection;
// Stop Filtreur from running
filtreur.stop();
// Start Filtreur. This method is automatically called by filtreur.js
filtreur.start();
Why Filtreur?
I have many web pages where the content is organized by tags, such as the Homepage, the Reading list, and the Blog. I wrote Filtreur to get a reusable component that could filter content on any web page.
I had the following requirements:
- Basic filtering: identify which elements match a given filter. Filters are arbitrary user-defined data.
- Visual result: hide/show elements according to filters. Generalize that by applying CSS classes to all filtered elements.
- Quick setup: implementing the filtering user interface should require as little work as possible. In the process of designing the best API possible, I settled on a declarative API.
- Declarative: the setup should be done within the flow of writing HTML. The setup should not require to switch context and move inside a script area in order to target DOM elements and initialize the logic. Multiple filtering interfaces as well as keyboard shortcuts should be declared in-place next to the data.
Compatibility
Supported browsers
- Google Chrome.
- Mozilla Firefox.
- Mobile Safari.
- Microsoft Edge.
- Internet Explorer 11.
Known issues
- Hitting Escape to unfilter a select box does not always select the "all" option.
License
Filtreur.js is published under the GNU General Public License.