From 359e67c734182ba1255133a8bd09479e0ab8c312 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 31 Jan 2025 14:46:42 +0100 Subject: [PATCH] refactor: refs #8388 improve filter and search functionality --- src/components/common/VnSelect.vue | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index c850f2e53..b06542f28 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -171,7 +171,8 @@ onMounted(() => { }); const arrayDataKey = - $props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label); + $props.dataKey ?? + ($props.url?.length > 0 ? $props.url : ($attrs.name ?? $attrs.label)); const arrayData = useArrayData(arrayDataKey, { url: $props.url, @@ -193,14 +194,13 @@ function setOptions(data) { function filter(val, options) { const search = val?.toString()?.toLowerCase(); - if (!search) return options; return options.filter((row) => { if ($props.filterOptions.length) { return $props.filterOptions.some((prop) => { const propValue = String(row[prop]).toLowerCase(); - return propValue.includes(search); + return matchesSearch(propValue, search); }); } @@ -208,10 +208,14 @@ function filter(val, options) { const id = String(row[$props.optionValue]); const optionLabel = String(row[$props.optionLabel]).toLowerCase(); - return id.includes(search) || optionLabel.includes(search); + return matchesSearch(id, search) || optionLabel.includes(search); }); } +function matchesSearch(val, search) { + return /^\d+$/.test(search) ? val.startsWith(search) : val.includes(search); +} + async function fetchFilter(val) { if (!$props.url) return; @@ -220,7 +224,7 @@ async function fetchFilter(val) { optionFilterValue.value ?? (new RegExp(/\d/g).test(val) ? optionValue.value - : optionFilter.value ?? optionLabel.value); + : (optionFilter.value ?? optionLabel.value)); let defaultWhere = {}; if ($props.filterOptions.length) { @@ -239,7 +243,7 @@ async function fetchFilter(val) { const { data } = await arrayData.applyFilter( { filter: filterOptions }, - { updateRouter: false } + { updateRouter: false }, ); setOptions(data); return data; @@ -272,7 +276,7 @@ async function filterHandler(val, update) { ref.setOptionIndex(-1); ref.moveOptionSelection(1, true); } - } + }, ); } @@ -308,7 +312,7 @@ function handleKeyDown(event) { if (inputValue) { const matchingOption = myOptions.value.find( (option) => - option[optionLabel.value].toLowerCase() === inputValue.toLowerCase() + option[optionLabel.value].toLowerCase() === inputValue.toLowerCase(), ); if (matchingOption) { @@ -320,11 +324,11 @@ function handleKeyDown(event) { } const focusableElements = document.querySelectorAll( - 'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])' + 'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])', ); const currentIndex = Array.prototype.indexOf.call( focusableElements, - event.target + event.target, ); if (currentIndex >= 0 && currentIndex < focusableElements.length - 1) { focusableElements[currentIndex + 1].focus();