Enhance FormSelect component by adding search prompt for large lists and implementing debounced search functionality. Introduce new props for search configuration, improving user experience and performance during data selection.
This commit is contained in:
@ -59,6 +59,12 @@
|
||||
<span>Sonuç Bulunamadı</span>
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="form-select-list-item" v-if="showSearchPrompt">
|
||||
<span>
|
||||
İlk {{ selectList.length }} kayıt gösteriliyor. Daha fazla sonuç için en az
|
||||
{{ props.minSearchLength }} harf yazın.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="form-select-list-item"
|
||||
v-if="multiple"
|
||||
@ -104,7 +110,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, onMounted, watch } from 'vue'
|
||||
import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue'
|
||||
import { useGlobalStore } from '@/stores/globalStore'
|
||||
const globalStore = useGlobalStore()
|
||||
|
||||
@ -129,6 +135,10 @@
|
||||
multipleText?: string
|
||||
view?: Function
|
||||
disabledClass?: string
|
||||
largeListThreshold?: number
|
||||
initialDisplayLimit?: number
|
||||
minSearchLength?: number
|
||||
searchDebounceMs?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@ -139,7 +149,11 @@
|
||||
clearable: false,
|
||||
extraData: '',
|
||||
multiple: false,
|
||||
multipleText: 'Tümü'
|
||||
multipleText: 'Tümü',
|
||||
largeListThreshold: 100,
|
||||
initialDisplayLimit: 100,
|
||||
minSearchLength: 2,
|
||||
searchDebounceMs: 120
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'change', 'clear'])
|
||||
@ -147,9 +161,11 @@
|
||||
const activated = ref<Boolean>(false)
|
||||
const multipleAllSelected = ref<boolean>(false)
|
||||
const q = ref<string>('')
|
||||
const debouncedQuery = ref<string>('')
|
||||
const rnd = ref<number>(Number(Math.floor(Math.random() * 1000000000)))
|
||||
const localValue = ref<string | number | boolean | null | string[]>()
|
||||
const selectedOption = ref<Record<string, any>>({})
|
||||
let searchDebounceTimer: ReturnType<typeof setTimeout> | undefined
|
||||
|
||||
if (props.multiple) {
|
||||
if (props.modelValue === null || props.modelValue === undefined) {
|
||||
@ -225,12 +241,24 @@
|
||||
}
|
||||
})
|
||||
|
||||
const isLargeList = computed<boolean>(() => {
|
||||
return props.listData.length > props.largeListThreshold
|
||||
})
|
||||
|
||||
const showSearchPrompt = computed<boolean>(() => {
|
||||
return isLargeList.value && debouncedQuery.value.length < props.minSearchLength
|
||||
})
|
||||
|
||||
const selectList = computed<Record<string, any>[]>(() => {
|
||||
if (q.value.length > 1) {
|
||||
if (debouncedQuery.value.length >= props.minSearchLength) {
|
||||
return props.listData.filter((v: Record<string, any>) => {
|
||||
let val = props.listText !== undefined ? v[props.listText] : v
|
||||
return globalStore.trToUpper(val).includes(globalStore.trToUpper(q.value))
|
||||
return globalStore
|
||||
.trToUpper(String(val))
|
||||
.includes(globalStore.trToUpper(debouncedQuery.value))
|
||||
})
|
||||
} else if (isLargeList.value) {
|
||||
return props.listData.slice(0, props.initialDisplayLimit)
|
||||
} else {
|
||||
return props.listData
|
||||
}
|
||||
@ -308,6 +336,7 @@
|
||||
if (props.disabled) return
|
||||
e.stopPropagation()
|
||||
q.value = ''
|
||||
debouncedQuery.value = ''
|
||||
activated.value = true
|
||||
|
||||
setTimeout(() => {
|
||||
@ -368,6 +397,18 @@
|
||||
SetSelectedOption()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (searchDebounceTimer !== undefined) clearTimeout(searchDebounceTimer)
|
||||
document.removeEventListener('click', closeList)
|
||||
})
|
||||
|
||||
watch(q, (value: string) => {
|
||||
if (searchDebounceTimer !== undefined) clearTimeout(searchDebounceTimer)
|
||||
searchDebounceTimer = setTimeout(() => {
|
||||
debouncedQuery.value = value.trim()
|
||||
}, props.searchDebounceMs)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.invalidText,
|
||||
() => {
|
||||
|
||||
Reference in New Issue
Block a user