Custom HTML filters

🎠 Create any filtering experience you like

Custom HTML Filters are a powerful feature that allows developers to create completely customized filtering interfaces for Directual Web Components (Tables, Cards, etc.). Instead of being limited to the built-in filter components, you can write your own HTML, CSS, and JavaScript to create any filtering experience you need.

What are HTML Filters?

HTML Filters are custom user interfaces that replace the standard Directual filtering system. They consist of:

  • Custom HTML: Your own form elements, layouts, and styling

  • Interactive JavaScript: Logic to handle user interactions and generate filters

  • DQL Integration: Seamless connection to Directual's query language

  • Real-time Updates: Instant filtering as users interact with your interface

Key Benefits

Complete Design Freedom: Create filters that match your exact design requirements ✅ Advanced Interactions: Build complex filtering logic with multiple conditions ✅ Custom Components: Use any UI library or custom components you prefer ✅ Business Logic: Implement domain-specific filtering rules and validations ✅ User Experience: Design intuitive interfaces tailored to your users' needs

How It Works

  1. Enable Custom Filters: Set customHTMLfilters: true in your component props

  2. Provide HTML Content: Pass your custom HTML/CSS/JS in customHTMLfiltersContent

  3. Use the API: Access window.DirectualFilter to interact with the filtering system

  4. Generate DQL: Create Directual Query Language strings to filter data

  5. Apply Filters: Call window.DirectualFilter.emit(dql) to update the view

Use Cases

  • E-commerce: Product search with price ranges, categories, ratings, and availability

  • Real Estate: Property filters with location maps, price ranges, and feature checkboxes

  • CRM: Contact filtering with tags, date ranges, and custom field combinations

  • Analytics: Data filtering with date pickers, metric selectors, and comparison tools

  • Content Management: Article filtering with categories, authors, and publication dates

AI Prompt for Custom Filter Development

You are an expert web developer creating custom HTML filters for Directual Web Components. Your task is to create interactive filter interfaces that integrate with the Directual filtering system.

### Technical Requirements

**API Contract:**
- Use `window.DirectualFilter.props` to access current state and available fields
- Call `window.DirectualFilter.emit(dqlString)` to apply filters
- DQL (Directual Query Language) format: `'fieldName' operator 'value'`

**Available Data:**
```javascript
window.DirectualFilter.props = {
    currentFilter: string,    // Current DQL filter
    fields: Array<{          // Available fields for filtering
        key: string,         // Field system name
        value: string        // Field display name
    }>,
    lang: string,           // Current language
    dict: object           // Localization dictionary
}
```

**DQL Operators:**
- `like` - partial text match
- `=` - exact match  
- `>=`, `<=`, `>`, `<` - numeric/date comparisons
- `AND`, `OR` - logical operators

### Filter Design Guidelines

