Content
Filter grid
Filter, search and sort a grid of items: a portfolio, a product list, a directory.
Filter, search and sort
Nothing matchesTry another word or filter.
HTML
<div class="pw-filter" data-pw-filter>
<div class="pw-filter-bar">
<button class="pw-btn pw-btn--sm" data-filter="*">All</button>
<button class="pw-btn pw-btn--sm" data-filter="web">Web</button>
<button class="pw-btn pw-btn--sm" data-filter="brand">Brand</button>
<button class="pw-btn pw-btn--sm" data-filter="print">Print</button>
<input class="pw-input pw-input--sm" type="search" data-filter-search placeholder="Search" aria-label="Search projects">
<select class="pw-native-select pw-input--sm" data-filter-sort aria-label="Sort">
<option value="">Newest first</option>
<option value="title">Name</option>
<option value="-year">Year, new to old</option>
</select>
<span class="pw-filter-count" data-filter-count></span>
</div>
<div class="pw-filter-grid">
<article class="demo-tile" data-tags="web" data-title="Atlas" data-year="2026"><img src="assets/img/fjord.svg" alt=""><b>Atlas</b><span>Web, 2026</span></article>
<article class="demo-tile" data-tags="brand print" data-title="Juniper" data-year="2025"><img src="assets/img/forest.svg" alt=""><b>Juniper</b><span>Brand and print, 2025</span></article>
<article class="demo-tile" data-tags="web brand" data-title="Ember" data-year="2025"><img src="assets/img/dunes.svg" alt=""><b>Ember</b><span>Web and brand, 2025</span></article>
<article class="demo-tile" data-tags="print" data-title="Nocturne" data-year="2024"><img src="assets/img/dusk.svg" alt=""><b>Nocturne</b><span>Print, 2024</span></article>
<article class="demo-tile" data-tags="web" data-title="Mesa" data-year="2024"><img src="assets/img/mesa.svg" alt=""><b>Mesa</b><span>Web, 2024</span></article>
<article class="demo-tile" data-tags="brand" data-title="Tundra" data-year="2023"><img src="assets/img/tundra.svg" alt=""><b>Tundra</b><span>Brand, 2023</span></article>
</div>
<p class="pw-empty" data-filter-empty hidden><b>Nothing matches</b>Try another word or filter.</p>
</div>How to use it
Each item lists its tags in data-tags, separated by spaces. Sorting reads any data-… attribute you name in the sort select: the value title sorts by data-title, and -year sorts by data-year from high to low.
Options
Set them as attributes on the element.
| Attribute | Default | What it does |
|---|---|---|
data-multi | Several filter buttons can be on at once. | |
data-match | any | With data-multi: all shows only items that have every chosen tag. |
data-filter | On a button: the tag. * means all. | |
data-active | On a button: on at the start. | |
data-filter-search | On a search field. | |
data-filter-sort | On a select. | |
data-filter-count | On an element that shows “4 of 6”. | |
data-filter-empty | On an element that shows when nothing matches. | |
data-search | On an item: the text to search in. Without it, the text of the item. |
Events
Listen with addEventListener. Details are in event.detail.
| Event | When |
|---|---|
pw:change | With filters, query, shown and total. |
From your script
var f = Partwise.get(filterElement, 'filter');
f.set(['web']); f.search('atlas'); f.reset();
f.refresh(); // after you add or remove itemsGood to know
- The filter buttons are toggle buttons with
aria-pressed. The number of results is announced. - It filters the items that are in the page. For thousands of items, filter on the server instead.
Files
Everything is in dist/partwise.css and dist/partwise.js. To load only this component, use src/css/00-base.css and src/js/00-core.js plus: css/50-more.css, js/50-more.js.