Now.js Framework Documentation
FilterManager
FilterManager
Overview
FilterManager is the filtering and sorting management system in Now.js Framework. It supports filtering with multiple criteria and animated transitions.
When to use:
- Need to filter product lists, articles, galleries
- Need to sort by various fields
- Need filter UI with animations
- Need multi-criteria filtering
Why use it:
- ✅ Declarative HTML attributes
- ✅ Multiple filter criteria
- ✅ Sorting (string, number, date)
- ✅ Animated transitions (fade, slide, scale)
- ✅ Works with TemplateManager
- ✅ Debounced operations
- ✅ Auto-initialization
Basic Usage
Filter Controls
<!-- Filter buttons -->
<div data-filter-scope="#products" data-filter-attr="data-category">
<button data-filter-value="*" class="active">All</button>
<button data-filter-value="electronics">Electronics</button>
<button data-filter-value="clothing">Clothing</button>
<button data-filter-value="books">Books</button>
</div>
<!-- Filterable items -->
<div id="products" class="product-grid">
<div class="product" data-category="electronics">
<h3>iPhone 15</h3>
<p>$999</p>
</div>
<div class="product" data-category="clothing">
<h3>T-Shirt</h3>
<p>$25</p>
</div>
<div class="product" data-category="electronics">
<h3>MacBook</h3>
<p>$1,299</p>
</div>
<div class="product" data-category="books">
<h3>JavaScript Guide</h3>
<p>$35</p>
</div>
</div>Sort Controls
<!-- Sort buttons -->
<div data-sort-scope="#products">
<button data-sort-by="name" data-sort-type="string">Name</button>
<button data-sort-by="price" data-sort-type="number">Price</button>
<button data-sort-by="date" data-sort-type="date">Date</button>
</div>
<!-- Sortable items (must have data attributes for sorting) -->
<div id="products">
<div class="product" data-name="iphone" data-price="999" data-date="2024-01-15">
...
</div>
<div class="product" data-name="macbook" data-price="1299" data-date="2024-02-01">
...
</div>
</div>Filter Options
Animation Types
<!-- Fade animation (default) -->
<div data-filter-scope="#gallery"
data-filter-attr="data-type"
data-filter-animation="fade"
data-filter-duration="300">
<button data-filter-value="*">All</button>
<button data-filter-value="photo">Photos</button>
<button data-filter-value="video">Videos</button>
</div>
<!-- Slide animation -->
<div data-filter-scope="#list"
data-filter-animation="slide"
data-filter-duration="400">
...
</div>
<!-- Scale animation -->
<div data-filter-scope="#items"
data-filter-animation="scale"
data-filter-duration="250">
...
</div>
<!-- No animation -->
<div data-filter-scope="#items"
data-filter-animation="none">
...
</div>Custom Filter Attribute
<!-- Filter by status -->
<div data-filter-scope="#orders" data-filter-attr="data-status">
<button data-filter-value="*">All</button>
<button data-filter-value="pending">Pending</button>
<button data-filter-value="completed">Completed</button>
<button data-filter-value="cancelled">Cancelled</button>
</div>
<div id="orders">
<div class="order" data-status="pending">Order #001</div>
<div class="order" data-status="completed">Order #002</div>
</div>Sort Options
Sort Types
<!-- String sort (default) -->
<button data-sort-by="name" data-sort-type="string">Sort by Name</button>
<!-- Number sort -->
<button data-sort-by="price" data-sort-type="number">Sort by Price</button>
<!-- Date sort -->
<button data-sort-by="created" data-sort-type="date">Sort by Date</button>Sort Order
<!-- Ascending (default) -->
<button data-sort-by="price" data-sort-order="asc">Low to High</button>
<!-- Descending -->
<button data-sort-by="price" data-sort-order="desc">High to Low</button>Toggle Sort Order
Clicking the same sort button toggles between asc/desc:
// First click: sort asc
// Second click: sort desc
// Third click: sort ascJavaScript API
filter(value, scope, options)
Filter items programmatically:
// Filter items
FilterManager.filter('electronics', '#products', {
attr: 'data-category',
animation: 'fade',
duration: 300
});
// Show all
FilterManager.filter('*', '#products', {
attr: 'data-category'
});sort(options)
Sort items:
// Sort by price ascending
FilterManager.sort({
scope: '#products',
by: 'price',
order: 'asc',
type: 'number'
});
// Sort by name descending
FilterManager.sort({
scope: '#products',
by: 'name',
order: 'desc',
type: 'string'
});getFilteredItems(scope)
Get filtered items:
const visibleProducts = FilterManager.getFilteredItems('#products');
console.log(`Showing ${visibleProducts.length} products`);clearFilters(scope)
Clear all filters:
FilterManager.clearFilters('#products');getActiveFilter(scope)
Get active filter:
const filter = FilterManager.getActiveFilter('#products');
// { value: 'electronics', attr: 'data-category' }Configuration
// Default config
FilterManager.config = {
defaultAnimation: 'fade', // Default animation type
defaultDuration: 300, // Animation duration (ms)
defaultFilterAttr: 'data-category', // Default filter attribute
debounceDelay: 150, // Debounce delay (ms)
debug: false // Debug mode
};API Reference
FilterManager.filter(value, scope, options)
Filter items
| Parameter | Type | Description |
|---|---|---|
value |
string | Value to filter by (* = show all) |
scope |
string | CSS selector for container |
options.attr |
string | Attribute for filtering |
options.animation |
string | 'fade', 'slide', 'scale', 'none' |
options.duration |
number | Animation duration (ms) |
FilterManager.sort(options)
Sort items
| Parameter | Type | Description |
|---|---|---|
options.scope |
string | CSS selector for container |
options.by |
string | Field name for sorting |
options.order |
string | 'asc' or 'desc' |
options.type |
string | 'string', 'number', 'date' |
FilterManager.getFilteredItems(scope)
Get visible items
| Parameter | Type | Description |
|---|---|---|
scope |
string | CSS selector |
Returns: Array<HTMLElement> - Visible elements
FilterManager.clearFilters(scope)
Clear filters
| Parameter | Type | Description |
|---|---|---|
scope |
string | CSS selector |
FilterManager.clearSorts(scope)
Clear sorts
| Parameter | Type | Description |
|---|---|---|
scope |
string | CSS selector |
FilterManager.getActiveFilter(scope)
Get active filter
Returns: Object|undefined - {value, attr}
FilterManager.getActiveSort(scope)
Get active sort
Returns: Object|undefined - {by, order, type}
Real-World Examples
Product Gallery with Filter & Sort
<div class="gallery-controls">
<!-- Filters -->
<div data-filter-scope="#gallery" data-filter-attr="data-type">
<button data-filter-value="*" class="active">All</button>
<button data-filter-value="photo">Photos</button>
<button data-filter-value="video">Videos</button>
<button data-filter-value="document">Documents</button>
</div>
<!-- Sort -->
<div data-sort-scope="#gallery">
<button data-sort-by="name" data-sort-type="string">Name</button>
<button data-sort-by="size" data-sort-type="number">Size</button>
<button data-sort-by="date" data-sort-type="date">Date</button>
</div>
</div>
<div id="gallery" class="grid">
<div class="item" data-type="photo" data-name="sunset" data-size="2048" data-date="2024-01-15">
<img src="/photos/sunset.jpg" alt="Sunset">
<span>sunset.jpg (2 MB)</span>
</div>
<div class="item" data-type="video" data-name="tutorial" data-size="50000" data-date="2024-02-01">
<video src="/videos/tutorial.mp4"></video>
<span>tutorial.mp4 (50 MB)</span>
</div>
<div class="item" data-type="document" data-name="report" data-size="256" data-date="2024-01-20">
<img src="/icons/pdf.svg" alt="PDF">
<span>report.pdf (256 KB)</span>
</div>
</div>Dynamic Filtering from API
// Load data and filter
async function loadAndFilter(category) {
const products = await ApiService.get('/api/products');
// Render with TemplateManager
TemplateManager.render({ products }, document.querySelector('#product-list'));
// Apply filter after render
setTimeout(() => {
if (category !== 'all') {
FilterManager.filter(category, '#product-list', {
attr: 'data-category',
animation: 'fade'
});
}
}, 100);
}Common Pitfalls
⚠️ 1. Must Have data-filter-scope
<!-- ❌ Won't work - no scope -->
<div>
<button data-filter-value="electronics">Electronics</button>
</div>
<!-- ✅ Must have scope -->
<div data-filter-scope="#products" data-filter-attr="data-category">
<button data-filter-value="electronics">Electronics</button>
</div>⚠️ 2. Items Must Have Filter Attribute
<!-- ❌ Won't work - no data-category -->
<div id="products">
<div class="product">iPhone</div>
</div>
<!-- ✅ Must have attribute -->
<div id="products">
<div class="product" data-category="electronics">iPhone</div>
</div>⚠️ 3. Wait for Template Render
// ❌ Filter may not work if template hasn't rendered
TemplateManager.render(data, container);
FilterManager.filter('electronics', '#products', options);
// ✅ Wait for template render first
TemplateManager.render(data, container);
setTimeout(() => {
FilterManager.filter('electronics', '#products', options);
}, 100);
// ✅ Or use event listener
EventManager.on('template:render', () => {
FilterManager.filter('electronics', '#products', options);
});Related Documentation
- TemplateManager - Template rendering
- AnimationManager - Animations
- TableManager - Table filtering