npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

advanced-filter-system

v1.5.2

Published

Advanced filtering system for DOM elements with multiple features

Readme

Advanced Filter System (AFS)

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.

✨ NEW in v1.5.1: Enhanced mixed mode filtering, improved event system, and comprehensive URL state management!

Live Demo | NPM Package | Interactive Examples

Table of Contents

Features

  • 🎯 Advanced Filter Logic
    • Mixed mode (OR within categories, AND between)
    • Per-type logic configuration
    • Multi-select and toggle modes
    • Category-specific clearing
  • 🔍 Multiple Filter Types
    • Button filters (toggle/multi-select)
    • Select dropdowns
    • Radio buttons (exclusive)
    • Checkboxes (multi-select)
    • Range sliders with histograms
    • Date range filters
  • 🔎 Smart Search
    • Real-time fuzzy search
    • Multiple searchable fields
    • Configurable debouncing
    • Minimum character threshold
  • ↕️ Flexible Sorting
    • Multi-column sorting
    • Custom sort functions
    • Auto-detect data types
    • Sort direction indicators
  • 📄 Advanced Pagination
    • Dynamic page sizes
    • Smooth transitions
    • Scroll-to-top option
    • Custom pagination controls
  • 🎨 Rich Animations
    • 14+ animation types (fade, slide, scale, flip, etc.)
    • Hardware-accelerated transitions
    • Customizable duration and easing
  • 🔗 State Management
    • URL state persistence
    • Browser history support
    • Shareable filtered URLs
    • State import/export
  • Performance Optimized
    • Debounced updates
    • Efficient DOM manipulation
    • Minimal reflows and repaints
  • 🎯 Event System
    • Comprehensive event API
    • Custom event support
    • Debug mode with logging

Installation

# NPM
npm install advanced-filter-system

# Yarn
yarn add advanced-filter-system

# PNPM
pnpm add advanced-filter-system

Or include via CDN:

<script type="module">
    import { AFS } from 'https://unpkg.com/advanced-filter-system@latest/dist/afs.modern.js';
</script>

Quick Start

HTML Structure

<!DOCTYPE html>
<html>
<head>
    <title>AFS Demo</title>
</head>
<body>
    <!-- Filter Controls -->
    <div class="filter-controls">
        <button class="btn-filter" data-filter="*">All</button>
        <button class="btn-filter" data-filter="category:tech">Technology</button>
        <button class="btn-filter" data-filter="category:design">Design</button>
    </div>
    
    <!-- Search Input -->
    <input type="text" class="filter-search" placeholder="Search...">
    
    <!-- Results Counter -->
    <div class="filter-counter"></div>
    
    <!-- Filterable Items -->
    <div class="items-container">
        <div class="filter-item" 
             data-categories="category:tech brand:apple" 
             data-title="MacBook Pro"
             data-price="2499"
             data-date="2024-03-15">
            <h3>MacBook Pro</h3>
            <p>$2,499</p>
        </div>
        <!-- More items... -->
    </div>
    
    <!-- Pagination Container -->
    <div class="afs-pagination-container"></div>
</body>
</html>

JavaScript Initialization

import { AFS } from 'advanced-filter-system';

const afs = new AFS({
    // Required selectors
    containerSelector: '.items-container',
    itemSelector: '.filter-item',
    filterButtonSelector: '.btn-filter',
    searchInputSelector: '.filter-search',
    counterSelector: '.filter-counter',
    
    // Search configuration
    searchKeys: ['title', 'categories'],
    
    // NEW: Advanced filter logic
    filterCategoryMode: 'mixed', // OR within categories, AND between
    filterTypeLogic: {
        category: { mode: 'OR', multi: true },  // Multi-select OR
        brand: 'OR',                            // Toggle mode
        price: 'AND'                            // Multi-select AND
    },
    
    // Pagination
    pagination: {
        enabled: true,
        itemsPerPage: 12
    },
    
    // Animations
    animation: {
        type: 'fade',
        duration: 300
    },
    
    // Debug mode
    debug: true
});

Filter Logic Modes

Mixed Mode (Recommended)

The most intuitive filtering experience - OR logic within filter categories, AND logic between different categories.

const afs = new AFS({
    filterCategoryMode: 'mixed',
    // When user selects: Tech OR Design AND Apple OR Samsung
    // Shows: (Tech OR Design) AND (Apple OR Samsung)
});

