Example: Checkbox Dropdown

#Repeater #Input #Dataset #Filter #Dropdown #Example

Demonstrates

Links for this example

About this example

This is another variation of the Search a Database example . This example creates a Dropdown checkbox menu allowing multiple selection of continents for the search filter. A container box is used to avoid shoving page contents out of the way. See the forum post Hey, you! Repeater! Stop shoving! to see how to do this.

The Dataset filter uses the hasSome() function as an or filter for multiple continents. The filter is only changed and applied if the search and continent selection differs from the previous search. The age code includes a Javascript function, compareArrays() which compares string arrays to determine if the continent selection has been changed.

4 Likes

Hey Yisrael!
Great sample man that can be used in so many scenarios and projects. I would though prefer that the continents and number of them selected gets updated when I tick or untick a checkbox. So I added a onChange event to the checkbox in the repeater like this to make that happen.

export function optionCheckbox_change(event) {
 // Added to make changes happen when you check or uncheck a continent 
 let arrContinents = [];
    $w("#continents").forEachItem(($item, itemData, index) => {
 if ($item('#optionCheckbox').checked) {
 let text = $item("#optionText").text;
            arrContinents.push(text);
        }
    });
    new_filter(lastFilterTitle, arrContinents);
    $w('#numContinentsText').text = arrContinents.length + " continent" + ((arrContinents.length > 1) ? "s " : " ") + "selected.";
}

Else I need to click on the box for the continents to refresh.

3 Likes

I thought about doing, it but as you know, there’s no end to bells and whistles that can be added. So, I left the exercise up to the reader. :wink:

I face problem again after using this tip for my website which is https://shemakesahome.com/ . please help me

So we can help, please explain what you are trying to accomplish and what is happening. Also, describe your code and how you are using it.

