Thank you in advance for helping me out with this. I have been searching and trying out codes from examples and the forum for 2 straight weeks without success. I am looking to build the same type of product filter similar to the Wix Store filter. The reason I opt out on Wix store is due to the lack of customization for its product pages. Really appreciate any help on this. Thank you again.
Currently my filter has two checkboxGroup with 5 to 6 values in each. Each checkboxGroup is set to query value from two individual Tag fields in the same database. From one contributors example, I was able to get closer to what I need and was able to query multiple items from one checkboxGroup. But once I select a check box from the second checkboxGroup the query would only match the second checkboxGroup and disregard the first checkboxGroup
The code for that looks like this
import wixData from 'wix-data';
const databaseName = 'StoneType';
const databaseField = 'stoneCategory';
const databaseField2 = 'stoneColor';
$w.onReady(function () {
$w('#checkboxGroup1').onChange((event) => {
addItemstoRepeater($w('#checkboxGroup1').value);
});
$w('#checkboxGroup2').onChange((event) => {
addItemstoRepeater($w('#checkboxGroup2').value);
});
$w('#clearButton').onClick((event) => {
$w("#checkboxGroup1").value = undefined;
$w("#checkboxGroup2").value = undefined;
addItemstoRepeater()
});
});
//populates repeater
function addItemstoRepeater(selectedOption = []) {
let dataQuery = wixData.query(databaseName);
if (selectedOption.length > 0) {
dataQuery = dataQuery.hasSome(databaseField2, selectedOption)
.or (dataQuery.hasSome(databaseField, selectedOption));
}
dataQuery
.find()
.then(results => {
const filtereditemsReady = results.items;
$w('#repeater1').data = filtereditemsReady;
})
}
Then after checking through the forum I found Velo Ninja's code and tried it out. I was able to get closer to what I am looking for but the filter would only allow one check box to be selected from each checkboxGroup. When more than one is selected the whole checkbox disappears. Also the onclick reset function stops working with the code.
import wixData from 'wix-data';
const databaseName = 'StoneType';
const databaseField = 'stoneCategory';
const databaseField2 = 'stoneColor';
$w.onReady(function () {
$w('#checkboxGroup1').onChange((event) => {
addItemstoRepeater();
});
$w('#checkboxGroup2').onChange((event) => {
addItemstoRepeater();
});
$w('#clearButton').onClick((event) => {
$w("#checkboxGroup1").value = undefined;
$w("#checkboxGroup2").value = undefined;
addItemstoRepeater()
});
});
function addItemstoRepeater(){
let dataQuery = wixData.query(databaseName);
let item1, item2
if ($w('#checkboxGroup1').value[0]!==undefined) {item1 = $w('#checkboxGroup1').value}
if (item1!==undefined){
for (var i=0; i < item1.length; i++) {
dataQuery = dataQuery.hasSome(databaseField, item1[i])
}
}
if ($w('#checkboxGroup2').value[0]!==undefined) {item2 = $w('#checkboxGroup2').value}
if (item2!==undefined){
for (var a=0; a < item2.length; a++) {
dataQuery = dataQuery.contains(databaseField2, item2[a])
}
}
dataQuery
.find()
.then(results => {
const filtereditemsReady = results.items;
$w('#repeater1').data = filtereditemsReady;
})
}
This is what my dataBase looks like
This is what my filter looks like
So i hope you tried to study all given tips and here it comes....
I think, this is what you were looking for....
import wixData from 'wix-data'; //-------- USER-INTERFACE ------------------------------------------------- var DBFIELDS = [] var DATABASE = "Team" var DBLIMIT = 1000 var REPEATER = "repeater1" //----------------------------- DBFIELDS[0] = "sprache"; //<---simple adding new TAGS-DATAFIELD here --> 1-st. CBG DBFIELDS[1] = "bundesland"; //<---simple adding new TAGS-DATAFIELD here --> 2-nd. CBG //-------- USER-INTERFACE ------------------------------------------------- $w.onReady(()=>{ wixData.query(DATABASE) .limit(DBLIMIT) .find() .then(async(results)=>{console.log(results.items); let ITEMS = results.items getUniqueCBGtitles(ITEMS, DBFIELDS[0], "CBG1"); //<--- simple adding new CBG here getUniqueCBGtitles(ITEMS, DBFIELDS[1], "CBG2"); //<--- simple adding new CBG here }); $w('#'+REPEATER).onItemReady(async($item, itemData, index) => { console.log(itemData.sprache) $item("#imgMain").src = itemData.pic $item("#txtFirstname").text = itemData.vorname $item("#txtLastname").text = itemData.name }); $w('#CBG1, #CBG2').onChange(()=>{ populateRepeater($w('#CBG1').value, $w('#CBG2').value) }); $w('#btnClear').onClick(()=> { $w("#CBG1, #CBG2").value = undefined; populateRepeater(); }); }); function populateRepeater(selectedOption1, selectedOption2) { let dataQuery = wixData.query(DATABASE); if (selectedOption1.length>0){dataQuery = dataQuery.hasAll(DBFIELDS[0], selectedOption1);} if (selectedOption2.length>0){dataQuery = dataQuery.hasAll(DBFIELDS[1], selectedOption2);} dataQuery.find() .then(results => { const filteredItems = results.items; $w('#'+REPEATER).data = filteredItems; }) } async function getUniqueCBGtitles(ITEMS, DBFIELD, CBG){ let uniqueTitles = await [...new Set(getxxx(ITEMS).flat())]; $w('#'+CBG).options = buildOptions(uniqueTitles); function getxxx(items) {const titlesOnly=items.map(item => item[DBFIELD]); return [...new Set(titlesOnly)];} function buildOptions(item) {return item.map(item => {return {label:item, value:item};});} }
An working example can be found here....
https://www.media-junkie.com/checkbox-filter
EDIT:
You will have to add a hasSome-filtering functionality if just 1 of 2 CBGs is selected.
Code some kind of a SWITCH (using if-else-queries).
If just one CBG is checked ---> switch to ---> "hasSome"
else ---> switch to ---> "hasAll"
Ok, like i always do --> starting from SCRATCH!
The first thing what i would do in your situation, is to create a function which would FILL ALL MY CBGs (CheckBoxGroups) ---> AUTOMATICALY <--- directly out from my chosen DB.
"Velo-Ninja, WhatTheHell do you mean?"đ
Take a look here....(this example is related to the following DATABASE....)
https://www.media-junkie.com/databases
import wixData from 'wix-data'; //-------- USER-INTERFACE ------------------------------------------------- var DBFIELDS = [] var DATABASE = "Team" var DBLIMIT = 1000 //----------------------------- DBFIELDS[0] = "sprache"; //<---simple adding new (TAG)-DATAFIELD here --> 1-st. CBG DBFIELDS[1] = "bundesland"; //<---simple adding new (TAG)-DATAFIELD here --> 2-nd. CBG //-------- USER-INTERFACE ------------------------------------------------- $w.onReady(()=>{ wixData.query(DATABASE) .limit(DBLIMIT) .find() .then(async(results)=>{console.log(results.items); let ITEMS = results.items get_CBGoptions(ITEMS, DBFIELDS[0], "CBG1"); //<---simple adding new CBG here get_CBGoptions(ITEMS, DBFIELDS[1], "CBG2"); //<---simple adding new CBG here }); }); //----------- DO NOT TOUCH THIS FUNCTION !!! ------------------------------------- async function get_CBGoptions(ITEMS, DBFIELD, CBG){ let uniqueTitles = await [...new Set(getxxx(ITEMS).flat())]; $w('#'+CBG).options = buildOptions(uniqueTitles); function getxxx(items) {const titlesOnly=items.map(item => item[DBFIELD]); return [...new Set(titlesOnly)];} function buildOptions(item) {return item.map(item => {return {label:item, value:item};});} } //----------- DO NOT TOUCH THIS FUNCTION !!! -------------------------------------
OK! First part of your PROJECT should be done!
But what is it for?
You surely have setted-up your CBG-Options, either directly in the Editor-Options, or you have connected the CBG-Options via a DATASET with a Collection to populate your CBGs with options. RIGHT ???
Or you even have a hardcoding for example like something like this one (either directly on your page-code-section, or in a separate public-js-file).....
$w('#CB1').options = [ {"label": "Burgenland", "value": "Burgenland"}, {"label": "KÀrnten", "value": "KÀrnten"}, {"label": "Niederösterreich", "value": "Niederösterreich"}, {"label": "Oberösterreich", "value": "Oberösterreich"}, {"label": "Salzburg", "value": "Salzburg"}, {"label": "Steiermark", "value": "Steiermark"}, {"label": "Tirol", "value": "Tirol"}, {"label": "Vorarlberg", "value": "Vorarlberg"}, {"label": "Wien", "value": "Wien"}, ]; //Options for CheckBox-2------------------------------ $w('#CB2').options = [ {"label": "Englisch", "value": "Englisch"}, {"label": "Estnisch", "value": "Estnisch"}, {"label": "Finnisch", "value": "Finnisch"}, {"label": "Französisch", "value": "Französisch"}, {"label": "Deutsch", "value": "Deutsch"}, {"label": "Italienisch", "value": "Italienisch"}, {"label": "RumÀnisch", "value": "RumÀnisch"}, {"label": "Russisch", "value": "Russisch"}, {"label": "Schwedisch", "value": "Schwedisch"}, {"label": "Spanisch", "value": "Spanisch"}, ];
...to populate your CBGs (DropDowns the same).
And EVERY-TIME you perhaps add a new ITEM in your DB, you also have to add a new VALUE in your CODE ---> MANUALY !!!
You surely do NOT want to do this all the time!
So your first progress will be to populate the CBG-options -> AUTOMATICALY!
How to do the same for DropDowns, you will find here....
https://www.wix.com/velo/forum/coding-with-velo/want-to-call-multiple-items-from-database-according-to-user-selection-can-you-help
Ok, back to you, let's see what we can do đ
I still did not find enough time to inspect your code.
In the meanwhile, you perhaps take a look onto this one...
import wixData from 'wix-data'; var DATASET = "#dataset1" //--------------------------------------- var REFERENCE0 = "datafield1" // modify to your own DATAFIELD-ID! var REFERENCE1 = "datafield2" //modify further DATAFIELD here var REFERENCE2 = "datafield3" //modify further DATAFIELD here var REFERENCE3 = "datafield4" //modify further DATAFIELD here export function start_SearchEngine(VALUE) {console.log("Search-Engine running...") let filter = wixData.filter() filter=filter.contains(REFERENCE0, VALUE) .or(filter.contains(REFERENCE1, VALUE)) //you can add different logics --> hasSome()... .or(filter.contains(REFERENCE2, VALUE)) //you can add different logics --> between()... .or(filter.eq(REFERENCE3, VALUE)); console.log(filter) $w(DATASET).setFilter(filter) .then(()=>{ let count = $w(DATASET).getTotalCount().toString(); console.log("COUNT = " + count) $w("#count").text = 'Total Products: (' + count + ')'; }) }
Modify all DATAFIELDS by your own.
It is also one of my own used or-filtering engines. Perhaps this one also can be used in your project.
I just tried out the code but myFilter cannot be found, so i added the below line to be able test the code. Not sure if this is correct
let myFilter = []
Then the below happend when I tried to select a check box. I immediately received the following error from the console. "Cannot set property '0' of undefined. "
no changes were applied to the repeater.
@Velo-Ninja
can you help me out again on this
Thank you again.
You can use lodash npm pack and you can create this via looking to this example = https://www.wix.com/velo/example/mega-search
You can add checkboxes as many as you want. The code should do the rest.
Before i can show you the right direction, i want to know if the shown OR-filter is e exactly what you are searching for? Did you do some testings?
Or do you expect another functionality of your filter?
Take a look on this link...
I tried to reconstruct your issue.... ---> Load ---> "DB-Preset-1"
I must be honest, i solved it in my interactive-example in another way.
I did not use ---> "hasSome" (it is ok to use hasSome), but i did it another way.
Your problem will sure be that you are using a kind of AND-FILTERING.
This will be surely the reason why your RESULTS gets lost, when using both CBGs (checkbox-groups).
You can test this little example and use ...
1) ---> AND-FILTERING
2) ---> OR-FILTERING
You will find the SWITCH-OPTIONS here...
Did you read this post here?????
https://www.wix.com/velo/forum/coding-with-velo/want-to-call-multiple-items-from-database-according-to-user-selection-can-you-help
Or the original INTRODUCTING-POST here...
https://www.wix.com/velo/forum/coding-with-velo/database-filtering-and-grouping-including-caching-of-results
You can do much more of your filtering-system.
What you are searching for will be a kind of OR-FILTERING-SYSTEM.
Select-A or Select-C or Select-D ---> [A, C, D] <--- RESULT-ARRAY after choice!