Gallery + 2 drop-down filters

Hi,

Thank you so much for all the information you are all giving. I have a search and two drop-downs to filter a gallery, search and first drop-down work, but the second one (categoria) doesn’t… It doesn’t return any results… Would it be possible for you to help me?

Thanks in advance!

import wixData from “wix-data”;

let lastFilterTitle;
let lastFilterUbicacion;
let lastFilterCategoria;

let debounceTimer;
export function iTitle_keyPress_1(event, $w) {
if (debounceTimer) {
clearTimeout(debounceTimer);
debounceTimer = undefined;
}
debounceTimer = setTimeout(() => {
filter($w(‘#iTitle’).value, lastFilterUbicacion);
}, 200);
}

function filter(title, ciudad, categoria) {
if (lastFilterTitle !== title || lastFilterUbicacion !== ciudad || lastFilterCategoria !== categoria) {
let newFilter = wixData.filter();
if (title)
newFilter = newFilter.contains(‘title’, title);
if (ciudad)
newFilter = newFilter.eq(‘ciudad’, ciudad);
if (categoria)
newFilter = newFilter.eq(‘categoria’, categoria);
$w(‘#dataset1’).setFilter(newFilter);
lastFilterTitle = title;
lastFilterUbicacion = ciudad;
lastFilterCategoria = categoria;
}

}

export function iCity_change_1(event, $w) {
filter(lastFilterTitle, $w(‘#iCity’).value);
}

export function dropdown1_change(event, $w) {
filter(‘categoria’, $w(‘#dropdown1’).value);
}

Hi Andrew,

Welcome to the Wix Code forums.

How do you want the filtering to work? Are both dropdown selections used together to filter the collection? Is the second dropdown dependent on the first? How is this supposed to work?

Thanks,

Yisrael

Hi Yisrael,

Thanks for your reply! I don’t want them to work as cascading or dependent, but yes to filter together if both are used.

Thanks,

Hi Andrew,

What you need is a query that checks for all three at once. Something like this:

let searchValue = $w("#input1").text;
let city = $w("#cityDropdown").value;
let category = $w("#categoryDropdown").value;

wixData.query("collection")
  .contains("title", searchValue)
  .contains("city", city)
  .contains("category", category)
  .find()
  .then( (results) => {
 let items = results.items;  // array of results
  } )
  .catch( (error) => {
 let errorMsg = error.message;
 let code = error.code;
  } );

I hope this helps.

Yisrael

Great, thanks!

Hi Yisrael,
I have a similar task to that of Andrew, and sadly am not able to adapt your code to my project. Could I hire you? (o:
thanks!
Garrett garrettnorvell@gmail.com
https://www.whitecoatwork.com/docjobs2

You can check out the WixArena - it’s a hub where you can look for Wix Code (and other) experts for hire.

Thanks for the recommendation, Yisrael. I tried it and nobody was able to help, but I’ll happily try it again (o:

HI Yisrael. Thank you for this. I am just unsure now how to set this to my dropdown to trigger it onchange?

EDIT* Got it thank you! Although not sure how to reset back to ALL? My first value is ALL, so would it be something like:

if (($w(“#location”).value === ‘All’)) {
$w(“#location”).selectedIndex === undefined;
}

This doesn’t work tho…

Hi TailoredWebDesign .

Would it be possible for you to paste your code here?
Thank you!

Hi @Tailored,

In your if statement, you are checking if set to All which means it is already set to All . If you want to set to All, then set the selectedIndex to the index for the All option.

Thanks yisrael. But how does it know that All means to basically remove filter?

You tell it. Take a look under wix-dataset.setFilter , and you will see that in order to clear a filter, you just set it to nothing:

$w("#dataset").setFilter( wixData.filter() );

So, when All is selected, you run the above code.

Yisrael

hmm ok but I don’t want it to reset the whole repeater, because other filters might still be ‘running’?

Would this code still apply?

My work around code which does kind of work is this:

let value = $w(‘#location’).value;
if (value === ‘All’) {
$w(‘#box3’).hide();
wixData.query(“Properties”)
.contains(“location”, “Queensland”)
.find()
.then((results) => {
$w(‘#repeater2’).data = results.items;

But it has a couple of second delay. If you want please take a look at my page so you can see it working:

https://pete092.wixsite.com/book-the-best/copy-of-queensland

I don’t understand what you’re doing in the code. If All is selected, you hide a box and then select Queensland . Where is the rest of the filter? Does All mean Queensland? What’s in the box ?

Simply put, the best thing would be to “build” a new filter each time there is a change in one of the selected options. So that if you select All for one of the options, that part of the filter would be ignored since there is nothing to filter. The other options however would still be part of the filter. If all three dropdowns have All selected, then the filter would be empty and would clear the dataset’s filter.

Sorry I am not very adanced with coding. Did you happen to look at my page?

Basically, when someone selects a location (say Hamilton Island) then they decide they want to select all the locations again (All locations) it needs to reset just that filter and keep the other options they have made. I think I am on the right track, so should I just add

let value = $w(’ #location ').value;
if (value === ‘All’) {
$w(" #dataset 1").setFilter( wixData.filter() );}

and this will just remove this particular filter?

A filter includes the selections from all three dropdowns. Something like this:

wixData.query("Properties")
	.contains("field1", <value from dropdown1>)
        .contains("field2", <value from dropdown2>)
        .contains("field3", <value from dropdown3>)
	.find()
	.then((results) => {
		$w('#repeater2').data = results.items;
        )};

The above example builds a filter using values from all three dropdowns.

Now, in the case that you’ve selected All from dropdown2, then you would end up with something like this:

wixData.query("Properties")
	.contains("field1", <value from dropdown1>)
        .contains("field3", <value from dropdown3>)
	.find()
	.then((results) => {
		$w('#repeater2').data = results.items;
        )};

Note that the above filter does not contain a filter for dropdown2 since there is nothing to filter since dropdown2 has All selected a its option.

Thanks Yisrael, and hope you are having a beer!!

I feel like I have this already, I have separate code for each dropdown as below:

import wixData from ‘wix-data’;
import wixWindow from ‘wix-window’;

export function location_change() {
wixData.query(“Properties”)
.contains(“location”, “Queensland”)
.contains(“subLocation”, $w(‘#location’).value)
.contains(“type”, $w(‘#Type’).value)
.ge(“guests”, Number($w(“#Guests”).value))
.ge(“bedrooms”, Number($w(“#Rooms”).value))
.ge(“bathrooms”, Number($w(“#Bathrooms”).value))
.find()
.then((results) => {
$w(‘#repeater2’).data = results.items;
if (results.items.length === 0) {
$w(‘#box3’).show();
} else $w(‘#box3’).hide();
}

export function Type_change() {
wixData.query(“Properties”)
.contains(“location”, “Queensland”)
.contains(“subLocation”, $w(‘#location’).value)
.contains(“type”, $w(‘#Type’).value)
.ge(“guests”, Number($w(“#Guests”).value))
.ge(“bedrooms”, Number($w(“#Rooms”).value))
.ge(“bathrooms”, Number($w(“#Bathrooms”).value))
.find()
.then((results) => {
$w(‘#repeater2’).data = results.items;
if (results.items.length === 0) {
$w(‘#box3’).show();
} else $w(‘#box3’).hide();
}
})
.catch((error) => {
let errorMsg = error.message;
let code = error.code;
});
}

export function Guests_change(event, $w) {
wixData.query(“Properties”)
.contains(“location”, “Queensland”)
.contains(“subLocation”, $w(‘#location’).value)
.contains(“type”, $w(‘#Type’).value)
.ge(“guests”, Number($w(“#Guests”).value))
.ge(“bedrooms”, Number($w(“#Rooms”).value))
.ge(“bathrooms”, Number($w(“#Bathrooms”).value))
.find()
.then((results) => {
$w(‘#repeater2’).data = results.items;
if (results.items.length === 0) {
$w(‘#box3’).show();
} else $w(‘#box3’).hide();
})
.catch((error) => {
let errorMsg = error.message;
let code = error.code;
});
}

export function Rooms_change(event, $w) {
wixData.query(“Properties”)
.contains(“location”, “Queensland”)
.contains(“subLocation”, $w(‘#location’).value)
.contains(“type”, $w(‘#Type’).value)
.ge(“guests”, Number($w(“#Guests”).value))
.ge(“bedrooms”, Number($w(“#Rooms”).value))
.ge(“bathrooms”, Number($w(“#Bathrooms”).value))
.find()
.then((results) => {
$w(‘#repeater2’).data = results.items;
if (results.items.length === 0) {
$w(‘#box3’).show();
} else $w(‘#box3’).hide();
})
.catch((error) => {
let errorMsg = error.message;
let code = error.code;
});
}

export function Bathrooms_change(event, $w) {
wixData.query(“Properties”)
.contains(“location”, “Queensland”)
.contains(“subLocation”, $w(‘#location’).value)
.contains(“type”, $w(‘#Type’).value)
.ge(“guests”, Number($w(“#Guests”).value))
.ge(“bedrooms”, Number($w(“#Rooms”).value))
.ge(“bathrooms”, Number($w(“#Bathrooms”).value))
.find()
.then((results) => {
$w(‘#repeater2’).data = results.items;
if (results.items.length === 0) {
$w(‘#box3’).show();
} else $w(‘#box3’).hide();
})
.catch((error) => {
let errorMsg = error.message;
let code = error.code;
});
}

I am just not sure what to add to make the All work sorry…Feeling very stupid!!

Or do I just rewrite the above with your code example?

It’s not really a problem creating a query for each dropdown’s onChange() . However, you just have to be able to handle the All option. If one of the dropdowns has All selected, then no value from that dropdown should be added to the filter. Just build a filter that doesn’t have a .contains() for that dropdown (as in my previous example).

OK so for the location_change dropdown, would I just add this if statement per your instructions?:

let location = $w(‘#location’).value;
if (type === ‘All’) {
wixData.query(“Properties”)
contains(“location”, “Queensland”) //this gives only Queensland results as I have other locations
//.contains(“subLocation”, $w(’ #location ‘).value) // remove this as per your instructions
.contains(“type”, $w(’ #Type ‘).value)
.ge(“guests”, Number($w(" #Guests “).value))
.ge(“bedrooms”, Number($w(” #Rooms “).value))
.ge(“bathrooms”, Number($w(” #Bathrooms ").value))
.find()
.then((results) => {
$w(’#repeater2’).data = results.items;
});

Then similar for all the _change codes? ie type

let type = $w(‘#Type’).value;
if (type === ‘All’) {
wixData.query(“Properties”)
contains(“location”, “Queensland”) //this gives only Queensland results as I have other locations
//.contains(“subLocation”, $w(’ #location ‘).value) // remove this as per your instructions
//.contains(“type”, $w(’ #Type ‘).value)//remove for all
.ge(“guests”, Number($w(" #Guests “).value))
.ge(“bedrooms”, Number($w(” #Rooms “).value))
.ge(“bathrooms”, Number($w(” #Bathrooms ").value))
.find()
.then((results) => {
$w(’#repeater2’).data = results.items;
});

Ok this works, but it shows my “there are no results” box, then after a delay it shows the correct results. My no results code is:

if (results.items.length === 0) {
$w(‘#box3’).show();
} else $w(‘#box3’).hide();

Is there any way to speed this process up as it doesn’t look very professional…Thank you so much for all your time by the way!!!