Hello Guys! I followed this tutorial and “Example: Search a Database. ( https://goo.gl/Qv2N3U )”
Thank you Yisrael for making these tutorials, I’m very grateful!

I have zero experience in coding, and I tried to follow each step as much as I could.
Now I’m facing 2 problems, and I hope someone could help me… T-T
Thanks in advance!

My website is for tourists to hire a local guide in Japan. I’d like the tourists to select “region” from the dropdown(Problem A), and choose any types of the tours they want from the Dropdown checkbox menu(Problem B).

(Problem A)
Every region I selected it would appear (I use “Kansai” as example), except for “Kanto.”

(Problem B)
Whichever type of tours I selected, the whole repeater of the tours disappeared.
What I’m trying to achieve here is: each tour has more than 1 type (ex: Tour X - Food, Scenery, Temple ; Tour Y - Food, Temple, Electronic goods, Shopping Center), and since the tutorial has only 1 type of “continent,” I figure my codes can’t be right.

*Video demonstrate for (Problem B): https://youtu.be/ukIHLmJ9jds
*My Website URL: https://bonyotaiwan.wixsite.com/bonyojapan/tours
*The code I’m using:

import wixData from "wix-data";

$w.onReady(() => {
  loadRegion();
});

let lastFilterTitle;
let lastFilterRegiontext;
let debounceTimer;
export function iTitle_keyPress(event, $w) {
 if (debounceTimer) {
    clearTimeout(debounceTimer);
    debounceTimer = undefined;
  }
  debounceTimer = setTimeout(() => {
    filter($w('#iTitle').value, lastFilterRegiontext);  
  }, 500);
}


export function iContinent_change(event) {
  filter(lastFilterTitle, $w('#iContinent').value);
}

function filter(title, regiontext) {
 if (lastFilterTitle !== title || lastFilterRegiontext !== regiontext) {
 let newFilter = wixData.filter();
 if (title)
      newFilter = newFilter.contains('articleTitle', title);
 if (regiontext)
      newFilter = newFilter.contains('regiontext', regiontext);
    $w('#dataset1').setFilter(newFilter);   
    lastFilterTitle = title; 
    lastFilterRegiontext = regiontext;
  }
}

function loadRegion() {
  wixData.query('Region')
    .find()
    .then(res => {
 let options = [{"value": '', "label": '全部地區'}];
      options.push(...res.items.map(regiontext => {
 return {"value": regiontext.title, "label": regiontext.title};
      }));
      $w('#iContinent').options = options;
    });

}


// Multiple checkbox



const containsAll = (arr1, arr2) =>
  arr2.every(arr2Item => arr1.includes(arr2Item))
const sameMembers = (arr1, arr2) =>
  containsAll(arr1, arr2) && containsAll(arr2, arr1);
const compareArrays = (arr1, arr2) => {
 if (!Array.isArray(arr1) || !Array.isArray(arr2) || (arr1.length !== arr2.length) )
 return false;
 return sameMembers(arr1, arr2);
}


let lastFilterRecommendation = [];

$w.onReady(() => {
  $w("#tags").onItemReady(($item, itemData, index) => {
 const text1 = $item("#optionText");
    text1.text = itemData.value;
  });
  loadRecommendation();
});


function loadRecommendation() {
  wixData.query('Recommendation')
    .find()
    .then(res => {
      $w("#tags").data = [];
      $w("#tags").collapse();
 let options = [];
 let id = 0;
      options.push(...res.items.map(tag => {
 return { "_id": "" + ++id, "value": tag.title, "label": tag.title };
      }));
      $w('#tags').data = options;
    });
}

export function tagBox_click(event) {
 if ($w('#tags').collapsed === true) {
    $w("#tags").expand();
  } else {
    $w("#tags").collapse();
 let arrRecommendation = [];
    $w("#tags").forEachItem(($item, itemData, index) => {
 if ($item('#optionCheckbox').checked) {
 let text = $item("#optionText").text;
        arrRecommendation.push(text);
      }
    });
    new_filter(lastFilterTitle, arrRecommendation);
     $w('#numTagText').text = "已選擇" +  arrRecommendation.length + "個" ;
  }
}

function new_filter(title, recommendation) {
 let res = compareArrays(recommendation, lastFilterRecommendation);
 if (lastFilterTitle !== title || !res) {
 let newFilter = wixData.filter();
 if (title)
      newFilter = newFilter.contains('title', title);

    newFilter = newFilter.hasSome('tag', recommendation);
    $w('#dataset1').setFilter(newFilter).then(function () {
 let count = $w("#dataset1").getTotalCount();
    });

    lastFilterTitle = title;
    lastFilterRecommendation = recommendation;
  }
}

Hi i have a question , i have make a dropdown filter list. it was working well yesterday but after i have save it it gives me a error in preview mode
On de error its written


i have writen everything as corvid had guide me
hope you can help me


import wixData from "wix-data";

let lastFilterContinents = [];

$w.onReady(() => {
 // handle each suggestion repeater item
    $w("#continents").onItemReady(($item, itemData, index) => {
        $item('#optionCheckbox').onChange(() => {
            filterByCheckboxes()
        })
        $item("#optionText").text = itemData.value;
    });
    loadContinents();
});

function loadContinents() {
    wixData.query('Continents')
        .find()
        .then(results => {
            $w("#continents").data = [];
 // Create and map an array for the dropdown menu options
 let continentDropdownOptions = [];
            continentDropdownOptions.push(...results.items.map(segments => {
 return { "_id": segments._id, "value": segments.title, "label": segments.title };
            }));
            $w('#continents').data = continentDropdownOptions;
        });
}
// Filtering per options checked
function filterByCheckboxes() {
 let continents = [];
    $w("#continents").forEachItem(($item, itemData, index) => {
 if ($item('#optionCheckbox').checked) {
            continents.push($item("#optionText").text);
        }
    });
    filter(continents);
    $w('#numContinentsText').text = `${continents.length} continent${((continents.length > 1) ? "s " : " ")} selected.`;
}
// Collapse or expand the multi-select menu on click
export function continentBox_click(event) {
 if ($w('#continents').collapsed === true) {
        $w("#continents").expand();
    } else {
        $w("#continents").collapse();
    }
}

function filter(continents) {
 let newContinentsFilterCheck = compareArrays(continents, lastFilterContinents);
 if (!newContinentsFilterCheck) {
 let newFilter = wixData.filter();
        newFilter = newFilter.hasSome('segments', continents);
        $w("#dataset2").setFilter(newFilter).then(function () {
 let count = $w("#dataset2").getTotalCount();
        });
        lastFilterContinents = continents;
    }
}

// Code to compare string arrays
// Used to compare the current and previous continent selections
function compareArrays(newFilterArray, lastFilterArray) {
 if (newFilterArray.length !== lastFilterArray.length) { return false } //Checking if the number of items in the filter arrays match
 //Sort both arrays for easy comparison and checking if the items match
 let sortedNewFilterArray = newFilterArray.concat().sort()
 let sortedLastFilterArray = lastFilterArray.concat().sort()
 for (let index in sortedNewFilterArray) {
 if (sortedNewFilterArray[index] !== sortedLastFilterArray[index]) return false
    }
 return true
}


line 54 is $w(“#dataset2”).setFilter(newFilter).then(function () {


i hope you can help me with this

Hi. Looks like the issue is related to preview mode only in Safari.
As a workaround, please use different browser (e.g. Chrome) or try this on a live site. We have notified our developers about this case.
Regards, Aleksander

thank u for your feed back. i also have a question do you know how i can use this code but have multiple repeaters of filters. the have to work togther to creat a filter and a reset button

@yisrael-wix How do we proceed in adding a third filter for another dropdown? I am not good in coding but I think we need to add something in the const expression in the code, another let expression, another function to load it, another click event, and add something in the filter. My question is how do we proceed it in the const expression?

If we want to add another checkbox dropdown, how do we code that? or is that possible? I tried exploring but to no avail.

@yisrael-wix Hello there! I have tried adding the filter into my Directory page but there is something wrong with my code. I have been working this for many weeks now and i really need your help as im new to coding! Here is my website for your inspection: https://marlineluo.wixsite.com/mysite-1/business-matching

I am building a business directory page where i can filter my database by sectors and market specifically with a dropdown multiple checkbox and at the same time featuring the sectors and market as tags in the repeater.

Could you kindly advise on how to solve the points below?

  1. I managed to link the dropdown to a reference dataset (market dataset). But when i click on any filter values, my repeater disappears totally.

  2. How do i combine another similar dropdown filter to a (sector dataset) ?

  3. How to create sector and market “tags” with my current datasets?

Main dataset collection: VC

Reference dataset collection: Market

Reference dataset collection: Sector

Here are the codes i used for this page:


// For full API documentation, including code examples, visit https://wix.to/94BuAAs

import wixData from ‘wix-data’;
let lastFilterMarket = ;
$w.onReady(() => {
// handle each suggestion repeater item
$w(“#market”).onItemReady(($item, itemData, index) => {
$item(‘#optionCheckbox’).onChange(() => {
filterByCheckboxes()
})
$item(“#optionText”).text = itemData.value;
});
loadmarket();
});
function loadmarket() {
wixData.query(‘market’)
.find()
.then(results => {
$w(“#market”).data = ;
// Create and map an array for the dropdown menu options
let marketDropdownOptions = ;
marketDropdownOptions.push(…results.items.map(market => {
return { “_id”: market._id, “value”: market.title, “label”: market.title };
}));
$w(‘#market’).data = marketDropdownOptions
});
}
// Filtering per options checked
function filterByCheckboxes() {
let market = ;
$w(“#market”).forEachItem(($item, itemData, index) => {
if ($item(‘#optionCheckbox’).checked) {
market.push($item(“#optionText”).text);
}
});
filter(market);
$w(‘#numMarketText’).text = ${market.length} market${((market.length > 1) ? "s " : " ")} selected.;
}
export function optionCheckbox_change(event) {
// Added to make changes happen when you check or uncheck a continent
let market = ;
$w(“#market”).forEachItem(($item, itemData, index) => {
if ($item(‘#optionCheckbox’).checked) {
let text = $item(“#optionText”).text;
market.push(text);
}
});
filter(lastFilterMarket, market);
$w(‘#numMarketText’).text = market.length + " market" + ((market.length > 1) ? “s " : " “) + “selected.”;
}
// Collapse or expand the multi-select menu on click
export function marketBox_click(event) {
if ($w(‘#market’).collapsed === true ) {
$w(”#market”).expand();
} else {
$w(“#market”).collapse();
}
}
function filter(market) {
let newMarketFilterCheck = compareArrays(market, lastFilterMarket);
if (!newMarketFilterCheck) {
let newFilter = wixData.filter();
newFilter = newFilter.hasSome(‘market’, market );
$w(‘#dataset1’).setFilter(newFilter).then( function () {
let count = $w(“#dataset1”).getTotalCount();
});
lastFilterMarket = market;
}
}
// Code to compare string arrays
// Used to compare the current and previous continent selections
function compareArrays(newFilterArray, lastFilterArray) {
if (newFilterArray.length !== lastFilterArray.length) { return false } //Checking if the number of items in the filter arrays match
//Sort both arrays for easy comparison and checking if the items match
let sortedNewFilterArray = newFilterArray.concat().sort()
let sortedLastFilterArray = lastFilterArray.concat().sort()
for ( let index in sortedNewFilterArray) {
if (sortedNewFilterArray[index] !== sortedLastFilterArray[index]) return false
}
return true
}


Looking forward to your rescue!! Thank you :slight_smile: