Vue js: Vuetify server side Datatable search filter not working
server side search & sort of datatable in vuetify.js
If we need server side search and sort in vuetify.js datatable, we have to make some changes in vuejs part.
import {environment} from '../../environment';export default { name: "Category", data() { return { categories: [], search: '', total: 0, loading: false, pagination: {}, headers: [ {text: 'ID', value: 'id'}, {text: 'Name', value: 'name'}, {text: 'Actions', value: 'name', sortable: false, align: 'center'} ], rowsPerPageItems: [5, 10, 20, 50, 100], } }, watch: { pagination { this.getCategoriesByPagination(); }, search() { this.getCategoriesByPagination(); } }, methods: { getCategoriesByPagination() { this.loading = true; // get by search keyword if (this.search) { axios.get(`${environment.apiUrl}/category-filter?query=${this.search}&page=${this.pagination.page}&per_page=${this.pagination.rowsPerPage}`) .then(res => { this.categories = res.data.data; this.total = res.data.meta.total; }) .catch(err => console.log(err.response.data)) .finally(() => this.loading = false); } // get by sort option if (this.pagination.sortBy && !this.search) { const direction = this.pagination.descending ? 'desc' : 'asc'; axios.get(`${environment.apiUrl}/category-order?direction=${direction}&sortBy=${this.pagination.sortBy}&page=${this.pagination.page}&per_page=${this.pagination.rowsPerPage}`) .then(res => { this.loading = false; this.categories = res.data.data; this.total = res.data.meta.total; }); } if(!this.search && !this.pagination.sortBy) { axios.get(`${environment.apiUrl}/category?page=${this.pagination.page}&per_page=${this.pagination.rowsPerPage}`) .then(res => { this.categories = res.data.data; this.total = res.data.meta.total; }) .catch(err => console.log(err.response.data)) .finally(() => this.loading = false); } } }}
in html part
<v-text-field v-model="search" append-icon="search" label="Search" single-line hide-details ></v-text-field><v-data-table :headers="headers" :items="categories" :pagination.sync="pagination" :total-items="total" :rows-per-page-items="rowsPerPageItems" :loading="loading" ></v-data-table>
in Laravel part, i used laravel scout
package.
Controller
/** * Get category * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection */public function getAll(){ $per_page = empty(request('per_page')) ? 10 : (int)request('per_page'); $categories = Category::latest()->paginate($per_page); return CategoryResource::collection($categories);}/** * Get category by search results * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection */public function getBySearch(){ $per_page = empty(request('per_page')) ? 10 : (int)request('per_page'); $categories = Category::search(request()->query('query'))->paginate($per_page); return CategoryResource::collection($categories);}/** * Get category by sorting * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection */public function getByOrder(){ $per_page = empty(request('per_page')) ? 10 : (int)request('per_page'); $direction = request()->query('direction'); $sortBy = request()->query('sortBy'); $categories = Category::orderBy($sortBy, $direction)->paginate($per_page); return CategoryResource::collection($categories);}
Route
Route::get('category', 'Api\CategoryController@getAll'); Route::get('category-filter', 'Api\CategoryController@getBySearch'); Route::get('category-order', 'Api\CategoryController@getByOrder');
Model
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Category extends Model { use Searchable; /** * Get the indexable data array for the model. * * @return array */ public function toSearchableArray() { return [ 'name' => $this->name ]; } }
To enable server-side search to work don't pass the search prop to v-data-table. Otherwise the datatable pagination and search are client side even if you pass the "totalItems" prop.
You can pass the search prop but the initial value needs to be null. I tried it first with an empty string and it didn't work, at least in my case.