Filter by multiple fields

I’m trying to create a resource hub where users filter a collection by location and type. I have everything in a collection and both the location field and type field are tags because many of the resources belong in multiple categories. I started off trying to connect it with drop down user inputs but the dataset would not let me connect when the field was set to a tag field.

So now I am trying selection tags but I can’t figure out how to get the collection to filter based on 2 different fields. Below is my code, any help would be great. Alternatively if anyone knows how to get the drop down user inputs working for this, that would be ideal because it looks much cleaner.

import wixData from 'wix-data';

const collectionName = 'MentalHealthResources';
const fieldToFilterByInCollection = 'location''type';

$w.onReady(function () {

    setRepeatedItemsInRepeater();
    loadDataToRepeater();

    $w('#locationtags').onChange((event) => {
 const selectedTags = $w('#locationtags').value;
        loadDataToRepeater(selectedTags);

    $w('#category').onChange((event) => {
 const selectedTags = $w('#category').value;
        loadDataToRepeater(selectedTags);
    })
});

function loadDataToRepeater(selectedCategories = []) {

 let dataQuery = wixData.query(collectionName);

 if (selectedCategories.length > 0) {
        dataQuery = dataQuery.hasAll(fieldToFilterByInCollection, selectedCategories);
    }

    dataQuery
        .find()
        .then(results => {
 const itemsReadyForRepeater = results.items;
            $w('#repeater').data = itemsReadyForRepeater;
 const isRepeaterEmpty = itemsReadyForRepeater.length === 0

 if (isRepeaterEmpty) {
                $w('#noResultsFound').show();
            } else {
                $w('#noResultsFound').hide();
            }
        })
}

function setRepeatedItemsInRepeater() {

    $w('#repeater').onItemReady(($item, itemData) => {
        $item('#name').src = itemData.name;
        $item('#description').tooltip = itemData.description;
        $item('#button').text = itemData.button

    })
}

$w.onReady(function () {
 // Write your JavaScript here

 // To select an element by ID use: $w("#elementID")

 // Click "Preview" to run your code
});

It’s not clear from your code what you’re trying to do.
But this is defiantly wrong:

const fieldToFilterByInCollection = 'location''type';

Yeah that part is giving me an error because I don’t know the correct syntax to filter by multiple fields in the collection or if it’s even possible.

This is the code I got from another post that worked when I had only 1 selection tag (location) set up. Example: When I click on the “Canada” selection tag button, then the repeater filters to show only results that are located in Canada. I want to add another separate filter that can look for type of service as well. Example: Click “mental health” for one filter and “Canada” in another filter to show only items in the collection that are mental health services located in Canada.

import wixData from 'wix-data';

const collectionName = 'MentalHealthResources';
const fieldToFilterByInCollection = 'location';


$w.onReady(function () {

    setRepeatedItemsInRepeater();
    loadDataToRepeater();

    $w('#locationtags').onChange((event) => {
 const selectedTags = $w('#locationtags').value;
        loadDataToRepeater(selectedTags);
    })
});

function loadDataToRepeater(selectedCategories = []) {

 let dataQuery = wixData.query(collectionName);

 if (selectedCategories.length > 0) {
        dataQuery = dataQuery.hasAll(fieldToFilterByInCollection, selectedCategories);
    }

    dataQuery
        .find()
        .then(results => {
 const itemsReadyForRepeater = results.items;
            $w('#repeater').data = itemsReadyForRepeater;
 const isRepeaterEmpty = itemsReadyForRepeater.length === 0

 if (isRepeaterEmpty) {
                $w('#noResultsFound').show();
            } else {
                $w('#noResultsFound').hide();
            }
        })
}

function setRepeatedItemsInRepeater() {

    $w('#repeater').onItemReady(($item, itemData) => {
        $item('#name').src = itemData.name;
        $item('#description').tooltip = itemData.description;
        $item('#button').text = itemData.button

    })
}

@megansauer

Sorry. I’m not sure how can you use selectedTags for multiple values of different fields.
I think each selectedTags element should represent a specific field.
Please elaborate.
[EDITED]

@jonatandor35 I’m not really sure how else to explain it.

I have a collection for Mental Health Resources.

One field is called “Location.” This field is set to “tags” and I have several tags per item (such as Canada, Ontario, Toronto etc.)

Another field is called “type.” This field is also set to tags and also has several tags per item (such as mental health, depression, anxiety etc.)

On my page, I have a repeater which is connected to the collection. I want to have it so that the user can filter this collection based on both “location” and “type”

I added an input called “selection tags.” I made those selection tags match all of the tags that I used for the “location” field in the collection and connected the selection tags to the repeater through the second block of code I sent you. This worked (meaning when I clicked “Toronto,” the repeater filtered the items to only show resources that had the “Toronto” tag in my collection.

However, I ALSO want to filter for “type.” So I added a SECOND input for “selection tags” to the page and I made those selection tags match the tags that I used for “type” in my collection. The problem I am having is I don’t know how to adjust my code to recognize BOTH selection tags for filtering.

You can perhaps use checkboxes.

@russian-dima Could you show me an example of what that would look like in the code?

@megansauer
Well, i’ll show you the right part of my CODE, wich is what you will need to get it to work…

I hope you are able to break the code down and understand it.

 //Filter-C-Boxes-------------------------------------------
 for (let a=0; a < CBoxes.length; a++) {
 //      console.log("MEMcboxes[a] = ", MEMcboxes[a])
 if (MEMcboxes[a]!==undefined && MEMcboxes[a]!=="undefined" && MEMcboxes[a]!==""){
 for (let b=0; b < MEMcboxes[a].length; b++) {
 //              console.log("MEM-AB:",MEMcboxes[a][b])
 if (MEMcboxes[a][b]!==undefined && MEMcboxes[a][b]!=="undefined" && MEMcboxes[a][b]!==""){  
                        query = await query.eq(CBoxes[a], MEMcboxes[a][b])  
                    }
 else {  }
                }
            }
 else {  }
        }
        query.find()
        .then(async res => {
            itemDATA = await res.items          
            result_COUNTER(res.length, itemDATA)
        })

And here you see the CODE in action…
https://www.media-junkie.com/pflegeservice

It’s the appearing Check-Box-Menu, which automaticaly fades in when a TAG-FIELD exsist in your DATABASE. If in your DATABASE no TAG-FIELD exist no drop-down-menu expands.

Switch between the given PRESET-DATABASES (1-3 + main-preset) and you will recognize it’s function.

You can also play around and setup the DB-PRESETs like you want. All included DATABASES in this example you will find when you click on DATABASES.

Take a look which DATA-Collections and their REFERENCE-FIELDS are given in this example. Chenge the PRESET-SETTINGS and take a look what happens.

The Settings-Menu you will find here…

This example works totaly —> DATASET-FREE!

The used element in this example are “Check-Box-Groups” …

…which represents the values of TAG-FIELDS in your DB.

Surely it would also be possible to use “Selection-Tags” instead of “Check-Box-Groups” to show the DATA from DB.