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 :)
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With