advanced-filter-system 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +421 -300
- package/dist/afs.legacy.js +1 -1
- package/dist/afs.legacy.js.map +1 -1
- package/dist/afs.modern.js +1 -1
- package/dist/afs.modern.js.map +1 -1
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A powerful and flexible vanilla JavaScript filtering system that provides advanced filtering, searching, sorting, and pagination capabilities for DOM elements. Zero dependencies, lightweight, and highly customizable.
|
|
4
4
|
|
|
5
|
-
[Live Demo](https://misits.github.io/advanced-filter-system) | [NPM Package](https://www.npmjs.com/package/advanced-filter-system)
|
|
5
|
+
[Live Demo](https://misits.github.io/advanced-filter-system) | [NPM Package](https://www.npmjs.com/package/advanced-filter-system) | [Interactive Examples](examples/demo.html)
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
@@ -13,28 +13,26 @@ A powerful and flexible vanilla JavaScript filtering system that provides advanc
|
|
|
13
13
|
- [Quick Start](#quick-start)
|
|
14
14
|
- [HTML Structure](#html-structure)
|
|
15
15
|
- [JavaScript Initialization](#javascript-initialization)
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
16
|
+
- [Filter Logic Modes](#filter-logic-modes)
|
|
17
|
+
- [Mixed Mode (Recommended)](#mixed-mode-recommended)
|
|
18
|
+
- [Per-Type Logic Configuration](#per-type-logic-configuration)
|
|
19
|
+
- [Legacy Modes](#legacy-modes)
|
|
20
|
+
- [Filter Types & UI Components](#filter-types--ui-components)
|
|
21
|
+
- [Button Filters](#button-filters)
|
|
22
|
+
- [Select Dropdowns](#select-dropdowns)
|
|
23
|
+
- [Radio Buttons](#radio-buttons)
|
|
24
|
+
- [Checkboxes](#checkboxes)
|
|
25
|
+
- [Range Sliders](#range-sliders)
|
|
26
|
+
- [Date Range Filters](#date-range-filters)
|
|
27
|
+
- [Advanced Features](#advanced-features)
|
|
28
|
+
- [Search & Filtering](#search--filtering)
|
|
19
29
|
- [Sorting](#sorting)
|
|
20
30
|
- [Pagination](#pagination)
|
|
21
|
-
- [Advanced Usage](#advanced-usage)
|
|
22
|
-
- [Filter Groups](#filter-groups)
|
|
23
|
-
- [Custom Sorting](#custom-sorting)
|
|
24
31
|
- [URL State Management](#url-state-management)
|
|
25
|
-
- [Components](#components)
|
|
26
|
-
- [Filter System](#filter-system)
|
|
27
|
-
- [Range Filter](#range-filter)
|
|
28
|
-
- [Input Range Filter](#input-range-filter)
|
|
29
|
-
- [Date Filter](#date-filter)
|
|
30
|
-
- [Search System](#search-system)
|
|
31
|
-
- [Sort System](#sort-system)
|
|
32
|
-
- [Pagination System](#pagination-system)
|
|
33
|
-
- [URL Manager](#url-manager)
|
|
34
|
-
- [Styling \& Theming](#styling--theming)
|
|
35
|
-
- [Built-in Themes](#built-in-themes)
|
|
36
|
-
- [Custom Themes](#custom-themes)
|
|
37
32
|
- [Animations](#animations)
|
|
33
|
+
- [Configuration Options](#configuration-options)
|
|
34
|
+
- [API Reference](#api-reference)
|
|
35
|
+
- [Examples](#examples)
|
|
38
36
|
- [Browser Support](#browser-support)
|
|
39
37
|
- [TypeScript Support](#typescript-support)
|
|
40
38
|
- [Contributing](#contributing)
|
|
@@ -42,45 +40,50 @@ A powerful and flexible vanilla JavaScript filtering system that provides advanc
|
|
|
42
40
|
|
|
43
41
|
## Features
|
|
44
42
|
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
|
|
43
|
+
- 🎯 **Advanced Filter Logic**
|
|
44
|
+
- Mixed mode (OR within categories, AND between)
|
|
45
|
+
- Per-type logic configuration
|
|
46
|
+
- Multi-select and toggle modes
|
|
47
|
+
- Category-specific clearing
|
|
48
|
+
- 🔍 **Multiple Filter Types**
|
|
49
|
+
- Button filters (toggle/multi-select)
|
|
50
|
+
- Select dropdowns
|
|
51
|
+
- Radio buttons (exclusive)
|
|
52
|
+
- Checkboxes (multi-select)
|
|
53
|
+
- Range sliders with histograms
|
|
54
|
+
- Date range filters
|
|
51
55
|
- 🔎 **Smart Search**
|
|
52
|
-
- Real-time search
|
|
53
|
-
- Multiple fields
|
|
54
|
-
-
|
|
56
|
+
- Real-time fuzzy search
|
|
57
|
+
- Multiple searchable fields
|
|
58
|
+
- Configurable debouncing
|
|
55
59
|
- Minimum character threshold
|
|
56
60
|
- ↕️ **Flexible Sorting**
|
|
57
|
-
- Multi-column
|
|
58
|
-
- Custom
|
|
61
|
+
- Multi-column sorting
|
|
62
|
+
- Custom sort functions
|
|
59
63
|
- Auto-detect data types
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
64
|
+
- Sort direction indicators
|
|
65
|
+
- 📄 **Advanced Pagination**
|
|
66
|
+
- Dynamic page sizes
|
|
67
|
+
- Smooth transitions
|
|
68
|
+
- Scroll-to-top option
|
|
69
|
+
- Custom pagination controls
|
|
70
|
+
- 🎨 **Rich Animations**
|
|
71
|
+
- 14+ animation types (fade, slide, scale, flip, etc.)
|
|
72
|
+
- Hardware-accelerated transitions
|
|
73
|
+
- Customizable duration and easing
|
|
74
|
+
- 🔗 **State Management**
|
|
75
|
+
- URL state persistence
|
|
66
76
|
- Browser history support
|
|
67
|
-
- Shareable URLs
|
|
68
|
-
-
|
|
77
|
+
- Shareable filtered URLs
|
|
78
|
+
- State import/export
|
|
79
|
+
- ⚡ **Performance Optimized**
|
|
69
80
|
- Debounced updates
|
|
70
81
|
- Efficient DOM manipulation
|
|
71
|
-
- Minimal reflows
|
|
72
|
-
- 🎨 **Rich Animation**
|
|
73
|
-
- Smooth transitions
|
|
74
|
-
- Custom animations
|
|
75
|
-
- Hardware acceleration
|
|
76
|
-
- 💾 **State Management**
|
|
77
|
-
- Centralized state
|
|
78
|
-
- Import/Export
|
|
79
|
-
- Undo/Redo support
|
|
82
|
+
- Minimal reflows and repaints
|
|
80
83
|
- 🎯 **Event System**
|
|
81
|
-
-
|
|
82
|
-
- Custom
|
|
83
|
-
-
|
|
84
|
+
- Comprehensive event API
|
|
85
|
+
- Custom event support
|
|
86
|
+
- Debug mode with logging
|
|
84
87
|
|
|
85
88
|
## Installation
|
|
86
89
|
|
|
@@ -114,207 +117,236 @@ Or include via CDN:
|
|
|
114
117
|
<title>AFS Demo</title>
|
|
115
118
|
</head>
|
|
116
119
|
<body>
|
|
117
|
-
<!--
|
|
118
|
-
<div class="
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
<!-- Filter Buttons -->
|
|
124
|
-
<div class="filter-buttons">
|
|
125
|
-
<button class="afs-btn-filter" data-filter="*">All</button>
|
|
126
|
-
<button class="afs-btn-filter" data-filter="category:category1">Category 1</button>
|
|
127
|
-
<button class="afs-btn-filter" data-filter="category:category2">Category 2</button>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
<!-- Sort Buttons -->
|
|
131
|
-
<div class="afs-sort-buttons">
|
|
132
|
-
<button class="afs-btn-sort" data-sort-key="price">
|
|
133
|
-
Price <span class="sort-direction">↑</span>
|
|
134
|
-
</button>
|
|
135
|
-
<button class="afs-btn-sort" data-sort-key="date">
|
|
136
|
-
Date <span class="sort-direction">↑</span>
|
|
137
|
-
</button>
|
|
120
|
+
<!-- Filter Controls -->
|
|
121
|
+
<div class="filter-controls">
|
|
122
|
+
<button class="btn-filter" data-filter="*">All</button>
|
|
123
|
+
<button class="btn-filter" data-filter="category:tech">Technology</button>
|
|
124
|
+
<button class="btn-filter" data-filter="category:design">Design</button>
|
|
138
125
|
</div>
|
|
139
|
-
|
|
140
|
-
<!--
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
<!--
|
|
144
|
-
<div
|
|
145
|
-
|
|
146
|
-
<!-- Items
|
|
147
|
-
<div
|
|
148
|
-
<div class="
|
|
149
|
-
data-categories="category:
|
|
150
|
-
data-
|
|
151
|
-
data-
|
|
152
|
-
data-
|
|
153
|
-
|
|
154
|
-
<
|
|
155
|
-
<p>$99.99</p>
|
|
156
|
-
<p>March 15, 2024</p>
|
|
126
|
+
|
|
127
|
+
<!-- Search Input -->
|
|
128
|
+
<input type="text" class="filter-search" placeholder="Search...">
|
|
129
|
+
|
|
130
|
+
<!-- Results Counter -->
|
|
131
|
+
<div class="filter-counter"></div>
|
|
132
|
+
|
|
133
|
+
<!-- Filterable Items -->
|
|
134
|
+
<div class="items-container">
|
|
135
|
+
<div class="filter-item"
|
|
136
|
+
data-categories="category:tech brand:apple"
|
|
137
|
+
data-title="MacBook Pro"
|
|
138
|
+
data-price="2499"
|
|
139
|
+
data-date="2024-03-15">
|
|
140
|
+
<h3>MacBook Pro</h3>
|
|
141
|
+
<p>$2,499</p>
|
|
157
142
|
</div>
|
|
158
143
|
<!-- More items... -->
|
|
159
144
|
</div>
|
|
160
|
-
|
|
161
|
-
<!-- Pagination -->
|
|
162
|
-
<div class="pagination-container"></div>
|
|
163
|
-
|
|
164
|
-
<!-- Scripts -->
|
|
165
|
-
<script type="module">
|
|
166
|
-
import { AFS } from 'https://unpkg.com/advanced-filter-system@latest/dist/afs.modern.js';
|
|
167
|
-
|
|
168
|
-
const afs = new AFS({
|
|
169
|
-
containerSelector: '#items-container',
|
|
170
|
-
itemSelector: '.afs-filter-item',
|
|
171
|
-
searchInputSelector: '.afs-filter-search',
|
|
172
|
-
filterButtonSelector: '.afs-btn-filter',
|
|
173
|
-
sortButtonSelector: '.afs-btn-sort',
|
|
174
|
-
counterSelector: '.afs-filter-counter',
|
|
175
|
-
debug: true,
|
|
176
|
-
responsive: true,
|
|
177
|
-
preserveState: true,
|
|
178
|
-
animation: {
|
|
179
|
-
type: 'fade',
|
|
180
|
-
duration: 300
|
|
181
|
-
},
|
|
182
|
-
pagination: {
|
|
183
|
-
enabled: true,
|
|
184
|
-
itemsPerPage: 10
|
|
185
|
-
},
|
|
186
|
-
styles: {
|
|
187
|
-
button: {
|
|
188
|
-
padding: "12px 24px",
|
|
189
|
-
border: "2px solid #ccc",
|
|
190
|
-
borderRadius: "8px",
|
|
191
|
-
fontSize: "16px",
|
|
192
|
-
fontFamily: "Arial, sans-serif",
|
|
193
|
-
fontWeight: "bold",
|
|
194
|
-
letterSpacing: "0.5px",
|
|
195
|
-
textTransform: "uppercase",
|
|
196
|
-
minHeight: "48px",
|
|
197
|
-
lineHeight: "1.8",
|
|
198
|
-
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
|
|
199
|
-
hover: {
|
|
200
|
-
boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
|
|
201
|
-
},
|
|
202
|
-
active: {
|
|
203
|
-
boxShadow: "0 1px 2px rgba(0,0,0,0.1)"
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
dropdown: {
|
|
207
|
-
// Same properties as button
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
// Add range filter
|
|
213
|
-
afs.rangeFilter.addRangeSlider({
|
|
214
|
-
key: 'price',
|
|
215
|
-
container: document.querySelector('#price-range'),
|
|
216
|
-
min: 0,
|
|
217
|
-
max: 1000,
|
|
218
|
-
step: 10
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// Add date filter
|
|
222
|
-
afs.dateFilter.addDateRange({
|
|
223
|
-
key: 'date',
|
|
224
|
-
container: document.querySelector('#date-filter')
|
|
225
|
-
});
|
|
226
|
-
</script>
|
|
145
|
+
|
|
146
|
+
<!-- Pagination Container -->
|
|
147
|
+
<div class="afs-pagination-container"></div>
|
|
227
148
|
</body>
|
|
228
149
|
</html>
|
|
229
150
|
```
|
|
230
151
|
|
|
231
152
|
### JavaScript Initialization
|
|
232
153
|
|
|
233
|
-
Using ES modules:
|
|
234
|
-
|
|
235
154
|
```javascript
|
|
236
155
|
import { AFS } from 'advanced-filter-system';
|
|
237
156
|
|
|
238
157
|
const afs = new AFS({
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
158
|
+
// Required selectors
|
|
159
|
+
containerSelector: '.items-container',
|
|
160
|
+
itemSelector: '.filter-item',
|
|
161
|
+
filterButtonSelector: '.btn-filter',
|
|
162
|
+
searchInputSelector: '.filter-search',
|
|
163
|
+
counterSelector: '.filter-counter',
|
|
164
|
+
|
|
165
|
+
// Search configuration
|
|
166
|
+
searchKeys: ['title', 'categories'],
|
|
167
|
+
|
|
168
|
+
// NEW: Advanced filter logic
|
|
169
|
+
filterCategoryMode: 'mixed', // OR within categories, AND between
|
|
170
|
+
filterTypeLogic: {
|
|
171
|
+
category: { mode: 'OR', multi: true }, // Multi-select OR
|
|
172
|
+
brand: 'OR', // Toggle mode
|
|
173
|
+
price: 'AND' // Multi-select AND
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
// Pagination
|
|
177
|
+
pagination: {
|
|
178
|
+
enabled: true,
|
|
179
|
+
itemsPerPage: 12
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
// Animations
|
|
242
183
|
animation: {
|
|
243
184
|
type: 'fade',
|
|
244
185
|
duration: 300
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
// Debug mode
|
|
189
|
+
debug: true
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Filter Logic Modes
|
|
194
|
+
|
|
195
|
+
### Mixed Mode (Recommended)
|
|
196
|
+
|
|
197
|
+
The most intuitive filtering experience - OR logic within filter categories, AND logic between different categories.
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
const afs = new AFS({
|
|
201
|
+
filterCategoryMode: 'mixed',
|
|
202
|
+
// When user selects: Tech OR Design AND Apple OR Samsung
|
|
203
|
+
// Shows: (Tech OR Design) AND (Apple OR Samsung)
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Per-Type Logic Configuration
|
|
208
|
+
|
|
209
|
+
Configure each filter type independently for maximum flexibility.
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
const afs = new AFS({
|
|
213
|
+
filterCategoryMode: 'mixed',
|
|
214
|
+
filterTypeLogic: {
|
|
215
|
+
category: { mode: 'OR', multi: true }, // Multi-select checkboxes
|
|
216
|
+
brand: 'OR', // Toggle buttons (exclusive)
|
|
217
|
+
price: 'AND', // Multi-select with AND logic
|
|
218
|
+
features: { mode: 'OR', multi: true } // Multi-select with OR logic
|
|
245
219
|
}
|
|
246
220
|
});
|
|
221
|
+
|
|
222
|
+
// Update logic at runtime
|
|
223
|
+
afs.filter.setFilterTypeLogic('brand', { mode: 'OR', multi: true });
|
|
247
224
|
```
|
|
248
225
|
|
|
249
|
-
|
|
226
|
+
### Legacy Modes
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
// Legacy OR mode (all filters use OR logic)
|
|
230
|
+
const afs = new AFS({ filterCategoryMode: 'OR' });
|
|
231
|
+
|
|
232
|
+
// Legacy AND mode (all filters use AND logic)
|
|
233
|
+
const afs = new AFS({ filterCategoryMode: 'AND' });
|
|
234
|
+
```
|
|
250
235
|
|
|
251
|
-
|
|
236
|
+
## Filter Types & UI Components
|
|
252
237
|
|
|
253
|
-
|
|
238
|
+
### Button Filters
|
|
254
239
|
|
|
255
240
|
```html
|
|
256
|
-
<!--
|
|
257
|
-
<
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
</
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
241
|
+
<!-- Toggle mode (exclusive) -->
|
|
242
|
+
<button class="btn-filter" data-filter="category:tech">Technology</button>
|
|
243
|
+
|
|
244
|
+
<!-- Multi-select mode -->
|
|
245
|
+
<button class="btn-filter" data-filter="brand:apple">Apple</button>
|
|
246
|
+
<button class="btn-filter" data-filter="brand:samsung">Samsung</button>
|
|
247
|
+
|
|
248
|
+
<!-- Clear specific category -->
|
|
249
|
+
<button class="btn-filter" data-filter="category:*">Clear Categories</button>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Select Dropdowns
|
|
253
|
+
|
|
254
|
+
```html
|
|
255
|
+
<select class="afs-filter-dropdown">
|
|
256
|
+
<option value="*">All Categories</option>
|
|
257
|
+
<option value="category:tech">Technology</option>
|
|
258
|
+
<option value="category:design">Design</option>
|
|
259
|
+
</select>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Radio Buttons
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<label><input type="radio" name="category" class="btn-filter" data-filter="*" checked> All</label>
|
|
266
|
+
<label><input type="radio" name="category" class="btn-filter" data-filter="category:tech"> Tech</label>
|
|
267
|
+
<label><input type="radio" name="category" class="btn-filter" data-filter="category:design"> Design</label>
|
|
270
268
|
```
|
|
271
269
|
|
|
272
|
-
|
|
270
|
+
### Checkboxes
|
|
271
|
+
|
|
272
|
+
```html
|
|
273
|
+
<label><input type="checkbox" class="btn-filter" data-filter="category:tech"> Technology</label>
|
|
274
|
+
<label><input type="checkbox" class="btn-filter" data-filter="category:design"> Design</label>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Range Sliders
|
|
273
278
|
|
|
274
279
|
```javascript
|
|
275
|
-
//
|
|
276
|
-
afs.
|
|
280
|
+
// Add price range slider with histogram
|
|
281
|
+
afs.rangeFilter.addRangeSlider({
|
|
282
|
+
key: 'price',
|
|
283
|
+
type: 'number',
|
|
284
|
+
container: '.price-range-container',
|
|
285
|
+
min: 0,
|
|
286
|
+
max: 3000,
|
|
287
|
+
step: 50,
|
|
288
|
+
ui: {
|
|
289
|
+
showHistogram: true,
|
|
290
|
+
bins: 10
|
|
291
|
+
}
|
|
292
|
+
});
|
|
277
293
|
|
|
278
|
-
// Add
|
|
279
|
-
afs.
|
|
294
|
+
// Add rating range slider
|
|
295
|
+
afs.rangeFilter.addRangeSlider({
|
|
296
|
+
key: 'rating',
|
|
297
|
+
type: 'number',
|
|
298
|
+
container: '.rating-range-container',
|
|
299
|
+
min: 4.0,
|
|
300
|
+
max: 5.0,
|
|
301
|
+
step: 0.1
|
|
302
|
+
});
|
|
303
|
+
```
|
|
280
304
|
|
|
281
|
-
|
|
282
|
-
afs.filter.removeFilter('category1');
|
|
305
|
+
### Date Range Filters
|
|
283
306
|
|
|
284
|
-
|
|
285
|
-
|
|
307
|
+
```javascript
|
|
308
|
+
// Add date range filter
|
|
309
|
+
afs.dateFilter.addDateRange({
|
|
310
|
+
key: 'date',
|
|
311
|
+
container: '.date-range-container',
|
|
312
|
+
minDate: new Date('2024-01-01'),
|
|
313
|
+
maxDate: new Date(),
|
|
314
|
+
format: 'YYYY-MM-DD'
|
|
315
|
+
});
|
|
286
316
|
```
|
|
287
317
|
|
|
288
|
-
|
|
318
|
+
## Advanced Features
|
|
319
|
+
|
|
320
|
+
### Search & Filtering
|
|
289
321
|
|
|
290
322
|
```javascript
|
|
291
323
|
// Configure search
|
|
292
324
|
afs.search.configure({
|
|
293
|
-
keys: ['title', 'description'],
|
|
325
|
+
keys: ['title', 'description', 'categories'],
|
|
326
|
+
fuzzy: true,
|
|
294
327
|
minLength: 2,
|
|
295
328
|
debounce: 300
|
|
296
329
|
});
|
|
297
330
|
|
|
298
|
-
//
|
|
299
|
-
afs.
|
|
331
|
+
// Programmatic filtering
|
|
332
|
+
afs.filter.addFilter('category:tech');
|
|
333
|
+
afs.filter.removeFilter('category:tech');
|
|
334
|
+
afs.filter.clearAllFilters();
|
|
300
335
|
```
|
|
301
336
|
|
|
302
337
|
### Sorting
|
|
303
338
|
|
|
304
339
|
```javascript
|
|
305
|
-
//
|
|
306
|
-
afs.
|
|
340
|
+
// Sort by single field
|
|
341
|
+
afs.filter.sortWithOrder('price', 'DESC');
|
|
307
342
|
|
|
308
|
-
//
|
|
309
|
-
afs.sort.sortMultiple([
|
|
310
|
-
{ key: 'category', direction: 'asc' },
|
|
311
|
-
{ key: 'price', direction: 'desc' }
|
|
312
|
-
]);
|
|
313
|
-
|
|
314
|
-
// Custom sort
|
|
343
|
+
// Custom sorting
|
|
315
344
|
afs.sort.sortWithComparator('title', (a, b) => {
|
|
316
|
-
return a.localeCompare(b);
|
|
345
|
+
return a.localeCompare(b, 'en', { numeric: true });
|
|
317
346
|
});
|
|
347
|
+
|
|
348
|
+
// Shuffle items
|
|
349
|
+
afs.filter.shuffle();
|
|
318
350
|
```
|
|
319
351
|
|
|
320
352
|
### Pagination
|
|
@@ -322,129 +354,183 @@ afs.sort.sortWithComparator('title', (a, b) => {
|
|
|
322
354
|
```javascript
|
|
323
355
|
// Configure pagination
|
|
324
356
|
afs.pagination.configure({
|
|
325
|
-
itemsPerPage:
|
|
326
|
-
showControls: true
|
|
357
|
+
itemsPerPage: 12,
|
|
358
|
+
showControls: true,
|
|
359
|
+
scrollToTop: true,
|
|
360
|
+
scrollBehavior: 'smooth'
|
|
327
361
|
});
|
|
328
362
|
|
|
329
|
-
//
|
|
330
|
-
afs.pagination.
|
|
331
|
-
afs.pagination.
|
|
332
|
-
afs.pagination.previousPage();
|
|
363
|
+
// Toggle pagination mode
|
|
364
|
+
afs.pagination.setPaginationMode(true); // Enable
|
|
365
|
+
afs.pagination.setPaginationMode(false); // Show all
|
|
333
366
|
```
|
|
334
367
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
### Filter Groups
|
|
368
|
+
### URL State Management
|
|
338
369
|
|
|
339
370
|
```javascript
|
|
340
|
-
//
|
|
341
|
-
afs
|
|
342
|
-
|
|
343
|
-
|
|
371
|
+
// Enable URL state persistence
|
|
372
|
+
const afs = new AFS({
|
|
373
|
+
preserveState: true,
|
|
374
|
+
urlStateKey: 'filters' // Custom URL parameter name
|
|
344
375
|
});
|
|
345
376
|
|
|
346
|
-
//
|
|
347
|
-
afs.
|
|
377
|
+
// Manual state management
|
|
378
|
+
const state = afs.getState();
|
|
379
|
+
afs.setState(state);
|
|
348
380
|
```
|
|
349
381
|
|
|
350
|
-
###
|
|
382
|
+
### Animations
|
|
351
383
|
|
|
352
384
|
```javascript
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
385
|
+
const afs = new AFS({
|
|
386
|
+
animation: {
|
|
387
|
+
type: 'fade', // fade, slide, scale, flip, rotate, zoom, bounce, blur, etc.
|
|
388
|
+
duration: 400,
|
|
389
|
+
easing: 'ease-out'
|
|
390
|
+
}
|
|
356
391
|
});
|
|
392
|
+
|
|
393
|
+
// Change animation at runtime
|
|
394
|
+
afs.filter.animation.setAnimation('slide');
|
|
357
395
|
```
|
|
358
396
|
|
|
359
|
-
|
|
397
|
+
## Configuration Options
|
|
360
398
|
|
|
361
399
|
```javascript
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
400
|
+
const afs = new AFS({
|
|
401
|
+
// Required selectors
|
|
402
|
+
containerSelector: '.items-container',
|
|
403
|
+
itemSelector: '.filter-item',
|
|
404
|
+
filterButtonSelector: '.btn-filter',
|
|
405
|
+
searchInputSelector: '.filter-search',
|
|
406
|
+
counterSelector: '.filter-counter',
|
|
407
|
+
|
|
408
|
+
// Filter logic (NEW!)
|
|
409
|
+
filterCategoryMode: 'mixed', // 'mixed', 'OR', 'AND'
|
|
410
|
+
filterTypeLogic: {
|
|
411
|
+
category: { mode: 'OR', multi: true },
|
|
412
|
+
brand: 'OR',
|
|
413
|
+
price: 'AND'
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
// Search configuration
|
|
417
|
+
searchKeys: ['title', 'categories', 'description'],
|
|
418
|
+
searchMode: 'fuzzy', // 'fuzzy' or 'exact'
|
|
419
|
+
searchMinChars: 2,
|
|
420
|
+
debounceTime: 300,
|
|
421
|
+
|
|
422
|
+
// Pagination
|
|
423
|
+
pagination: {
|
|
424
|
+
enabled: true,
|
|
425
|
+
itemsPerPage: 12,
|
|
426
|
+
container: '.afs-pagination-container',
|
|
427
|
+
showPrevNext: true,
|
|
428
|
+
scrollToTop: true,
|
|
429
|
+
scrollBehavior: 'smooth'
|
|
430
|
+
},
|
|
431
|
+
|
|
432
|
+
// Counter display
|
|
433
|
+
counter: {
|
|
434
|
+
template: 'Showing {visible} of {total} items',
|
|
435
|
+
filteredTemplate: '({filtered} filtered)',
|
|
436
|
+
noResultsTemplate: 'No items found'
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
// Animations
|
|
440
|
+
animation: {
|
|
441
|
+
type: 'fade',
|
|
442
|
+
duration: 300,
|
|
443
|
+
easing: 'ease-out'
|
|
444
|
+
},
|
|
445
|
+
|
|
446
|
+
// State management
|
|
447
|
+
preserveState: true,
|
|
448
|
+
urlStateKey: 'filters',
|
|
449
|
+
|
|
450
|
+
// Styling
|
|
451
|
+
styles: {
|
|
452
|
+
colors: {
|
|
453
|
+
primary: '#000',
|
|
454
|
+
background: '#f5f5f5',
|
|
455
|
+
text: '#333'
|
|
456
|
+
},
|
|
457
|
+
button: {
|
|
458
|
+
borderRadius: '6px',
|
|
459
|
+
padding: '8px 16px'
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
|
|
463
|
+
// Debug mode
|
|
464
|
+
debug: true
|
|
465
|
+
});
|
|
370
466
|
```
|
|
371
467
|
|
|
372
|
-
##
|
|
373
|
-
|
|
374
|
-
Each component can be used independently or as part of the AFS system.
|
|
375
|
-
|
|
376
|
-
### Filter System
|
|
377
|
-
|
|
378
|
-
See [Filter Documentation](docs/filter.md)
|
|
379
|
-
|
|
380
|
-
### Range Filter
|
|
381
|
-
|
|
382
|
-
See [Range Filter Documentation](docs/range-filter.md)
|
|
383
|
-
|
|
384
|
-
### Input Range Filter
|
|
385
|
-
|
|
386
|
-
See [Input Range Filter Documentation](docs/input-range-filter.md)
|
|
387
|
-
|
|
388
|
-
### Date Filter
|
|
468
|
+
## API Reference
|
|
389
469
|
|
|
390
|
-
|
|
470
|
+
### Core Methods
|
|
391
471
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
See [Sort Documentation](docs/sort.md)
|
|
399
|
-
|
|
400
|
-
### Pagination System
|
|
401
|
-
|
|
402
|
-
See [Pagination Documentation](docs/pagination.md)
|
|
472
|
+
```javascript
|
|
473
|
+
// Filter management
|
|
474
|
+
afs.filter.addFilter('category:tech');
|
|
475
|
+
afs.filter.removeFilter('category:tech');
|
|
476
|
+
afs.filter.clearAllFilters();
|
|
477
|
+
afs.filter.setFilterTypeLogic('brand', 'AND');
|
|
403
478
|
|
|
404
|
-
|
|
479
|
+
// Search
|
|
480
|
+
afs.search.search('query');
|
|
481
|
+
afs.search.clearSearch();
|
|
405
482
|
|
|
406
|
-
|
|
483
|
+
// Sorting
|
|
484
|
+
afs.filter.sortWithOrder('price', 'DESC');
|
|
485
|
+
afs.filter.shuffle();
|
|
407
486
|
|
|
408
|
-
|
|
487
|
+
// Pagination
|
|
488
|
+
afs.pagination.goToPage(2);
|
|
489
|
+
afs.pagination.nextPage();
|
|
490
|
+
afs.pagination.previousPage();
|
|
409
491
|
|
|
410
|
-
|
|
492
|
+
// State
|
|
493
|
+
const state = afs.getState();
|
|
494
|
+
afs.setState(state);
|
|
411
495
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
colors: {
|
|
416
|
-
primary: '#3b82f6',
|
|
417
|
-
background: '#f3f4f6',
|
|
418
|
-
text: '#1f2937'
|
|
419
|
-
}
|
|
420
|
-
}
|
|
496
|
+
// Events
|
|
497
|
+
afs.on('filter:applied', (data) => {
|
|
498
|
+
console.log(`Showing ${data.visible} of ${data.total} items`);
|
|
421
499
|
});
|
|
422
500
|
```
|
|
423
501
|
|
|
424
|
-
###
|
|
502
|
+
### Event System
|
|
425
503
|
|
|
426
504
|
```javascript
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
},
|
|
434
|
-
}
|
|
435
|
-
});
|
|
505
|
+
// Available events
|
|
506
|
+
afs.on('filter:applied', callback);
|
|
507
|
+
afs.on('search:performed', callback);
|
|
508
|
+
afs.on('sort:applied', callback);
|
|
509
|
+
afs.on('pagination:changed', callback);
|
|
510
|
+
afs.on('state:changed', callback);
|
|
436
511
|
```
|
|
437
512
|
|
|
438
|
-
|
|
513
|
+
## Examples
|
|
439
514
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
515
|
+
The project includes comprehensive examples demonstrating all features:
|
|
516
|
+
|
|
517
|
+
- **[Interactive Demo](examples/demo.html)** - Complete demo with all filter types
|
|
518
|
+
- **[Button Filters](examples/demo.html#buttons)** - Toggle and multi-select buttons
|
|
519
|
+
- **[Select Dropdowns](examples/demo.html#select)** - Dropdown filter controls
|
|
520
|
+
- **[Radio Buttons](examples/demo.html#radio)** - Exclusive radio button filters
|
|
521
|
+
- **[Checkboxes](examples/demo.html#checkbox)** - Multi-select checkbox filters
|
|
522
|
+
- **[Range Filters](examples/demo.html#range)** - Sliders with histogram support
|
|
523
|
+
- **[Search Functionality](examples/demo.html#search)** - Real-time search examples
|
|
524
|
+
|
|
525
|
+
### Running Examples Locally
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
# Clone the repository
|
|
529
|
+
git clone https://github.com/misits/advanced-filter-system.git
|
|
530
|
+
cd advanced-filter-system
|
|
531
|
+
|
|
532
|
+
# Open examples in browser
|
|
533
|
+
open examples/index.html
|
|
448
534
|
```
|
|
449
535
|
|
|
450
536
|
## Browser Support
|
|
@@ -455,19 +541,33 @@ const afs = new AFS({
|
|
|
455
541
|
- Edge (latest)
|
|
456
542
|
- Opera (latest)
|
|
457
543
|
|
|
544
|
+
Modern browser features used:
|
|
545
|
+
- ES6 Modules
|
|
546
|
+
- CSS Custom Properties
|
|
547
|
+
- IntersectionObserver API
|
|
548
|
+
- URLSearchParams API
|
|
549
|
+
|
|
458
550
|
## TypeScript Support
|
|
459
551
|
|
|
460
|
-
Full TypeScript support with type definitions
|
|
552
|
+
Full TypeScript support with comprehensive type definitions:
|
|
461
553
|
|
|
462
554
|
```typescript
|
|
463
|
-
import {
|
|
555
|
+
import { AFS, AFSOptions, FilterTypeLogic } from 'advanced-filter-system';
|
|
556
|
+
|
|
557
|
+
interface CustomOptions extends AFSOptions {
|
|
558
|
+
customProperty: string;
|
|
559
|
+
}
|
|
464
560
|
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
561
|
+
const filterLogic: FilterTypeLogic = {
|
|
562
|
+
category: { mode: 'OR', multi: true },
|
|
563
|
+
brand: 'OR'
|
|
468
564
|
};
|
|
469
565
|
|
|
470
|
-
const afs = new AFS(
|
|
566
|
+
const afs = new AFS({
|
|
567
|
+
containerSelector: '#items',
|
|
568
|
+
itemSelector: '.item',
|
|
569
|
+
filterTypeLogic: filterLogic
|
|
570
|
+
} as CustomOptions);
|
|
471
571
|
```
|
|
472
572
|
|
|
473
573
|
## Contributing
|
|
@@ -475,10 +575,29 @@ const afs = new AFS(options);
|
|
|
475
575
|
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on:
|
|
476
576
|
|
|
477
577
|
1. Setting up the development environment
|
|
478
|
-
2.
|
|
479
|
-
3.
|
|
480
|
-
4.
|
|
481
|
-
5.
|
|
578
|
+
2. Code style and standards
|
|
579
|
+
3. Testing requirements
|
|
580
|
+
4. Pull request process
|
|
581
|
+
5. Bug reporting guidelines
|
|
582
|
+
6. Feature request templates
|
|
583
|
+
|
|
584
|
+
### Development Setup
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
# Clone and install
|
|
588
|
+
git clone https://github.com/misits/advanced-filter-system.git
|
|
589
|
+
cd advanced-filter-system
|
|
590
|
+
npm install
|
|
591
|
+
|
|
592
|
+
# Run development server
|
|
593
|
+
npm run dev
|
|
594
|
+
|
|
595
|
+
# Build for production
|
|
596
|
+
npm run build
|
|
597
|
+
|
|
598
|
+
# Run tests
|
|
599
|
+
npm test
|
|
600
|
+
```
|
|
482
601
|
|
|
483
602
|
## License
|
|
484
603
|
|
|
@@ -487,3 +606,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
487
606
|
---
|
|
488
607
|
|
|
489
608
|
Made with ♥ by [misits](https://github.com/misits)
|
|
609
|
+
|
|
610
|
+
**Star ⭐ this repo if you find it helpful!**
|