Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vuetify data table pagination custom function

I have JSON data that is already paginated from the server. I have successfully shown the items in my vuetify data table. Now I want to create pagination that loads the next or previous set of data from the server. Unable to add custom function in data table pagination that loads the next set of data from the server.

{
    "current_page": 1,
    "data": [
        {
            "id": 1,
            "contact_person": "person one",
            "email": "[email protected]",
            "phone": 1234567890,
            "gst": "0987654321",
            "user_id": 3,
            "created_at": "2019-08-17 18:30:00",
            "updated_at": "2019-08-17 18:55:32"
        },
        {
            "id": 2,
            "contact_person": "person two",
            "email": "[email protected]",
            "phone": 1234567891,
            "gst": "0987654322",
            "user_id": 3,
            "created_at": "2019-08-17 18:30:00",
            "updated_at": "2019-08-17 18:55:32"
        }
    ],
    "first_page_url": "http://localhost:8000/customer?page=1",
    "from": 1,
    "last_page": 3,
    "last_page_url": "http://localhost:8000/customer?page=3",
    "next_page_url": "http://localhost:8000/customer?page=2",
    "path": "http://localhost:8000/customer",
    "per_page": 2,
    "prev_page_url": null,
    "to": 2,
    "total": 6
}

I want "next_page_url" and "prev_page_url" to be executed on pagination icon click. Thank you in adv :)

like image 635
Amit Biswas Avatar asked Oct 26 '25 09:10

Amit Biswas


1 Answers

You need to provide the total-items property of the data-table - it will be used in conjunction with the pagination.rowsPerPage to calculate the total number of pages. Then, you will need to handle the @update:pagination event whose argument will be the new pagination object:

  pagination:
    {
      descending: !!this.$route.query.desc,
      sortBy: this.$route.query.orderby || 'name',
      rowsPerPage: +this.$route.query.limit || 10,
      page: +this.$route.query.page || 1,
      totalItems: 0,
    }

In this event handler you will fetch the specified page through AJAX and then update the items property of the data-table.

For example:

<template>
      <v-data-table 
        :headers="headers" 
        :items="domains" 
        :rows-per-page-items="listSize" 
        :pagination.sync="pagination" 
        :total-items="totalNumberOfItems" 
        @update:pagination="paginate"
      >
      ....
</template>

<script>
  data()
  {
    return {
      totalNumberOfItems: 0,
      domains: [],
      listSize: [10, 25, 50, 100],
      pagination:
        {
          descending: !!this.$route.query.desc,
          sortBy: this.$route.query.orderby || 'name',
          rowsPerPage: +this.$route.query.limit || 10,
          page: +this.$route.query.page || 1,
          totalItems: 0,
        }
    }
  },
  beforeRouteUpdate (to, from, next)
  {
    this.fetchData(to);
    next();
  },
  methods:
  {
    buildQuery (route)
    {
      const query = route ? route.query : this.$route.query;
      const paginate = this.pagination;

      let params = '?limit=' + paginate.rowsPerPage + '&orderby=' + paginate.sortBy;
      if (paginate.page > 1) params += '&start=' + (this.pagination.page - 1) * this.pagination.rowsPerPage;
      if (paginate.descending) params += '&direction=desc';

      return params;
    },
    fetchData (route)
    {
      this.$ajax(
        {
          method: 'GET',
          url: '/getData/' + this.buildQuery(route),
          okay: (data) =>
          {
            this.totalNumberOfItems = data.resulttotals;
            this.domains = data.items;
          },
          fail: (stat, error) =>
          {
            this.$root.showFailed(error);
          },
        }
      );
    },
      paginate (val)
      {
        // emitted by the data-table when changing page, rows per page, or the sorted column/direction - will be also immediately emitted after the component was created
        const query = this.$route.query;
        const obj = Object.assign({}, query);
        if (val.rowsPerPage !== this.listSize[0]) obj.limit = val.rowsPerPage;
        if (val.descending) obj.desc = 'true';
        else delete obj.desc;
        obj.orderby = val.sortBy;
        obj.page = val.page;
        // check if old and new query are the same - VueRouter will not change the route if they are, so probably this is the first page loading
        let same = true;
        for (let key in query)
        {
          if (query[key] != obj[key])
          {
            same = false;
            break;
          }
        }
        // to handle the case when a KEY exists in OBJ but not in query
        for (let key in obj)
        {
          if (query[key] != obj[key])
          {
            same = false;
            break;
          }
        }
        if (same) this.fetchData(); // page has been manually reloaded in the browser
        else
        {
          this.$router.replace({
            ...this.$router.currentRoute,
            query: obj
          });
        }
      },
  }
</script>
like image 163
IVO GELOV Avatar answered Oct 29 '25 01:10

IVO GELOV



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!