Skip to content

Instantly share code, notes, and snippets.

@andrii-trush
Created November 6, 2018 22:34
Show Gist options
  • Save andrii-trush/2007a82a62811afe9e4f9ba9923dfff3 to your computer and use it in GitHub Desktop.
Save andrii-trush/2007a82a62811afe9e4f9ba9923dfff3 to your computer and use it in GitHub Desktop.
VueJS component for Laravel pagination + column sortable (https://github.com/Kyslik/column-sortable)
<template>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th class="text-nowrap">
<a href="#" @click.prevent="sortChange('name')">
<span>Name</span>
<i class="fa" :class="getClass('name', 'alpha')"></i>
</a>
</th>
<th class="text-nowrap">
<a href="#" @click.prevent="sortChange('email')">
<span>E-mail</span>
<i class="fa" :class="getClass('email', 'alpha')"></i>
</a>
</th>
<th class="text-nowrap">
<a href="#" @click.prevent="sortChange('created_at')">
<span>Created</span>
<i class="fa" :class="getClass('created_at', 'numeric')"></i>
</a>
</th>
</tr>
</thead>
<tbody>
<tr v-for="user in laravelData.data">
<td>{{user.name}}</td>
<td>{{user.email}}</td>
<td class="text-nowrap">{{user.created_at}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3" class="text-right">
<pagination :limit="5" :data="laravelData"
@pagination-change-page="pageChange"></pagination>
</td>
</tr>
</tfoot>
</table>
</div>
</template>
<script>
/**
* @file VueJS component for Laravel pagination + column sortable by {@link https://github.com/Kyslik/column-sortable|Kyslik}
* @author Tdev
* @version 1.0.0
* @copyright TDev 2018
* @see [Laravel pagination]{@link https://laravel.com/docs/5.6/pagination}
* @see [A Vue.js pagination component for Laravel pagination]{@link https://github.com/gilbitron/laravel-vue-pagination}
* @see [Package for handling column sorting in Laravel by Kyslik]{@link https://github.com/Kyslik/column-sortable}
*/
export default {
name: "ColumnSortable",
/**
* Get data on instance created {@link https://vuejs.org/v2/api/#created}
*/
created() {
this._getData();
},
/**
* @see [The data object for the Vue instance]{@link https://vuejs.org/v2/api/#data}
* @return {Object}
*/
data() {
let search = this._getSearchParams();
/**
* Default data for instance
*/
let dataObject = {
direction: 'asc',
laravelData: {},
sort: null,
loading: false,
page: 1
};
/**
* If search params presents. Set them as default before sending first request for data getting
*/
if (Object.keys(search).length > 0) {
for (let prop in search) {
if (search.hasOwnProperty(prop) && typeof dataObject[prop] !== "undefined") {
dataObject[prop] = search[prop]
}
}
}
return dataObject
},
methods: {
/**
* Pagination event @see https://github.com/gilbitron/laravel-vue-pagination
* @param {number} page
*/
pageChange(page) {
this.page = page;
this._getData();
},
/**
* On click search like Blade extension @see https://github.com/Kyslik/column-sortable#blade-extension
* @param {string} key
*/
sortChange(key) {
this.page = 1;
this.direction = this.sort !== key || this.direction === 'desc' ? 'asc' : 'desc';
this.sort = key;
this._getData();
},
/**
* @param {string} key
* @param {string} type
*/
getClass(key, type) {
if (key === this.sort) {
return 'fa-sort-' + type + '-' + this.direction
}
return 'fa-sort'
},
/**
* @private
* @async
*/
async _getData() {
// Prepare search params
let params = {page: this.page}, vm = this;
if (this.sort !== null) {
params['sort'] = this.sort;
params['direction'] = this.direction;
}
// Change url in browser with current searc params
window.history.replaceState(params, null, vm._fullUrl(params));
// Vue.prototype.$http = axios; in main js file
await vm.$http.get('users', {params: params}).then(res => {
vm.laravelData = res.data;
}).catch(err => {
// Catch error
})
},
/**
* Get full url for [Window history]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/history}
* @private
* @param {Object} params
* @return {string}
*/
_fullUrl(params) {
return window.location.protocol + '//' + window.location.hostname + window.location.pathname + '?' + this._serialize(params)
},
/**
* @description From object search params to url query string.
* @private
* @param {Object} params
* @return {string}
*/
_serialize(params) {
let str = [];
for (let p in params)
if (params.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(params[p]));
}
return str.join("&");
},
/**
* @private
* @description Parse search params from url
* @see [StackOverflow answer]{@link https://stackoverflow.com/questions/2090551/parse-query-string-in-javascript#answer-7826782}
* @return {object}
*/
_getSearchParams() {
let search = window.location.search;
let args = search.substring(1).split('&'), argsParsed = {}, i, arg, kvp, key, value, argsLength;
for (i = 0, argsLength = args.length; i < argsLength; i++) {
arg = args[i];
if (-1 === arg.indexOf('=')) {
argsParsed[decodeURIComponent(arg).trim()] = true;
}
else {
kvp = arg.split('=');
key = decodeURIComponent(kvp[0]).trim();
value = decodeURIComponent(kvp[1]).trim();
argsParsed[key] = value;
}
}
return argsParsed;
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment