Search & autocomplete
Build search with autocomplete using suggest() for suggestions and setCondition() for filtering results.
Key dcupl functions
| Function | Purpose |
|---|---|
catalog.fn.suggest() |
Get autocomplete suggestions for an attribute |
query.setCondition() |
Set filter condition (replaces the conditions on that attribute) |
query.addCondition() |
Add filter condition (ORed with others on the same attribute) |
Get suggestions
Use suggest() to get autocomplete suggestions as the user types:
const suggestions = productList.catalog.fn.suggest({
attribute: 'name',
value: 'lap', // User input
max: 5, // Limit results
});
// [{ value: 'Laptop Pro', keys: ['p1'] }, { value: 'Laptop Air', keys: ['p2'] }, { value: 'Laptop Stand', keys: ['p8'] }]Each suggestion contains:
value- The suggested termkeys- Item keys that match this value
A plain search term matches the start of the value, ignoring case: 'lap' suggests "Laptop Pro" but not "Gaming Laptop".
Match anywhere in the value
Wrap the term in slashes for a regular expression and set regexFlags: 'i' to ignore case ('/lap/i' would be compared as a plain value and match nothing):
const suggestions = productList.catalog.fn.suggest({
attribute: 'name',
value: '/lap/',
regexFlags: 'i',
max: 5,
});
// Also suggests "Gaming Laptop"Escape regex characters in user input before wrapping it in slashes.
Suggest from multiple attributes
Get suggestions from different attributes and combine them:
const nameSuggestions = productList.catalog.fn.suggest({
attribute: 'name',
value: userInput,
max: 5,
});
const brandSuggestions = productList.catalog.fn.suggest({
attribute: 'brand',
value: userInput,
max: 3,
});
// One dropdown: label each entry with the attribute it came from
const combined = [
...nameSuggestions.map((s) => ({ ...s, source: 'name' })),
...brandSuggestions.map((s) => ({ ...s, source: 'brand' })),
];
// [{ value: 'Laptop Pro', keys: ['p1'], source: 'name' }, ..., { value: 'Lenovo', keys: ['p4', 'p9'], source: 'brand' }]The source tells you which condition to set when the user picks an entry.
Handling input
max defaults to 20. In a search box, wait for a minimum length (for example 2 characters) and debounce the input (for example 150 ms) before you call suggest(). Each distinct term is cached on the list until the next update that affects it (see Caching), so a debounce also keeps that cache small.
let timer: ReturnType<typeof setTimeout> | undefined;
function onSearchInput(userInput: string) {
clearTimeout(timer);
if (userInput.length < 2) return;
timer = setTimeout(() => {
const suggestions = productList.catalog.fn.suggest({ attribute: 'name', value: userInput, max: 5 });
// render suggestions
}, 150);
}Apply search filter
When user selects a suggestion or submits search, filter the results. Wrap the term in slashes ('/term/') for substring search; a bare string must match the whole value. Set regexFlags: 'i' for case-insensitive search:
// Text search with 'find' operator: names containing "laptop" in any case
productList.catalog.query.setCondition({
operator: 'find',
attribute: 'name',
value: '/laptop/',
options: { regexFlags: 'i' },
});
const results = productList.catalog.query.items();Filter by exact match
When user selects a specific suggestion (e.g., a brand):
productList.catalog.query.setCondition({
operator: 'eq',
attribute: 'brand',
value: 'Apple',
});
const results = productList.catalog.query.items();Clear and re-apply
setCondition() replaces the previous condition on the same attribute, so a new search term needs no clearing. Call clear() only to drop all other filters as well (it also resets sort and paging):
// Optional: remove all conditions and options
productList.catalog.query.clear();
// Apply new search (escape regex characters in user input)
const escaped = newSearchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
productList.catalog.query.setCondition({
operator: 'find',
attribute: 'name',
value: `/${escaped}/`,
options: { regexFlags: 'i' },
});Complete flow
// 1. User types "lap"
const suggestions = productList.catalog.fn.suggest({
attribute: 'name',
value: 'lap',
max: 5,
});
// 2. User selects "Laptop Pro" from suggestions (a bare string matches the whole value)
productList.catalog.query.setCondition({
operator: 'find',
attribute: 'name',
value: 'Laptop Pro',
});
// 3. Get filtered results
const results = productList.catalog.query.items();suggest() draws from the list's current result by default (relevantData: 'filtered'), so once the search condition on name is set, the next suggest() on name only returns "Laptop Pro". To keep suggesting every name while a search is active, leave the search's group out:
const suggestions = productList.catalog.fn.suggest({
attribute: 'name',
value: userInput,
max: 5,
relevantData: 'excludeQuery',
excludeQuery: { groupKey: 'name' }, // the group setCondition() created for 'name'
});