Per-Type Logic Configuration

Configure each filter type independently for maximum flexibility.

const afs = new AFS({
    filterCategoryMode: 'mixed',
    filterTypeLogic: {
        category: { mode: 'OR', multi: true },  // Multi-select checkboxes
        brand: 'OR',                            // Toggle buttons (exclusive)
        price: 'AND',                           // Multi-select with AND logic
        features: { mode: 'OR', multi: true }   // Multi-select with OR logic
    }
});

// Update logic at runtime
afs.filter.setFilterTypeLogic('brand', { mode: 'OR', multi: true });

Legacy Modes

// Legacy OR mode (all filters use OR logic)
const afs = new AFS({ filterCategoryMode: 'OR' });

// Legacy AND mode (all filters use AND logic)
const afs = new AFS({ filterCategoryMode: 'AND' });

Filter Types & UI Components

Button Filters

<!-- Toggle mode (exclusive) -->
<button class="btn-filter" data-filter="category:tech">Technology</button>

<!-- Multi-select mode -->
<button class="btn-filter" data-filter="brand:apple">Apple</button>
<button class="btn-filter" data-filter="brand:samsung">Samsung</button>

<!-- Clear specific category -->
<button class="btn-filter" data-filter="category:*">Clear Categories</button>

Select Dropdowns

<select class="afs-filter-dropdown">
    <option value="*">All Categories</option>
    <option value="category:tech">Technology</option>
    <option value="category:design">Design</option>
</select>

Radio Buttons

<label><input type="radio" name="category" class="btn-filter" data-filter="*" checked> All</label>
<label><input type="radio" name="category" class="btn-filter" data-filter="category:tech"> Tech</label>
<label><input type="radio" name="category" class="btn-filter" data-filter="category:design"> Design</label>

Checkboxes

<label><input type="checkbox" class="btn-filter" data-filter="category:tech"> Technology</label>
<label><input type="checkbox" class="btn-filter" data-filter="category:design"> Design</label>

Range Sliders

// Add price range slider with histogram
afs.rangeFilter.addRangeSlider({
    key: 'price',
    type: 'number',
    container: '.price-range-container',
    min: 0,
    max: 3000,
    step: 50,
    ui: {
        showHistogram: true,
        bins: 10
    }
});

// Add rating range slider
afs.rangeFilter.addRangeSlider({
    key: 'rating',
    type: 'number',
    container: '.rating-range-container',
    min: 4.0,
    max: 5.0,
    step: 0.1
});

Date Range Filters

// Add date range filter
afs.dateFilter.addDateRange({
    key: 'date',
    container: '.date-range-container',
    minDate: new Date('2024-01-01'),
    maxDate: new Date(),
    format: 'YYYY-MM-DD'
});

Advanced Features

Search & Filtering

// Programmatic search
afs.search.search('query');
afs.search.clearSearch();
afs.search.setValue('new query');

// Programmatic filtering
afs.filter.addFilter('category:tech');
afs.filter.removeFilter('category:tech');
afs.filter.clearAllFilters();
afs.filter.clearFilterCategory('category:*');

Sorting

// Sort by single field
afs.sort.sort('price', 'desc');

// Custom sorting
afs.sort.sortWithComparator('title', (a, b) => {
    return a.localeCompare(b, 'en', { numeric: true });
});

// Shuffle items
afs.sort.shuffle();

Pagination

// Pagination navigation
afs.pagination.goToPage(2);
afs.pagination.nextPage();
afs.pagination.previousPage();

// Toggle pagination mode
afs.pagination.setPaginationMode(true); // Enable
afs.pagination.setPaginationMode(false); // Show all

URL State Management

// Enable URL state persistence
const afs = new AFS({
    preserveState: true,
    urlStateKey: 'filters' // Custom URL parameter name
});

// Manual state management
const state = afs.getState();
afs.setState(state);

Animations

const afs = new AFS({
    animation: {
        type: 'fade', // fade, slide, scale, flip, rotate, zoom, bounce, blur, etc.
        duration: 400,
        easing: 'ease-out'
    }
});

// Change animation options at runtime
afs.updateOptions({
    animation: {
        type: 'slide',
        duration: 400
    }
});

Configuration Options

