Reputation: 5107
I'm working on an issue with a vue autocomplete function in a laravel site.
I've set my route, controller and blade. Currently, if I inspect the vue component and type in the input, it shows the keywords I'm typing in the console, so I know it's catching what I'm typing.
As for the $groupResult in my controller, if I just dump that on my page then it dumps about 100 results as expected. All I want to do is have an autocomplete on the input that searches within those 100 results.
What exactly am I missing here?
Route
Route::get('campaigns/categories','CampaignsController@searchcategories')->name('campaigns.categories');
Controller:
public function searchcategories(Request $request)
{
$userNum = $this->user;
$category = new categoryService();
$safecategories = $category->info($userNum);
$groupResult = array();
foreach($safecategories->categories as $categories){
$groupItem = array();
$groupItem["group_code"] = $categories->group_code;
$groupItem["group_name"] = $categories->group_name;
array_push($groupResult, $groupItem);
}
return view('campaigns')
->with('groupResult', $groupResult);
}
Blade
<div id="categoryNames">
<input type="text" v-model="keywords">
<ul v-if="results.length > 0">
<li v-for="result in results" :key="result.id" v-text="result.name"></li>
</ul>
</div>
var categoryNames = new Vue({
data() {
return {
keywords: null,
results: []
};
},
watch: {
keywords(after, before) {
this.fetch();
}
},
methods: {
fetch() {
axios.get('campaigns/categories', { params: { keywords: this.keywords } })
.then(response => this.results = response.data)
.catch(error => {});
}
}
}).$mount('#categoryNames');
Upvotes: 0
Views: 2019
Reputation: 5701
If you're simply attempting to filter the existing results there is no need to call the server to do this.
<div id="categoryNames">
<input type="text" v-model="keywords">
<ul v-if="filteredResults.length > 0">
<li v-for="result in filteredResults" :key="result.id" v-text="result.name"></li>
</ul>
</div>
var categoryNames = new Vue({
data() {
return {
keywords: null,
results: []
};
},
computed: {
filteredResults () {
return this.keywords ? this.results.filter(row => row.name.search(new RegExp(`${this.keywords}`, 'i')) !== -1) : this.results
}
}
}).$mount('#categoryNames');
The computed property returns an array of objects (I assumed you are filtering on the object key name). If a keyword is present it uses regex to perform a case insensitive search. If keyword is not present it returns the full results object.
Note, I did not test this code directly so there may be a typo etc. But have implemented many versions of this in a large scale application.
Upvotes: 1