Contact Age Filter

This example demonstrates how to create a custom age range filter for a contacts app using the new filterMicroappView async API.

Scenario

You have a contacts table with name and age fields, and you want to create a custom search panel that allows filtering contacts by age range.

Implementation

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        .filter-container {
            display: flex;
            gap: 10px;
            align-items: center;
            padding: 20px;
            font-family: Arial, sans-serif;
        }
        .filter-input {
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 80px;
        }
        .filter-button {
            padding: 8px 16px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .filter-button:hover {
            background: #0056b3;
        }
        .clear-button {
            padding: 8px 16px;
            background: #6c757d;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-left: 5px;
        }
        .clear-button:hover {
            background: #545b62;
        }
    </style>
</head>
<body>
    <div class="filter-container">
        <label>Age from:</label>
        <input type="number" id="minAge" class="filter-input" value="20" min="0" max="120">
        <label>to:</label>
        <input type="number" id="maxAge" class="filter-input" value="30" min="0" max="120">
        <button onclick="applyFilter()" class="filter-button">Filter</button>
        <button onclick="clearFilter()" class="clear-button">Clear</button>
    </div>

    <script>
        let buzzyFrameAPI;
        let contactsTableID;

        (async function initializeAPI() {
            try {
                buzzyFrameAPI = new BuzzyFrameAPI();
                const { resourceJSON } = await buzzyFrameAPI.initialise();
                
                contactsTableID = resourceJSON.children?.find(
                    child => child.title === 'Contacts'
                )?._id;
                
                if (!contactsTableID) {
                    console.error('Contacts table not found in resourceJSON');
                }
            } catch (error) {
                console.error('Failed to initialize BuzzyFrameAPI:', error);
            }
        })();

        async function applyFilter() {
            if (!buzzyFrameAPI || !contactsTableID) {
                console.error('API not initialized or contacts table not found');
                return;
            }

            const minAge = parseInt(document.getElementById('minAge').value);
            const maxAge = parseInt(document.getElementById('maxAge').value);

            if (isNaN(minAge) || isNaN(maxAge)) {
                alert('Please enter valid age values');
                return;
            }

            if (minAge > maxAge) {
                alert('Minimum age cannot be greater than maximum age');
                return;
            }

            try {
                await buzzyFrameAPI.filterMicroappView({
                    microAppID: contactsTableID,
                    viewFilters: [
                        { age: { $gte: minAge } },
                        { age: { $lte: maxAge } }
                    ],
                    viewFilterIsMongoQuery: true,
                    filterContext: 'contact-age-filter'
                });
                console.log(`Applied age filter: ${minAge} to ${maxAge}`);
            } catch (error) {
                console.error('Failed to apply filter:', error);
            }
        }

        async function clearFilter() {
            if (!buzzyFrameAPI || !contactsTableID) {
                console.error('API not initialized or contacts table not found');
                return;
            }

            try {
                await buzzyFrameAPI.filterMicroappView({
                    microAppID: contactsTableID,
                    viewFilters: [],
                    viewFilterIsMongoQuery: true,
                    filterContext: 'contact-age-filter'
                });
                console.log('Cleared age filter');
            } catch (error) {
                console.error('Failed to clear filter:', error);
            }
        }
    </script>
</body>
</html>

Key Points

Modern Async API Approach

  • Uses the new filterMicroappView async API instead of deprecated filterview postMessage

  • Initializes BuzzyFrameAPI at the top level before React components

  • Uses proper error handling with try/catch blocks

MongoDB Query Syntax

  • Uses $gte (greater than or equal) and $lte (less than or equal) operators

  • Supports complex filtering with multiple conditions

  • Set viewFilterIsMongoQuery: true to enable MongoDB operators

User Experience Features

  • Input validation to ensure valid age ranges

  • Clear filter functionality to remove all filters

  • Responsive design with hover effects

  • Error handling with console logging

Filter Context

  • Uses filterContext: 'contact-age-filter' to identify this specific filter

  • Allows multiple filters to coexist without conflicts

  • Helps with debugging and filter management

Migration from Deprecated filterview

If you're migrating from the old filterview postMessage approach:

Old approach (deprecated):

window.parent.postMessage({
    from: 'buzzy-iframe',
    action: 'filterview',
    body: filterParams,
    frameToken: frameToken
}, '*');

New approach (recommended):

await buzzyFrameAPI.filterMicroappView({
    microAppID: contactsTableID,
    viewFilters: filterParams.viewFilters,
    viewFilterIsMongoQuery: true,
    filterContext: 'your-filter-context'
});

Testing the Example

  1. Create a contacts app with name (text) and age (number) fields

  2. Add some sample contacts with different ages

  3. Add this code widget to a screen that displays the contacts table

  4. Test filtering by different age ranges

  5. Verify that the "Clear" button removes all filters

Last updated