From b6b5b6c3f38a5824e0d71b26a376453b3b5232cd Mon Sep 17 00:00:00 2001 From: Poh Nean Date: Fri, 29 Sep 2023 14:45:02 +0800 Subject: [PATCH] feat: adding custom-search prop --- src/components/DataTable.vue | 5 +++-- src/hooks/useTotalItems.ts | 17 ++++++++++++++--- src/modes/Client.vue | 16 ++++++++++++++++ src/propsWithDefault.ts | 4 ++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/components/DataTable.vue b/src/components/DataTable.vue index e51b2ab..af7e1fb 100644 --- a/src/components/DataTable.vue +++ b/src/components/DataTable.vue @@ -73,7 +73,7 @@ v-else-if="slots['header']" name="header" v-bind="header" - /> + /> + > , searchField: Ref, searchValue: Ref, + customSearch: (item: Item) => boolean | undefined, serverItemsLength: Ref, multiSort: Ref, emits: (event: EmitsEventName, ...args: any[]) => void, ) { + const defaultSearchFunction = (item: Item) => { + if (searchValue.value === '') { + return true; + } + + const regExp = new RegExp(searchValue.value, 'i'); + return regExp.test(generateSearchingTarget(item)); + }; + + const generateSearchingTarget = (item: Item): string => { if (typeof searchField.value === 'string' && searchField.value !== '') return getItemValue(searchField.value, item); if (Array.isArray(searchField.value)) { @@ -32,9 +43,9 @@ export default function useTotalItems( // items searching const itemsSearching = computed((): Item[] => { // searching feature is not available in server-side mode - if (!isServerSideMode.value && searchValue.value !== '') { - const regex = new RegExp(searchValue.value, 'i'); - return items.value.filter((item) => regex.test(generateSearchingTarget(item))); + if (!isServerSideMode.value) { + const searchFn = customSearch ?? defaultSearchFunction; + return items.value.filter(searchFn); } return items.value; }); diff --git a/src/modes/Client.vue b/src/modes/Client.vue index bdbe259..50d492c 100644 --- a/src/modes/Client.vue +++ b/src/modes/Client.vue @@ -33,6 +33,7 @@ :header-item-class-name="headerItemClassNameFunction" :body-item-class-name="bodyItemClassNameFunction" :body-expand-row-class-name="bodyExpandRowClassNameFunction" + :custom-search="customSearchFunction" @update-sort="updateSort" @update-filter="updateFilter" multi-sort @@ -165,6 +166,21 @@ const updateTotalItems = (items: Item[]) => { console.log(JSON.stringify(items)); }; +// Example of Custom search by name and height +// e.g.: searchValue = 'h 6-11' +const customSearchFunction = (item: Item) => { + const keyword = searchValue.value.toLowerCase(); + + return keyword + .split(' ') + .every((word) => { + const nameMatched = item.name.toLowerCase().includes(word); + const heightMatched = item.indicator.height.toLowerCase().includes(word); + + return nameMatched || heightMatched; + }); +} + const items = ref([ { name: "Stephen Curry", firstName: "GSW", number: 30, position: 'G', indicator: {"height": '6-2', "weight": 185}, lastAttended: "Davidson", country: "USA"}, { name: "Kevin Durant", firstName: "BKN", number: 7, position: 'F', indicator: {"height": '6-10', "weight": 240}, lastAttended: "Texas-Austin", country: "USA"}, diff --git a/src/propsWithDefault.ts b/src/propsWithDefault.ts index 947441d..332e1f6 100644 --- a/src/propsWithDefault.ts +++ b/src/propsWithDefault.ts @@ -103,6 +103,10 @@ export default { type: String, default: '', }, + customSearch: { + type: Object as PropType<(item: Item) => boolean> | null, + default: null, + }, serverOptions: { type: Object as PropType | null, default: null,