# SmartFilter.js

######

## Find What You Need, Instantly!

SmartFilter.js is a powerful JavaScript library that provides advanced filtering capabilities for lists, navigation menus, and other DOM elements. It features fuzzy search with intelligent scoring, performance optimizations, and a robust error handling system.

Pro Tip: SmartFilter.js uses an advanced fuzzy matching algorithm that can find items even when users make typos or only remember part of a name.

## Installation

Include the SmartFilter.js script in your HTML file:

    <script src="scripts/core/smartFilter.js"></script>

#### Basic initialization

    // Initialize with default options
    var filter = new ListFilter('#navigation-list', '#search-input');

    // Or with custom options
    var filter = new ListFilter('#navigation-list', '#search-input', {
        debounceWait: 300,
        minLength: 2,
        caseSensitive: false,
        onFilter: function(value) {
            console.log('Filtering with:', value);
        }
    });

#### HTML Structure

    <input type="text" id="search-input" placeholder="Search...">
    <span class="js-filter-message"></span>

    <nav id="navigation-list">
        <ul>
            <li class="nav-title">Category 1</li>
            <li>
                <a href="page1.html">
                    <span class="nav-link-text">Page 1</span>
                </a>
            </li>
            <li>
                <a href="page2.html">
                    <span class="nav-link-text">Page 2</span>
                </a>
            </li>
            <li class="nav-title">Category 2</li>
            <li>
                <a href="page3.html">
                    <span class="nav-link-text">Page 3</span>
                </a>
            </li>
        </ul>
    </nav>

Important: For the filter to work correctly, each filterable item should have a `<span class="nav-link-text">` element containing the text to be filtered.

## Configuration Options

SmartFilter.js offers several configuration options to customize its behavior:

Option | Default Value | Description | Type
--- | --- | --- | ---
`anchor` | null | Element to which the filter class will be applied (instead of the list element). | Element|string|null
`messageSelector` | '.js-filter-message' | Selector for the element that displays the match count. | string
`debounceWait` | 250 | Time in milliseconds to wait before filtering after input changes. | number
`minLength` | 1 | Minimum number of characters required to trigger filtering. | number
`maxLength` | 100 | Maximum number of characters allowed in the search input. | number
`caseSensitive` | false | Whether the filter should be case-sensitive. | boolean
`onFilter` | null | Callback function that is called when filtering occurs. | Function|null
`onReset` | null | Callback function that is called when the filter is reset. | Function|null
`onError` | null | Callback function that is called when an error occurs. | Function|null

## Advanced Configuration Example

Here's an example of how to configure SmartFilter with advanced options:

    var filter = new ListFilter('#navigation-list', '#search-input', {
        anchor: '#nav-container',
        messageSelector: '.filter-results',
        debounceWait: 300,
        minLength: 2,
        maxLength: 50,
        caseSensitive: false,
        onFilter: function(value) {
            console.log('Filtering with:', value);
            // Update UI or trigger other actions
        },
        onReset: function() {
            console.log('Filter has been reset');
            // Restore original state or trigger other actions
        },
        onError: function(error) {
            console.error('Filter error:', error);
            // Handle errors gracefully
        }
    });

## Fuzzy Search Algorithm

SmartFilter.js uses an advanced fuzzy search algorithm with intelligent scoring:

    // Match weights used by the fuzzy search algorithm
    var MATCH_WEIGHTS = {
        EXACT: 3,              // Exact match gets highest score
        SUBSTRING: 2,          // Substring match gets second highest score
        CONSECUTIVE: 0.5,      // Consecutive character matches
        CONSECUTIVE_BONUS: 0.1, // Bonus for each additional consecutive match
        NON_CONSECUTIVE: 0.3,  // Non-consecutive character matches
        PREFIX_BONUS: 0.2,     // Bonus for matching at the beginning
        CASE_MATCH_BONUS: 0.1  // Bonus for matching case
    };

The algorithm provides several advantages:

- Typo tolerance: Finds matches even when users make typing errors
- Partial matching: Works with incomplete search terms
- Intelligent scoring: Ranks results by relevance
- Performance optimization: Uses caching to improve speed
- Case sensitivity options: Can match exact case or ignore case

Pro Tip: The fuzzy search algorithm gives higher scores to matches at the beginning of words and consecutive character matches, making the results more intuitive for users.

## Performance Optimizations

SmartFilter.js includes several performance optimizations:

#### Debouncing

    // Debounce function with rate limiting
    function debounce(func, wait, immediate) {
        var timeout;
        var lastRun = 0;

        return function() {
            var context = this;
            var args = arguments;
            var now = Date.now();

            // Rate limiting
            if (now - lastRun < RATE_LIMIT_MS) {
                return;
            }

            // Debounce implementation
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                timeout = null;
                if (!immediate) func.apply(context, args);
            }, wait);

            if (immediate && !timeout) func.apply(context, args);
        };
    }

#### Result Caching

    // Cache for fuzzy match results
    var fuzzyMatchCache = new Map();

    // Check cache before computing match
    var cacheKey = pattern + '|' + str;
    if (fuzzyMatchCache.has(cacheKey)) {
        return fuzzyMatchCache.get(cacheKey);
    }

    // Store result in cache
    fuzzyMatchCache.set(cacheKey, score);

