Vue js: Vuetify server side Datatable search filter not working

BGTabulation BGTabulate picture BGTabulation BGTabulate · Dec 4, 2017 · Viewed 22.2k times · Source

I'm using vuetify for my datatable. Pagination and sort are working except the search filter. The response data from search filter is correct but the problem is its not rendering the response to my template. In vuetify docs theres only have for pagination and sort. I'm trying to implement the search function via server-side.

My User.vue

export default{
    data () {
    return {
      max25chars: (v) => v.length <= 25 || 'Input too long!',
      tmp: '',
      search: '',
      totalItems: 0,
      pagination: {
        rowsPerPage: 1,
        search: ''
      },
      headers: [
        {
          text: 'Name',
          sortable: true,
          value: 'name',
          align: 'left'
        },
        {
          text: 'Email Add',
          sortable: true,
          value:'email',
          align: 'left'
        },
        {
          text: 'Roles',
          sortable: true,
          value:'roles_permissions',
          align: 'left'
        },
        {
          text: 'Date joined',
          sortable: true,
          value:'created_at',
          align: 'left'
        }
      ],
      items: [],
      loading: false,
      timer: null
    }
  },
  watch:{
    pagination:{
            handler(){
                this.getDataFromApi()
          .then(data => {
            const self = this;
            self.items = data.items;
            self.totalItems = data.total;
          })
            },
      deep: true
    }
  },
  mounted(){
    this.getDataFromApi()
        .then(data => {
            this.items = data.items;
        this.totalItems = data.total;
        });
  },
  methods:{
    getDataFromApi(search_val){
        this.loading = true;
      return new Promise((resolve, reject) => {
        const { sortBy, descending, page, rowsPerPage } = this.pagination
                const search = this.search;
        //console.log(search);
        clearTimeout(this.timer);
        this.timer = setTimeout(function(){

          axios({
            url: '/prod/api/user_table',
            method:'post',
            data:{
              sortBy : sortBy,
              descending: descending,
              page : page,
              rowsPerPage : rowsPerPage,
              search_val : search
            }
          })
          .then(response=>{
            if(response.status == 200){

              let items = response.data.data;
              const total = response.data.totalRecords;
              this.loading = false;
              resolve({
                items,
                total
              });
            }
          })
          .catch(error=>{
            if(error.response){
              console.log(error.response);
            }
          })
        },1000);
      })
    },
    fetchDataFromApi(value){
        //console.log(value);
    }
  },
  created(){

  }
}

Here is my back end side using laravel

public function dataTable(Request $request){
    //return Datatable::eloquent(User::query())->make(true);
    $sortBy = $request->sortBy;
    $descending = $request->descending;
    $page = $request->page;
    $rowsPerPage = $request->rowsPerPage;
    $search_val = $request->search_val;

    //echo $rowsPerPage;
    if($descending){
        $orderedBy = 'desc';
    }else{
        $orderedBy = 'asc';
    }
    $start = ($page - 1) * $rowsPerPage;


    /*$totalRec = User::all();
    if(empty(trim($search_val))){
        $user = User::orderBy($sortBy,$orderedBy)->skip($start)->take($rowsPerPage)->get();
    }else{
        $user = User::where([

        ]);
    }*/

    $query = User::query();
    $column = ['name', 'email'];
    foreach ($column as $col) {
       $query->orWhere($col, 'LIKE','%'.$search_val.'%');
    }
    $query->orderBy($sortBy,$orderedBy)->skip($start)->take($rowsPerPage);
    $arr_items = [];
    foreach ($query->get()->toArray() as $shit => $v) {
        $arr_items['data'][] = array(
            'value' => $v['id'],
            'name' => $v['name'],
            'email' => $v['email'],
            'roles_permissions' => '',
            'created_at' => $v['created_at']
        );
    }
    $arr_items['totalRecords'] = User::count();
    return response()->json($arr_items);
}

Answer

Eliyas Hossain picture Eliyas Hossain · Jun 17, 2018

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
            ];
         }
    }