Created
November 6, 2018 22:34
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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