#### DOM Caching

    // Pre-cache DOM elements
    this._cache = {
        items: this.list.getElementsByTagName('a'),
        titles: this.list.getElementsByTagName('li'),
        messageElement: document.querySelector(this.settings.messageSelector),
        size: 0
    };

Important: The filter automatically clears caches when they grow too large to prevent memory issues. The maximum cache size is set to 10,000 items.

## API Methods

SmartFilter.js exposes several methods for programmatic control:

    // Get filter instance
    var filter = new ListFilter('#navigation-list', '#search-input');

    // Manually trigger filtering
    filter.filter();

    // Reset the filter (clear input and show all items)
    filter.reset();

    // Destroy the filter instance and clean up
    filter.destroy();

#### Internal Methods

    // Find the navigation title associated with an element
    filter.findNavTitle(element);

    // Show all parent elements of a given element
    filter.showParents(element);

    // Show all child elements of a given element
    filter.showChildren(element);

## Error Handling

SmartFilter.js includes a robust error handling system:

    // Error handling with auto-recovery
    _handleError: function(error) {
        console.error('ListFilter error:', error);

        // Track error frequency
        var now = Date.now();
        if (now - this._lastErrorTime > 60000) {
            this._errorCount = 0;
        }

        this._errorCount++;
        this._lastErrorTime = now;

        // Call error callback if provided
        if (this.settings.onError) {
            this.settings.onError(error);
        }

        // Auto-recovery if too many errors
        if (this._errorCount > 10) {
            this.reset();
            this._errorCount = 0;
        }
    }

The error handling system provides:

- Detailed error logging: Logs errors with context information
- Error rate tracking: Monitors error frequency
- Custom error callbacks: Allows custom error handling
- Auto-recovery: Automatically resets the filter if too many errors occur
- Input validation: Prevents common errors by validating inputs

## Event Handling

SmartFilter.js uses efficient event handling to manage user interactions:

    // Bind events with passive listeners for better performance
    bindEvents: function() {
        var self = this;
        this.handleFilter = debounce(this.filter.bind(this), this.settings.debounceWait);

        // Use passive event listeners for better performance
        this.input.addEventListener('input', this._validateEvent.bind(this), { passive: true });
        this.input.addEventListener('change', this._validateEvent.bind(this), { passive: true });

        // Add ESC key handler
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape' || e.key === 'Esc') {
                self.reset();
            }
        });

        // Handle window resize for responsive layouts
        this._resizeHandler = debounce(function() {
            if (self.input.value.length > self.settings.minLength) {
                self.filter();
            }
        }, 250);

        window.addEventListener('resize', this._resizeHandler, { passive: true });
    }

The filter responds to the following events:

- input: Triggers filtering when the search input changes
- change: Triggers filtering when the search input loses focus
- keydown (Escape): Resets the filter when the Escape key is pressed
- resize: Re-applies the filter when the window is resized
- click: Resets the filter when the message element is clicked

## CSS Classes

SmartFilter.js uses several CSS classes to manage the visibility of elements:

Class | Description | Applied To
--- | --- | ---
`js-list-filter` | Indicates that the element is a filterable list | List element or anchor element
`js-list-active` | Indicates that the filter is currently active | List element
`js-filter-hide` | Hides elements that don't match the filter | List items
`js-filter-show` | Shows elements that match the filter | List items
`nav-title` | Identifies category titles in the navigation | Category title elements
`nav-link-text` | Identifies the text content to be filtered | Text elements inside links

Pro Tip: You can style these classes in your CSS to create visual effects when filtering, such as highlighting matched items or fading out hidden items.

## Best Practices

- Set an appropriate `debounceWait` value (200-300ms is recommended) to balance responsiveness and performance
- Use the `minLength` option to prevent filtering on very short inputs
- Provide a clear visual indication when filtering is active
- Include a way for users to clear the filter (the filter automatically supports the Escape key)
- Use the `onFilter` and `onReset` callbacks to synchronize other UI elements
- Implement proper error handling with the `onError` callback

Pro Tip: For large lists, consider increasing the `debounceWait` value to reduce the frequency of filtering operations and improve performance.

## Troubleshooting

Common Issues:

- Filter not working? Check that your HTML structure includes `<span class="nav-link-text">` elements inside your links.
- No matches found? Verify that the text content of your items matches what users are searching for.
- Performance issues? Try increasing the `debounceWait` value and ensure you're not filtering extremely large lists.
- Filter showing incorrect results? Check that your navigation titles are properly marked with the `nav-title` class.
- Match count not showing? Verify that you have an element matching the `messageSelector` option.

##### On This Page

- Introduction
- Installation
- Configuration
- Advanced Configuration
- Fuzzy Search
- Performance
- API Methods
- Error Handling
- Event Handling
- CSS Classes
- Best Practices
- Troubleshooting

#### Hi Sunny,

how can I help you today?
Analyze my data

Create a new report

Summarize my Calendar

App Builder
Unlock limitless design potential with 16+ layout combinations and extensive customization options—tailor your dashboard to fit your exact needs.
Header position fixed
Navigation full height
Navigation position fixed
Navigation collapsed
Navigation Minified
Dark Navigation
Colorblind Mode
High Contrast Mode