Hm…I hadn’t considered this because it seemed like not what Selection Tags are for.
First…Selection Tags are meant to be an input…meaning, they write data to your database from an input form. This is not what I want. I am not submitting a form. I am asking a user to filter a database query based on the value selected.
Second, they are multi select. A user chooses any number of selection tags, and the selections are written to the form submission table. This is not what I want. I want to be able to pick one chip, and have it set a filter on a dataset…not write anything to a table.
Third, it is the UI layer that determines what the choices are, not the database. This means that if I have multiple UIs that use these chips, I have to set up the Selection Tag values in the UI layer. I want this information to come from the database so I only have to store it once, and it’s always consistent.
Here’s what I’m trying to do:
I have “enums” in my database in the form of reference tables. Those tables contain the only allowable values for a column in my main table. I want choices to come from the list provided by my database. Here’s a hypothetical example, I have two tables: Toys, and Colors. Toys has a MultiRef column to Colors. Colors has rows like Yellow, Orange, Red, Green, Blue, Purple.
In some particular UI (I’m building a search page), The user would say “show me only Blue toys” by clicking on the Blue tab/chip. The Toys dataset would apply the filter on the Toys.colors MultiRef column and filter the search results.
I want basically an enum whose values are displayed as chips. This is not what Selection tags are for. They are for accepting input from a user that conforms to a specific list of choices and writing it to a collection Tags column.
But…I could make this work by not actually connecting the Selection Tags to a database table/column, then programmatically populating the tag values by querying the Colors reference table in dataset.onReady, and then capturing the selection tag value in its change handler and setting a filter in Toys and create a custom change handler that unselected everything before applying the new selection onChange (using your code above). Basically, I would be using the UI capabilities only…not really the whole Selection Tag feature.
I suppose I could do this…Even though it’s not the intended use for Selection Tags, maybe this is not so hacky…I just coded up a quick POC and it works…(code below).
In fact, this could be the solution to another problem I had to HACK to get around…the fact that checkbox layouts are not easily controlled…you get a single row, or a single column…not a grid. So I had to create a pretty complicated (and what I really mean is…HORRIBLE) UI in order to be able to display filter menus that have a lot of choices. The UI is so bad that I had to just hide the whole page on mobile. I think I could rewrite it using this solution.
The only thing I sort of worry about with this solution is that since it’s not really the intended use of Selection Tags, I’m hoping Wix won’t change something that breaks how I’m using it.
But…barring that worry…this works…Thanks!
import wixData from 'wix-data';
$w.onReady(function () {
$w('#colorsDataset').onReady(() => {
$w('#colorsDataset')
.getItems(0, $w('#colorsDataset').getTotalCount()).then((results) => {
let options = results.items.map((item) => {
return { label: item.title, value: item._id} });
options.push({label: 'Show all', value: '-1'});
$w('#colorSelectionTags').options = options;
// by default, show all. Dataset is not filtered.
$w('#colorSelectionTags').value = ['-1'];
});
});
});
export function colorSelectionTags_change(event) {
// sets selection to just the last value - removes multi-select behavior
let value = $w("#colorSelectionTags").value.reverse()[0];
$w("#colorSelectionTags").value = [value];
if (value === '-1') {
$w('#toysDataset').setFilter(wixData.filter());
} else {
$w('#toysDataset').setFilter(wixData.filter().hasSome("color", Object.values([value])));
}
}