Working with dropdowns

Hello All,
I have spent a week trying to solve this problem, but have reached an impasse. I am building a dictionary where a search bar allows you to search for a word or phrase while a drop-down allows you to select the first letter of words.

www.BeforeTheCorps.com/slang

Right now, there are two problems:

  1. The “All Letters” option does not populate as the default, and does not stay selected when clicked.
  2. The dropdown list doesn’t always work - it will sometimes not reset, or will return either none or some of the options beginning with the first letter. It appears to be some type of reset issue when clicking between different options on the dropdown.
    The issues are the same in the editor and live site. Can anyone point me in the right direction?

On the page is repeater linked to database “Marine Corps Slang & Acronyms” drawing from columns titled “title” and “definition”
I created a second database collection called “123” that contains the alphabet
Both are added as Read Only datasets (ID on the page as dataset1 and dataset2 respectively)
The input box is “iTitle” while the drop-down is “firstLetter”
I want to be able to search by title and first letter

import wixData from "wix-data";

$w.onReady(()=> {
    wixData.query('123')
      .find()
      .then(res => {
 let options = [{"value": '','label':'All Letters'}];
          options.push(...res.items.map(firstLetter => {
 return {'value':firstLetter.title,'label': firstLetter.title};
          }));
          $w('#firstLetter').options = options;
      })
});

let lastFilterTitle;
let lastFilterLetter;

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

function filter(title,letter) {
 if (lastFilterTitle !== title || lastFilterLetter !== letter) {
 let newFilter = wixData.filter();
 if (title)
          newFilter = newFilter.contains('title', title);
 if (letter) 
          newFilter = newFilter.eq('firstLetter', letter)
    $w('#dataset1').setFilter(newFilter);
    lastFilterTitle = title;
    lastFilterLetter = letter;
    }
} 

export function FirstLetter_change(event, $w) {
    filter(lastFilterLetter, $w('#firstLetter').value);
}

You can change the value that you are using for “all letters” to all .

 let options = [{"value": 'all','label':'All Letters'}];

Then, if letter is not all, set the filter:

if (letter && letter !== 'all') 
          newFilter = newFilter.eq('firstLetter', letter)

This hasn’t been tested, but something like the above should help.

Hi Yisrael,
I tried that but it does not address either of the issues - All Letters does not show up as the default selection on the drop down, nor does it bring up all options. I think that doesn’t work because the value “all” would not show up anywhere in the data set. Having an empty string works to include all results in the data set.

-Andrew

@beforethecorps You are correct, the value “all” does not appear in the dataset, but you don’t need that value. What you need for “all results” is to simply not apply a filter on the firstLetter field as I indicated in my previous comment, like this:

if (letter && letter !== 'all') 
          newFilter = newFilter.eq('firstLetter', letter)

And, to set the default selection set the selectedIndex.

@yisrael-wix I have input the code snippets from both your comments as recommended, but they are not working. The selectedIndex function worked right away, so one of two problems resolved. I continue to have the issue of the dropdown resulting in only a partial return of values. For example, if there are six words starting with C, it may return none, all, or some of those values.

This is how the page code looks with the

import wixData from "wix-data";

$w.onReady(()=> {
    wixData.query('123')
      .find()
      .then(res => {
 let options = [{"value": 'all','label':'All Letters'}];
          options.push(...res.items.map(firstLetter => {
 return {'value':firstLetter.title,'label': firstLetter.title};
          }));
          $w('#firstLetter').options = options;
          $w("#firstLetter").selectedIndex = 0;
      })
});

let lastFilterTitle;
let lastFilterLetter;

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

function filter(title,letter) {
 if (lastFilterTitle !== title || lastFilterLetter !== letter) {
 let newFilter = wixData.filter();
 if (title)
          newFilter = newFilter.contains('title', title);
 if (letter && letter !== 'all') 
          newFilter = newFilter.eq('firstLetter', letter)
    $w('#dataset1').setFilter(newFilter);
    lastFilterTitle = title;
    lastFilterLetter = letter;
    }
} 

export function FirstLetter_change(event, $w) {
    filter(lastFilterLetter, $w('#firstLetter').value);
}

Got it!

It’s like this…

In FirstLetter_change(), you call filter:

filter(lastFilterLetter, $w('#firstLetter').value);

However, the first parameter for the filter function is title:

function filter(title,letter)

What happens is that the second time you change the selected first letter from the dropdown, you are calling the filter function with the lastFilterLetter which will be filtered (incorrectly) as the Title, and the newly selected filter letter which will be added (correctly) as the firstLetter filter.

You probably want this instead:

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

I hope this helps.

@Yisrael (Wix) That works! Thanks so much!!