Use of .OR

Using the code from this post, https://www.wix.com/velo/forum/tips-tutorials-examples/how-to-create-a-search-for-your-database, I am trying to filter more than one keyfield, so one way is adding another .contain and using .OR…

I found one post where .OR is used with two .contains, but in a query, not with ( $w ( ‘#dataset1’ ). setFilter ( wixData . filter(). That code is really clear, but I just don’t get how to extrapolate to mine

Writen as it is now, my code would just take the first filter

Help would be great

// API Reference: https://www.wix.com/velo/reference/api-overview/introduction
// “Hello, World!” Example: https://learn-code.wix.com/en/article/1-hello-world

import wixData from "wix-data";

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

let debounceTimer;

export function input1_keyPress(event) {
 if (debounceTimer) {
    clearTimeout(debounceTimer);
    debounceTimer = undefined;
 }
    debounceTimer = setTimeout( () => {
        filter($w('#input1').value);
 }, 200);
}

let lastFilterTitle;

function filter(title) {
 if (lastFilterTitle !== title) {
 ($w('#dataset1').setFilter(wixData.filter().contains("claveProducto", title))); //FIRST FILTER
 ($w('#dataset1').setFilter(wixData.filter().contains("clave1Producto", title))) //SECOND FILTER
 
    lastFilterTitle = title; 
 
 }

}

Hi Sebas,

This example https://www.wix.com/velo/example/custom-store-filters should show you how to filter by multiple keyfields. See the function ’ filter()

Hey @shantanukumar847 , thanks for the quick reply,

I saw the example, actually I found it usefull for something I wanted to do

However in regards to this post, I want to use one input to search in two or more keyfields. That’s why I think I need to use contain and .OR

It must be easy, but I can’t figure out how to write it

Not sure if this will help in your case but I ran into something where I needed nested operators like this

const bPromise = wixData . query ( “Meals” ). hasSome ( “time” , “Breakfast” )
. not ( wixData . query ( “Meals” ). hasSome ( “allergens” , $w ( ‘#allergies’ ). value ))
. find (). then ( ( allMeals ) => { return allMeals }

the .not contains a subquery perhaps you can do something similar by having 1 outer setfilter that contains the or, with a sub setfilter inside each

@archaeous @shantanukumar847 , really thanks for the help

Finally, I got it

Apart from your help, I also use this post’s code from JD, and the setFilter example in the api that is really clear
https://www.wix.com/velo/forum/coding-with-velo/using-an-or-operator-to-filter-by-multiple-fields-in-a-dataset-at-once-for-a-repeater

// API Reference: https://www.wix.com/velo/reference/api-overview/introduction
// “Hello, World!” Example: https://learn-code.wix.com/en/article/1-hello-world

import wixData from "wix-data";



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

let debounceTimer;

export function input1_keyPress(event) {
 if (debounceTimer) {
    clearTimeout(debounceTimer);
    debounceTimer = undefined;
 }
    debounceTimer = setTimeout( () => {
        filter($w('#input1').value);
 }, 200);
}

let lastFilterTitle;

function filter(title) {
 
 if (lastFilterTitle !== title) {

 let filter = wixData.filter().contains('claveProducto',title)
 .or(wixData.filter().contains('clave1Producto',title));

       $w('#dataset1').setFilter(filter)

    lastFilterTitle = title; 
 
 }

}

Took me awhile to wrap my brain around some of the ways you can combine or nest filters and queries and not sure I 100% have it yet but can usually figure out something that works haha.

Here another version of an OR-Filtering-System for 3-different kinds of elements.

User-Interface--------------------------------------------------------------------------------------

var DropDowns, CBoxes, SelTags
var STprefix = "ST" ;    //-----> ID-Prefix of SelectionTags-element
var DDprefix = "DD" ;    //-----> ID-Prefix of DropDown-element
var CBGprefix = "CBG" ;  //-----> ID-Prefix of CheckBox-element
var DATABASE = "DATABASE-ID-HERE"

Prefixing-example…

ST1 / ST2 / ST3 ---> ID's of 3x-Selection-Tag-elements

/Drop-Downs--------------------------------

DropDowns[0] = "SOME-DATAFIELD-ID-HERE-FOR-DROPDOWN"
DropDowns[1] = "ANOTHER-DATAFIELD-ID-HERE-FOR-SECOND-DROPDOWN"

//Check-Boxes--------------------------------

CBoxes[0] = "SOME-DATAFIELD-ID-HERE-FOR-CHECKBOX-GROUP"
CBoxes[1] = "ANOTHER-DATAFIELD-ID-HERE-FOR-2nd-CHECKBOX-GROUP"

//Selection-Tags--------------------------------

SelTags[0] = "SOME-DATAFIELD-ID-HERE-FOR-SELECTION-TAGS"
SelTags[1] = "SOME-DATAFIELD-ID-HERE-FOR-SECOND-SELECTION-TAGS"

User-Interface--------------------------------------------------------------------------------------

What is —> MEMdropdowns / MEMcboxes / MEMstags ???
And how to use it???

Do NOT touch this CODE ITSELF!!! Only add or delete new elements depending to → Selection-Tags!!! —>

$w('#ST1, #ST2, #ST3, #ST4, #ST5)

For Dropdowns…------------------------

$w('Dropdown').onChange(async(event)=>{
   let selectedElementID = event.target.id;
   let selectedINDEX = Number(event.target.id[event.target.id.length - 1]); 
   if(selectedElementID===(DDprefix+selectedINDEX)){$w('#'+selectedElementID).blur();
      $w('#'+selectedElementID).style.backgroundColor = "rgba(175,225,155,0.5)";
      MEMdropdowns[selectedINDEX-1] = await $w('#'+selectedElementID).value;
      setTimeout(()=>{FILTER_ENGINE()},100);
   }
});

For Check-Box-Groups…------------------------

$w('CheckboxGroup').onChange(async(event)=>{
    let selectedElementID = event.target.id;
    let selectedINDEX = Number(event.target.id[event.target.id.length - 1]); 
    MEMcboxes[selectedINDEX-1] = await $w('#'+selectedElementID).value; 
    setTimeout(()=>{FILTER_ENGINE()},100);
 });

For Selection-Tags--------------

$w('#ST1, #ST2, #ST3, #ST4, #ST5).onChange(async(event)=>{
    let selectedElementID = event.target.id;
    let selectedINDEX = Number(event.target.id[event.target.id.length - 1]); 
    MEMstags[selectedINDEX-1] = await $w('#'+selectedElementID).value; 
    await local.setItem(SelTags[(selectedINDEX-1)], MEMstags[(selectedINDEX-1)])
    setTimeout(()=>{FILTER_ENGINE()},100)
 })

Do NOT touch this CODE ITSELF!!! Only fill the User-Interface-section!!!

async function FILTER_ENGINE() {console.log("START_Filter-Engine")
 let query = [];
//OR-Filter------------------------------------------------------------------------
 else{
 //Dropdowns--------------------------------------
 for (let i=0; i < DropDowns.length; i++) { 
 if (MEMdropdowns[i]!==undefined && MEMdropdowns[i]!=="undefined" && MEMdropdowns[i]!==""){
                $w('#'+DDprefix+(i+1)).value = MEMdropdowns[i]
                query.push({datafield: DropDowns[i], value: MEMdropdowns[i]})
 }else { }
 }
 //C-Boxes----------------------------------------
 if (MEMcboxes!==undefined) { 
    for (var a = 0; a < CBoxes.length; a++) {
       if (MEMcboxes[a]!==undefined){
          for (var b = 0; b < MEMcboxes[a].length; b++) {
             query.push({datafield: CBoxes[a], value: MEMcboxes[a][b]})
          }
      }else { }
   }
 }
 //Selection-Tags----------------------------------------
 if (MEMstags!==undefined) { 
    for (var a = 0; a < SelTags.length; a++) {
       if (MEMstags[a]!==undefined){
          for (var b = 0; b < MEMstags[a].length; b++) {
             query.push({datafield: SelTags[a], value: MEMstags[a][b]})
          }
       }else { }
    }
 }else { } 
 //---------------------------------                                                                                         
        itemDATA = await get_FilterData(DATABASE, query);  
 if(itemDATA[0]!==undefined){result_COUNTER(itemDATA.length, itemDATA)}                                     
 else{console.log("ERROR")
 }
 }
 }

Normaly this would work on Backend. I tried to modify it to Front-End.
Hopefully without mistakes :sweat_smile:

function get_FilterData(DATABASE, REQUEST)
 REQUEST.find() //or ---> return REQUEST.find()
 .then(async(res) => {
     let uniqueItems=[], uniqueIDs=[], VALUE, ITEM, ID
 
     for (var i = 0; i < res.items.length; i++) {
        ITEM = await res.items[i]
        ID = await res.items[i]._id
        for (var a = 0; a < REQUEST.length; a++) {
           VALUE = await res.items[i][REQUEST[a].datafield]
           console.log("VALUE: ", VALUE)
           console.log("ITEM: ", ITEM)
           console.log("ID: ", ID)
           console.log("REQUEST: ",REQUEST[a].value)       
           if(VALUE[0].length!==1){console.log("TAGS")
              for (var x = 0; x < VALUE.length; x++) {
                 if(VALUE[x]===REQUEST[a].value) {console.log("TREFFER")
                    if(uniqueIDs.includes(ID)){}
                    else{uniqueIDs.push(ID), await uniqueItems.push(ITEM)}
                 }
              } 
           }
           else{
              if(VALUE===REQUEST[a].value) {console.log("TREFFER")
                 if(uniqueIDs.includes(ID)){}
                 else{uniqueIDs.push(ID), await uniqueItems.push(ITEM)}
              }
           }
        } 
     }
     console.log("Unique-Items: ", uniqueItems)
     return  uniqueItems
    } 
 })
 .catch((err) => {console.log(err)});
}

If all works like expected all you will have to do is to fill out the —> USER-INTERFACE.

Create new DropDown or CheckBox-Group, or Selection-Tag-Element on your page and give it an ID like shown in the example above (using the Element-PREFIX)

DD1, DD2, DD3, DD4… and so on for DropDowns
CBG1, CBG2, CBG3 … and so on for Check-Box-Groups
and ST1, St2, ST3… and so on for NEW Selection-Tag-Elements

Perhaps you will have to do the one or the other bug-fixing!

I hope you understood what to do exactly.

When you get this working, you will be able to add or remove NEW/OLD-ELEMENTS without crushing the code.

Good luck!:wink::laughing::sunglasses:

You can only use —> Selection-Tag-DATAFIELDS for Selection-Tags and Check-Box-Groups. (But if it is my new version of Filtering-Engine, then it also would work on any other DATAFIELD in your DB). I am not sure, which one i have written down here xDDDDDDDDDDD​:rofl::sweat_smile:

BTW: You can of course also change the PREFIXES → DD/CBG/ST , but i do not know why you should do this.

When you get this working, you will have a lot of fun & pleasure with it :wink:

@russian-dima ,

Velo is one thing, but Java is like the moon to me

Thanks for always helping, and for the code example…a few months and I might fully understand it jaja

Ohh, i forgot to mention, that you will find another kind of or-filtering here…
https://www.wix.com/velo/forum/coding-with-velo/how-can-i-create-multi-checkbox-filter-similar-to-the-wix-store-prebuild-filter