Now.js Framework Documentation
FilterManager
FilterManager
ภาพรวม
FilterManager คือระบบจัดการ filtering และ sorting ของ items ใน Now.js Framework รองรับการกรองด้วยหลายเกณฑ์ พร้อม animated transitions
ใช้เมื่อ:
- ต้องการกรองรายการสินค้า, บทความ, gallery
- ต้องการ sorting ตาม field ต่างๆ
- ต้องการ filter UI พร้อม animations
- ต้องการ multi-criteria filtering
ทำไมต้องใช้:
- ✅ Declarative HTML attributes
- ✅ Multiple filter criteria
- ✅ Sorting (string, number, date)
- ✅ Animated transitions (fade, slide, scale)
- ✅ Works with TemplateManager
- ✅ Debounced operations
- ✅ Auto-initialization
การใช้งานพื้นฐาน
Filter Controls
<!-- Filter buttons -->
<div data-filter-scope="#products" data-filter-attr="data-category">
<button data-filter-value="*" class="active">ทั้งหมด</button>
<button data-filter-value="electronics">อิเล็กทรอนิกส์</button>
<button data-filter-value="clothing">เสื้อผ้า</button>
<button data-filter-value="books">หนังสือ</button>
</div>
<!-- Filterable items -->
<div id="products" class="product-grid">
<div class="product" data-category="electronics">
<h3>iPhone 15</h3>
<p>฿35,000</p>
</div>
<div class="product" data-category="clothing">
<h3>T-Shirt</h3>
<p>฿500</p>
</div>
<div class="product" data-category="electronics">
<h3>MacBook</h3>
<p>฿55,000</p>
</div>
<div class="product" data-category="books">
<h3>JavaScript Guide</h3>
<p>฿450</p>
</div>
</div>Sort Controls
<!-- Sort buttons -->
<div data-sort-scope="#products">
<button data-sort-by="name" data-sort-type="string">ชื่อ</button>
<button data-sort-by="price" data-sort-type="number">ราคา</button>
<button data-sort-by="date" data-sort-type="date">วันที่</button>
</div>
<!-- Sortable items (ต้องมี data attributes สำหรับ sort) -->
<div id="products">
<div class="product" data-name="iphone" data-price="35000" data-date="2024-01-15">
...
</div>
<div class="product" data-name="macbook" data-price="55000" 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="*">ทั้งหมด</button>
<button data-filter-value="pending">รอดำเนินการ</button>
<button data-filter-value="completed">เสร็จสิ้น</button>
<button data-filter-value="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
เมื่อคลิกปุ่ม sort เดิมซ้ำ จะ toggle ระหว่าง asc/desc:
// คลิกครั้งแรก: เรียง asc
// คลิกครั้งสอง: เรียง desc
// คลิกครั้งสาม: เรียง ascJavaScript API
filter(value, scope, options)
กรอง items ด้วย JavaScript:
// Filter items
FilterManager.filter('electronics', '#products', {
attr: 'data-category',
animation: 'fade',
duration: 300
});
// Show all
FilterManager.filter('*', '#products', {
attr: 'data-category'
});sort(options)
เรียง 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)
รับ items ที่ถูกกรองแล้ว:
const visibleProducts = FilterManager.getFilteredItems('#products');
console.log(`Showing ${visibleProducts.length} products`);clearFilters(scope)
ล้าง filters ทั้งหมด:
FilterManager.clearFilters('#products');getActiveFilter(scope)
รับ filter ที่ active อยู่:
const filter = FilterManager.getActiveFilter('#products');
// { value: 'electronics', attr: 'data-category' }การตั้งค่า
// 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 อ้างอิง
FilterManager.filter(value, scope, options)
กรอง items
| Parameter | Type | Description |
|---|---|---|
value |
string | ค่าที่จะกรอง (* = แสดงทั้งหมด) |
scope |
string | CSS selector ของ container |
options.attr |
string | Attribute สำหรับกรอง |
options.animation |
string | 'fade', 'slide', 'scale', 'none' |
options.duration |
number | Animation duration (ms) |
FilterManager.sort(options)
เรียง items
| Parameter | Type | Description |
|---|---|---|
options.scope |
string | CSS selector ของ container |
options.by |
string | Field name สำหรับ sort |
options.order |
string | 'asc' หรือ 'desc' |
options.type |
string | 'string', 'number', 'date' |
FilterManager.getFilteredItems(scope)
รับ visible items
| Parameter | Type | Description |
|---|---|---|
scope |
string | CSS selector |
Returns: Array<HTMLElement> - Visible elements
FilterManager.clearFilters(scope)
ล้าง filters
| Parameter | Type | Description |
|---|---|---|
scope |
string | CSS selector |
FilterManager.clearSorts(scope)
ล้าง sorts
| Parameter | Type | Description |
|---|---|---|
scope |
string | CSS selector |
FilterManager.getActiveFilter(scope)
รับ active filter
Returns: Object|undefined - {value, attr}
FilterManager.getActiveSort(scope)
รับ active sort
Returns: Object|undefined - {by, order, type}
ตัวอย่างการใช้งานจริง
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">ทั้งหมด</button>
<button data-filter-value="photo">รูปภาพ</button>
<button data-filter-value="video">วิดีโอ</button>
<button data-filter-value="document">เอกสาร</button>
</div>
<!-- Sort -->
<div data-sort-scope="#gallery">
<button data-sort-by="name" data-sort-type="string">ชื่อ</button>
<button data-sort-by="size" data-sort-type="number">ขนาด</button>
<button data-sort-by="date" data-sort-type="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);
}ข้อควรระวัง
⚠️ 1. ต้องมี data-filter-scope
<!-- ❌ ไม่ work - ไม่มี scope -->
<div>
<button data-filter-value="electronics">Electronics</button>
</div>
<!-- ✅ ต้องมี scope -->
<div data-filter-scope="#products" data-filter-attr="data-category">
<button data-filter-value="electronics">Electronics</button>
</div>⚠️ 2. Items ต้องมี filter attribute
<!-- ❌ ไม่ work - ไม่มี data-category -->
<div id="products">
<div class="product">iPhone</div>
</div>
<!-- ✅ ต้องมี attribute -->
<div id="products">
<div class="product" data-category="electronics">iPhone</div>
</div>⚠️ 3. Wait for Template Render
// ❌ Filter อาจไม่ work ถ้า template ยังไม่ render
TemplateManager.render(data, container);
FilterManager.filter('electronics', '#products', options);
// ✅ รอ template render ก่อน
TemplateManager.render(data, container);
setTimeout(() => {
FilterManager.filter('electronics', '#products', options);
}, 100);
// ✅ หรือใช้ event listener
EventManager.on('template:render', () => {
FilterManager.filter('electronics', '#products', options);
});เอกสารที่เกี่ยวข้อง
- TemplateManager - Template rendering
- AnimationManager - Animations
- TableManager - Table filtering