const afs = new AFS({
    // Required selectors
    containerSelector: '.items-container',
    itemSelector: '.filter-item',
    filterButtonSelector: '.btn-filter',
    searchInputSelector: '.filter-search',
    counterSelector: '.filter-counter',
    
    // Filter logic (NEW!)
    filterCategoryMode: 'mixed', // 'mixed', 'OR', 'AND'
    filterTypeLogic: {
        category: { mode: 'OR', multi: true },
        brand: 'OR',
        price: 'AND'
    },
    
    // Search configuration
    searchKeys: ['title', 'categories', 'description'],
    debounceTime: 300,
    
    // Pagination
    pagination: {
        enabled: true,
        itemsPerPage: 12,
        container: '.afs-pagination-container',
        showPrevNext: true,
        scrollToTop: true,
        scrollBehavior: 'smooth'
    },
    
    // Counter display
    counter: {
        template: 'Showing {visible} of {total}',
        showFiltered: true,
        filteredTemplate: '({filtered} filtered)',
        noResultsTemplate: 'No items found',
        formatter: (num) => num.toLocaleString()
    },
    
    // Animations
    animation: {
        type: 'fade',
        duration: 300,
        easing: 'ease-out'
    },
    
    // State management
    preserveState: true,
    stateExpiry: 86400000, // 24 hours
    observeDOM: false,
    
    // CSS Classes
    activeClass: 'active',
    hiddenClass: 'hidden',
    activeSortClass: 'sort-active',
    
    // Debug mode
    debug: true
});

API Reference

Core Methods

// Filter management
afs.filter.addFilter('category:tech');
afs.filter.removeFilter('category:tech');
afs.filter.clearAllFilters();
afs.filter.clearFilterCategory('category:*');
afs.filter.setFilterTypeLogic('brand', { mode: 'OR', multi: true });
afs.filter.toggleFilterExclusive('category:tech');

// Search
afs.search.search('query');
afs.search.clearSearch();
afs.search.setValue('new query');
const currentQuery = afs.search.getValue();

// Sorting  
afs.sort.sort('price', 'desc');
afs.sort.sortMultiple([
    { key: 'category', direction: 'asc' },
    { key: 'price', direction: 'desc' }
]);
afs.sort.shuffle();
afs.sort.reset();

// Pagination
afs.pagination.goToPage(2);
afs.pagination.nextPage();
afs.pagination.previousPage();
afs.pagination.setPaginationMode(true);

// Range Filters
afs.rangeFilter.addRangeSlider({
    key: 'price',
    container: '.price-range-container'
});

// Date Filters
afs.dateFilter.addDateRange({
    key: 'date',
    container: '.date-range-container'
});

// State
const state = afs.getState();
afs.setState(state);

// Events
afs.on('filtersApplied', (data) => {
    console.log(`Showing ${data.visibleItems} of ${data.total} items`);
});

Event System

// Available events
afs.on('filtersApplied', callback);
afs.on('search', callback);
afs.on('sort', callback);
afs.on('pageChanged', callback);
afs.on('urlStateLoaded', callback);

Examples

The project includes comprehensive examples demonstrating all features:

Running Examples Locally

# Clone the repository
git clone https://github.com/misits/advanced-filter-system.git
cd advanced-filter-system

# Open examples in browser
open examples/index.html

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)
  • Opera (latest)

Modern browser features used:

  • ES6 Modules
  • CSS Custom Properties
  • IntersectionObserver API
  • URLSearchParams API

TypeScript Support

Full TypeScript support with comprehensive type definitions:

import { AFS, AFSOptions, FilterTypeLogic } from 'advanced-filter-system';

interface CustomOptions extends AFSOptions {
    customProperty: string;
}

const filterLogic: FilterTypeLogic = {
    category: { mode: 'OR', multi: true },
    brand: 'OR'
};

const afs = new AFS({
    containerSelector: '#items',
    itemSelector: '.item',
    filterTypeLogic: filterLogic
} as CustomOptions);

Contributing

We welcome contributions! Please see our Contributing Guide for details on:

  1. Setting up the development environment
  2. Code style and standards
  3. Testing requirements
  4. Pull request process
  5. Bug reporting guidelines
  6. Feature request templates

Development Setup

# Clone and install
git clone https://github.com/misits/advanced-filter-system.git
cd advanced-filter-system
npm install

# Run development server
npm run dev

# Build for production
npm run build

# Run tests
npm test

License

This project is licensed under the MIT License - see the LICENSE file for details.


Made with ♥ by misits

Star ⭐ this repo if you find it helpful!