How to create a checkbox user input filter?

Hi, can someone help? The idea is to use a repeater to give an options to a dropdown through a collapsible box (so it creates a filter by checkbox). The code itself seems okay but not quite sure,
Idea came from: https://www.wix.com/corvid/forum/community-discussion/solved-filter-dataset-from-group-check-boxes-and-update-a-dropdown-box-with-that-filter


Heres the code that i’ve used on the page:

import wixData from 'wix-data';

//Exercise filter
export function FilterByDrink() {
 let alcohol = [];
 let mixer = [];
 let garnish = [];

 // Get the indexes of all the checkboxes checked in that group
 let selectedalcohol = $w("#AlcoholCheckboxGroup").selectedIndices;
 let selectedmixer = $w("#MixerCheckboxGroup").selectedIndices;
 let selectedgarnish = $w("#GarnishCheckboxGroup").selectedIndices;
 let filter = wixData.filter();

 // Now, loop through the checked items and add each field to the array and apply filter
 if (selectedalcohol.length > 0) {
 for (var i = 0; i < selectedalcohol.length; i++) {
            alcohol.push($w('#AlcoholCheckboxGroup').options[selectedalcohol[i]].value);
        }
    }
 if (alcohol.length > 0) {
        filter = filter.hasSome("AlcoholTags", alcohol);
    }

 if (selectedmixer.length > 0) {
 for (var i2 = 0; i2 < selectedmixer.length; i2++) {
            mixer.push($w('#MixerCheckboxGroup').options[selectedmixer[i2]].value);
        }
    }
 if (mixer.length > 0) {
        filter = filter.hasSome("MixerTags", mixer);
    }

 if (selectedgarnish.length > 0) {
 for (var i3 = 0; i3 < selectedgarnish.length; i3++) {
            garnish.push($w('#GarnishCheckboxGroup').options[selectedgarnish[i3]].value);
        }
    }
 if (garnish.length > 0) {
        filter = filter.hasSome("GarnishTags", garnish);
    }

    $w("#dataset1").setFilter(filter)
        .then(() => {
            console.log("count after", $w("#dataset1").getTotalCount());
            $w("#numberOfdrinksavailable").value = "Number of drinks available" + " " + $w("#dataset1").getTotalCount()

        })

        .catch((err) => {
            console.log(err);
        });
}

// Filetr each time you click a check box in a group

export function AlcoholCheckboxGroup_change(event) {
 //Add your code for this event here: 
    FilterByDrink();
}

export function MixerCheckboxGroup_change(event) {
 //Add your code for this event here: 
    FilterByDrink();
}

export function GarnishCheckboxGroup_change(event) {
 //Add your code for this event here: 
    FilterByDrink();
}

export function AlcoholTitleBox_click_1(event) {
 //Add your code for this event here: 
 if ($w('#AlcoholBox').collapsed) {
        $w('#AlcoholBox').expand();
    } else
        $w('#AlcoholBox').collapse();

}

export function MixerTitleBox_click(event) {
 //Add your code for this event here: 

 if ($w('#MixerBox').collapsed) {
        $w('#MixerBox').expand();
    } else
        $w('#MixerBox').collapse();
}

export function GarnishTitleBox_click(event) {
 //Add your code for this event here: 
 if ($w('#GarnishBox').collapsed) {
        $w('#GarnishBox').expand();
    } else
        $w('#GarnishBox').collapse();
}

If someone can help, would be really appreciated.
#checkbox #checkboxfilter #userinput #filter #dropdown #tickbox #

Hi Pav :raised_hand_with_fingers_splayed:

I suggest that you create an onChange() event handler for each checkbox and run a function that will check which checkboxs are checked and apply the filter accordingly.

Let’s assume that you have 3 checkboxs, you can scale them easily, we’ll create a for…loop that will create the onChange() event handler for each checkbox to save time and to make our code shorter and easier to understand.

let numberOfCheckBoxes = 3;

for (let i = 1; i <= numberOfCheckBoxes; i++) {
    $w(`#checkBox${i}`).onChange(async (event) => {
        await setFilters(); // We'll create this function later
    })
}

Now each of the checkboxes has its own onChange() event handler, next, we need to create the function that will check the checkboxes values and set the filter.

