Hello Guys, Is it possible to eliminate / filter options in a dropdown comparing another dropdown?

Suppose I have two datasets A and B and their Data eg. List (Field Name). Kindly see below images.


Kindly help me to eliminate/do not display/filter option in DATA_B dropdown comparing similar option through code. Any help in regard will be helpful. Thanks in advance. : )

Try something like:

import wixData from 'wix-data';
let dataset1Lists;
let isDataset2Ready = false;
$w.onReady(() => {
    $w('#dataset1').onReady(() => {
        $w('#dataset1').getItems(0, 1000).then(r => {
            dataset1Lists = r.items.map(e => e.list);
            filterDataset2();
        });
    });
    $w('#dataset2').onReady(() => {
        isDataset2Ready = true;
        filterDataset2();
    });
});

function filterDataset2() {
    if (dataset1Lists && isDataset2Ready) {
        if (dataset1Lists.length > 0) {
            let filter = wixData.filter();
            dataset1Lists.forEach(e => filter = filter.ne('list', e));
            $w('#dataset2').setFilter(filter);
        }
    }
}
3 Likes

Allow me to show another way of doing this, assuming that your dropdowns are manually connected instead of coded.

//Function that filters repeated items from dropdowns
const filter = (list, listToFilter) => {
    return listToFilter.filter(({ label }) => !list.some(item => item.label === label))
}

$w.onReady(async () => {
    //Wait for the dataset A to be ready
    $w('#datasetA').onReady(() => {
        //Wait for the dataset B to be ready
        $w('#datasetB').onReady(() => {
            //Get the dropdown values
            const dd1 = $w('#dropdown1').options
            const dd2 = $w('#dropdown2').options
            //Filter the values
            const filteredDD = filter(dd1, dd2)
            //Feed them to the dropdown that needs filter
            $w('#dropdown2').options = filteredDD
        })
    })
})

Best regards.

2 Likes

Thank you so very much @J. D. , I have no words to thank you. : )

2 Likes

@Bruno Prado … You are amazing too. Thanks for this solution too. You guys are awesome. This was a very problem for me to sort out. You gave your precious time for me I won’t forget this. Love you guys : )

1 Like

@bwprado , your code is based on the assumption that dataset1 gets ready prior to dataset2. It’s not necessarily right.

1 Like

@jonatandor35 You are totally right about that, it was a wrong assumption of mine, and it worked just fine because dataset A loads quicker than dataset B in the example. So, to correct the code I create two alternatives, one that we write lessc code, but it runs the filter two times (no problem if the data is small). And another more functional, that we write more code, but it is more efficient.

Version 1:

//Function that filters repeated items from dropdowns
const filterDropdown = (list, listToFilter) => {
    return listToFilter.filter(
        ({ label }) => !list.some(item => item.label === label)
    )
}

$w.onReady(async () => {
    //Wait for the dataset A and B to be ready
    $w('#datasetA, #datasetB').onReady(() => {
        //Get the dropdown values
        const dd1 = $w('#dropdown1').options
        const dd2 = $w('#dropdown2').options
        //Filter the values
        const filteredDD = filterDropdown(dd1, dd2)
        //Feed them to the dropdown that needs filter
        $w('#dropdown2').options = filteredDD
    })
    //Wait for the dataset B to be ready
})

Version 2:

let datasetA = false
let datasetB = false

//Function that filters repeated items from dropdowns
const filterDropdown = (list, listToFilter) => {
    return listToFilter.filter(
        ({ label }) => !list.some(item => item.label === label)
    )
}

const loadDropdowns = () => {
    const dd1 = $w('#dropdown1').options
    const dd2 = $w('#dropdown2').options
    //Filter the values
    const filteredDD = filterDropdown(dd1, dd2)
    //Feed them to the dropdown that needs filter
    $w('#dropdown2').options = filteredDD
}

const checkLoad = () => {
    if (datasetA && datasetB) loadDropdowns()
}

$w.onReady(async () => {
    //Wait for the dataset A and B to be ready
    $w('#datasetA').onReady(() => {
        datasetA = true
        checkLoad()
    })
    $w('#datasetB').onReady(() => {
        datasetB = true
        checkLoad()
    })
})

Thanks for the tip @J. D.!

2 Likes