**[DESCRIBE YOUR FILTER REQUIREMENTS HERE]**
*Example: Create a modern, responsive filter interface with search inputs, dropdown selectors, and date pickers. Use Bootstrap-style components with blue (#007bff) primary color and clean typography.*

### Implementation Pattern

1. **HTML Structure**: Create form elements with unique IDs
2. **JavaScript Functions**: Implement filter logic and DQL generation
3. **Event Handlers**: Connect UI interactions to `window.DirectualFilter.emit()`
4. **State Management**: Handle filter clearing and validation

### Example Code Template

```html
<div style="padding: 20px; border: 1px solid #ddd; border-radius: 8px;">
    <h4>Custom Filters</h4>
    
    <!-- Text Search -->
    <div style="margin-bottom: 15px;">
        <label>Search Text:</label>
        <input type="text" id="textSearch" placeholder="Enter search term...">
        <button onclick="applyTextFilter()">Apply</button>
    </div>
    
    <!-- Numeric Range -->
    <div style="margin-bottom: 15px;">
        <label>Number Range:</label>
        <input type="number" id="minNumber" placeholder="Min">
        <input type="number" id="maxNumber" placeholder="Max">
        <button onclick="applyNumberFilter()">Filter</button>
    </div>
    
    <!-- Actions -->
    <button onclick="clearFilters()">Clear All</button>
</div>

<script>
function applyTextFilter() {
    const value = document.getElementById('textSearch').value;
    if (value) {
        const dql = "'fieldName' like '" + value + "'";
        window.DirectualFilter.emit(dql);
    }
}

function applyNumberFilter() {
    const min = document.getElementById('minNumber').value;
    const max = document.getElementById('maxNumber').value;
    
    let conditions = [];
    if (min) conditions.push("'numberField' >= '" + min + "'");
    if (max) conditions.push("'numberField' <= '" + max + "'");
    
    const dql = conditions.join(' AND ');
    window.DirectualFilter.emit(dql);
}

function clearFilters() {
    document.getElementById('textSearch').value = '';
    document.getElementById('minNumber').value = '';
    document.getElementById('maxNumber').value = '';
    window.DirectualFilter.emit('');
}

// Initialize on load
setTimeout(() => {
    console.log('Available fields:', window.DirectualFilter.props.fields);
}, 100);
</script>
```

### Best Practices

1. **Field Validation**: Check if fields exist before filtering
2. **Error Handling**: Validate user input and DQL syntax
3. **Performance**: Debounce rapid filter changes
4. **UX**: Provide clear feedback and loading states
5. **Accessibility**: Use proper labels and keyboard navigation

### Advanced Features

- **Multi-field filtering**: Combine multiple conditions with AND/OR
- **Dynamic field selection**: Let users choose which fields to filter
- **Preset filters**: Provide common filter combinations
- **Filter history**: Save and restore previous filter states

---

## Simple Example: Product Search Filter

```html
<div class="custom-filter" style="padding: 20px; background: #f8f9fa; border-radius: 8px; font-family: Arial, sans-serif;">
    <h3 style="margin-top: 0; color: #333;">🔍 Product Search</h3>
    
    <!-- Product Name Search -->
    <div style="margin-bottom: 15px;">
        <label style="display: block; font-weight: bold; margin-bottom: 5px;">Product Name:</label>
        <input type="text" id="productName" 
               style="width: 250px; padding: 8px; border: 1px solid #ccc; border-radius: 4px;"
               placeholder="Enter product name...">
    </div>
    
    <!-- Price Range -->
    <div style="margin-bottom: 15px;">
        <label style="display: block; font-weight: bold; margin-bottom: 5px;">Price Range:</label>
        <input type="number" id="minPrice" placeholder="Min $" 
               style="width: 100px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; margin-right: 10px;">
        <input type="number" id="maxPrice" placeholder="Max $"
               style="width: 100px; padding: 8px; border: 1px solid #ccc; border-radius: 4px;">
    </div>
    
    <!-- Category Dropdown -->
    <div style="margin-bottom: 15px;">
        <label style="display: block; font-weight: bold; margin-bottom: 5px;">Category:</label>
        <select id="category" style="width: 200px; padding: 8px; border: 1px solid #ccc; border-radius: 4px;">
            <option value="">All Categories</option>
            <option value="electronics">Electronics</option>
            <option value="clothing">Clothing</option>
            <option value="books">Books</option>
        </select>
    </div>
    
    <!-- Action Buttons -->
    <div>
        <button onclick="searchProducts()" 
                style="padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px;">
            Search Products
        </button>
        <button onclick="clearSearch()"
                style="padding: 10px 20px; background: #6c757d; color: white; border: none; border-radius: 4px; cursor: pointer;">
            Clear
        </button>
    </div>
    
    <!-- Status Display -->
    <div id="filterStatus" style="margin-top: 15px; padding: 10px; background: #e9ecef; border-radius: 4px; display: none;">
        <strong>Active Filter:</strong> <span id="currentFilter"></span>
    </div>
</div>

<script>
function searchProducts() {
    const name = document.getElementById('productName').value;
    const minPrice = document.getElementById('minPrice').value;
    const maxPrice = document.getElementById('maxPrice').value;
    const category = document.getElementById('category').value;
    
    let conditions = [];
    
    // Add name filter
    if (name) {
        conditions.push("'productName' like '" + name + "'");
    }
    
    // Add price range filters
    if (minPrice) {
        conditions.push("'price' >= '" + minPrice + "'");
    }
    if (maxPrice) {
        conditions.push("'price' <= '" + maxPrice + "'");
    }
    
    // Add category filter
    if (category) {
        conditions.push("'category' = '" + category + "'");
    }
    
    // Combine all conditions
    const dql = conditions.join(' AND ');
    
    // Show current filter
    updateFilterStatus(dql);
    
    // Apply filter
    window.DirectualFilter.emit(dql);
    
    console.log('Applied filter:', dql);
}

function clearSearch() {
    // Clear all inputs
    document.getElementById('productName').value = '';
    document.getElementById('minPrice').value = '';
    document.getElementById('maxPrice').value = '';
    document.getElementById('category').value = '';
    
    // Hide status
    document.getElementById('filterStatus').style.display = 'none';
    
    // Clear filter
    window.DirectualFilter.emit('');
    
    console.log('Filters cleared');
}

function updateFilterStatus(dql) {
    const status = document.getElementById('filterStatus');
    const current = document.getElementById('currentFilter');
    
    if (dql) {
        current.textContent = dql;
        status.style.display = 'block';
    } else {
        status.style.display = 'none';
    }
}

// Auto-search on Enter key
document.addEventListener('keypress', function(e) {
    if (e.key === 'Enter') {
        searchProducts();
    }
});

// Initialize when API is ready
setTimeout(() => {
    if (window.DirectualFilter) {
        console.log('🚀 Custom filter ready!');
        console.log('Available fields:', window.DirectualFilter.props.fields);
        
        // Show current filter if any
        const current = window.DirectualFilter.props.currentFilter;
        if (current) {
            updateFilterStatus(current);
        }
    }
}, 100);
</script>
```

This example creates a comprehensive product search interface with:
- Text search for product names
- Numeric range filtering for prices  
- Dropdown category selection
- Combined filter logic with AND operators
- Clear visual feedback
- Keyboard shortcuts (Enter to search)

The filter generates DQL like: `'productName' like 'laptop' AND 'price' >= '100' AND 'price' <= '500' AND 'category' = 'electronics'`

Last updated

Was this helpful?