async function setFilters() {
    
    // Check which checkbox is checked and add the checked ones into an array
    let checkedBoxes = [];
    
    for (let i = 0; i < numberOfCheckBoxes; i++) {
        if ($w(`#checkBox${String(i+1)}`).checked) {
            let item = {
                id: #checkBox${String(i+1)},
                boxIndex: i
            }
            
            checkedBoxes.push(item);
        } 
    }
    
    // Now set set the filter
    let totalChecked = checkedBoxes.length;
    if (totalChecked > 0) {
        let filter;       
        
        switch (totalChecked) {
        case 1:
            let firstBox = {
                id: checkedBoxes[0].id,
                index: checkedBoxes[0].boxIndex
            }                          
            filter = wixData.filter()
                .eq(`field${firstBox.index}`, true)
                         
        break;
        
        case 2:
            filter = wixData.filter()
                .eq(`field${checkedBoxes[0].boxIndex}`, true)
                .eq(`field${checkedBoxes[1].boxIndex}`, true)              
            
        break;
        
        case 3:
            filter = wixData.filter()
                .eq(`field${checkedBoxes[0].boxIndex}`, true)
                .eq(`field${checkedBoxes[1].boxIndex}`, true)
                .eq(`field${checkedBoxes[2].boxIndex}`, true)
            }
        break;
        /* You can scale to as much as you want
        and add as much cases as you want
        */        
        } 
        
        $w('#dataset1').setFilter(filter);
    } else {
        // Reset the filter if no checkbox is checked
        $w('#dataset1').setFilter(wixData.filter());
    }
}

I know it’s a bit too long, but it’s the shortest I could made.
Hope you found it useful.

Ahmad

Hi Ahmad!
Firstly thank you for your help! I am working with a group checkbox rather than individual ones as there is a lot of values to enter, will this still be working the same or will this be a tad different?
Are you able to just explain on a few things at all? So i’ve added the code to the page and tried to make it work, but getting a bit stuck on certain parts. From the first code snippet it keeps coming up with an error that a checkbox is not a valid sector but on the page the group checkbox is called AlcoholCheckboxGroup. I tried to search it up but the results were just saying that the element is not on the page so it cant be referenced.


The same issue on the second part of the code along with a slight confusion on
what string to attach to it to make it work. Please see code snippet below:

async function AlcoholFilter() {
 
 // Check which checkbox is checked and add the checked ones into an array
 let checkedBoxes = [];
 
 for (let i = 0; i < numberOfCheckBoxes; i++) {
 if ($w('#AlcoholCheckboxGroup${String(i+1)}').checked) {
 let item = {
                id: '#AlcoholCheckboxGroup${String(i+1)}',
                boxIndex: i
            }
 
            checkedBoxes.push(item);
        } 
    }
 
 // Now set set the filter
 let totalChecked = checkedBoxes.length;
 if (totalChecked > 0) {
 let filter;       
 
 switch (totalChecked) {
 case 1:
 let firstBox = {
                id: checkedBoxes[0].id,
                index: checkedBoxes[0].boxIndex
            }                          
            filter = wixData.filter(
                .eq(`field${firstBox.index}`, true)
            )             
 break;
 
 case 2:
            filter = wixData.filter(
                .eq(`field${checkedBoxes[0].boxIndex}`, true)
                .eq(`field${checkedBoxes[1].boxIndex}`, true)              
            )
 break;
 
 case 3:
            filter = wixData.filter(
                .eq(`field${checkedBoxes[0].boxIndex}`, true)
                .eq(`field${checkedBoxes[1].boxIndex}`, true)
                .eq(`field${checkedBoxes[2].boxIndex}`, true)
            }
 break;
 /* You can scale to as much as you want
        and add as much cases as you want
        */ 
        } 
 
        $w('#dataset1').setFilter(filter);
    } else {
 // Reset the filter if no checkbox is checked
        $w('#dataset1').setFilter(wixData.filter());
    }
}

On the case 1 the .eq the error code keeps coming up as unexpected token.


Hope to hear from you soon!

Hi Pav :raised_hand_with_fingers_splayed:

In the first picture you attached (line 21), you’re mixing up the static event handler syntax with the dynamic event handler.

Read this answer on question " Dynamic events handlers vs static ones? ".

Regarding the parsing error that you get, it was an error in my code, (sorry I did write it here without proofing), but I fixed it.

Can you try it now?
Also, can you provide me with your site URL where the page is?