From 01071196df691989b67a7a4e30402062a54657fa Mon Sep 17 00:00:00 2001 From: A1Gard Date: Wed, 25 Dec 2024 06:06:44 +0330 Subject: [PATCH] added auto complete for tags --- app/Http/Controllers/Api/TagController.php | 26 +++++++ resources/js/components/TagInput.vue | 69 +++++++++++++++++++ .../views/admin/clips/clip-form.blade.php | 1 + .../views/admin/posts/post-form.blade.php | 1 + .../sub-pages/product-step3.blade.php | 1 + routes/api.php | 3 + 6 files changed, 101 insertions(+) create mode 100644 app/Http/Controllers/Api/TagController.php diff --git a/app/Http/Controllers/Api/TagController.php b/app/Http/Controllers/Api/TagController.php new file mode 100644 index 0000000..e67beb7 --- /dev/null +++ b/app/Http/Controllers/Api/TagController.php @@ -0,0 +1,26 @@ +' . config('app.locale'), 'like', '%' . $q . '%')->limit(10)->pluck('name'); + return ['OK' => true, 'data' => $tags]; + } +} diff --git a/resources/js/components/TagInput.vue b/resources/js/components/TagInput.vue index 13d38c4..210186c 100644 --- a/resources/js/components/TagInput.vue +++ b/resources/js/components/TagInput.vue @@ -7,9 +7,18 @@ + @@ -26,6 +35,8 @@ export default { return { tag: '', tags: [], + searchList:[], + selectedIndex: -1, } }, emits: ['update:modelValue'], @@ -58,6 +69,10 @@ export default { }, type: Function, }, + autoComplete:{ + default: '', + type: String, + } }, mounted() { if (this.modelValue != null) { @@ -72,9 +87,18 @@ export default { computed: {}, methods: { addTag(e) { + if (this.selectedIndex > -1 && (this.selectedIndex + 1) < this.searchList.length ){ + this.tags.push(this.searchList[this.selectedIndex]) ; + this.tag = ''; + this.searchList = []; + this.checkDuplicate(); + this.$emit('update:modelValue', this.tags.join(this.splitter)); + return; + } if (this.tag.trim()) { // Check if the input is not empty this.tags.push(this.tag.trim()); // Add the trimmed tag this.tag = ''; // Reset the input + this.checkDuplicate(); this.$emit('update:modelValue', this.tags.join(this.splitter)); } }, @@ -89,6 +113,32 @@ export default { rem(tag){ this.tags.splice(this.tags.indexOf(tag),1); this.$emit('update:modelValue', this.tags.join(this.splitter)); + }, + async checkAutoComplete(e){ + + if (this.autoComplete !== '' && this.tag.length > 2){ + let resp = await axios.get(this.autoComplete + this.tag); + if (resp.data.OK == true){ + this.searchList = resp.data.data; + } + } + + }, + selectTag(i,e){ + this.tags.push(this.searchList[i]) ; + this.tag = ''; + this.searchList = []; + this.checkDuplicate(); + this.$emit('update:modelValue', this.tags.join(this.splitter)); + }, + incIndex(){ + this.selectedIndex++; + }, + decIndex(){ + this.selectedIndex--; + }, + checkDuplicate(){ + this.tags = [...new Set(this.tags)]; } } } @@ -126,4 +176,23 @@ export default { .tag-select i:hover { color: red; } + +#search-list{ + padding: 0; + list-style: none; + li{ + border-bottom: 1px solid silver; + padding: 4px; + + &:last-child{ + border-bottom: 0; + } + + &.selected{ + background: olive; + } + } + border: 1px solid grey; + border-radius: 6px; +} diff --git a/resources/views/admin/clips/clip-form.blade.php b/resources/views/admin/clips/clip-form.blade.php index 6ace078..5767af6 100644 --- a/resources/views/admin/clips/clip-form.blade.php +++ b/resources/views/admin/clips/clip-form.blade.php @@ -94,6 +94,7 @@ @if(isset($item)) xvalue="{{old('title',implode(',,',$item->tags->pluck('name')->toArray()??''))}}" @endif + auto-complete="{{route('v1.tag.search','')}}/" > diff --git a/resources/views/admin/posts/post-form.blade.php b/resources/views/admin/posts/post-form.blade.php index 52f3686..f99f349 100644 --- a/resources/views/admin/posts/post-form.blade.php +++ b/resources/views/admin/posts/post-form.blade.php @@ -57,6 +57,7 @@ @if(isset($item)) xvalue="{{old('title',implode(',,',$item->tags->pluck('name')->toArray()??''))}}" @endif + auto-complete="{{route('v1.tag.search','')}}/" > {{-- diff --git a/routes/api.php b/routes/api.php index 9f1d337..67c7342 100644 --- a/routes/api.php +++ b/routes/api.php @@ -41,4 +41,7 @@ Route::prefix('v1')->name('v1.')->group( Route::apiResource('web', \App\Http\Controllers\Api\HomeController::class)->only('index'); Route::apiResource('products' , \App\Http\Controllers\Api\ProductController::class)->only('index'); + + Route::get('tag/search/{q}', [\App\Http\Controllers\Api\TagController::class, 'search'])->name('tag.search'); + });