Skip to content

Instantly share code, notes, and snippets.

@autotrof
Last active April 21, 2023 04:34
Show Gist options
  • Save autotrof/6cc472dcb4e9bc258505a68e95843842 to your computer and use it in GitHub Desktop.
Save autotrof/6cc472dcb4e9bc258505a68e95843842 to your computer and use it in GitHub Desktop.
<script>
import axios from 'axios'
export default{
props:{
listPerPage:{
type:Array,
default:()=>[10,25,50]
},
perPage:{
type:Number,
default:10
},
page:{
type:Number,
default:1
},
search:{
type:String,
default:""
},
sort:{
type:Number,
default:0
},
sortDir:{
type:String,
default:"asc"
},
listKolom:{
type:Array,
},
url:{
required:true,
type:String,
default:""
},
dataPost:{
type:Object,
default:()=>{
return{}
}
}
},
data(){
return {
_listPerPage:this.listPerPage,
_perPage:this.perPage,
_page:this.page,
_search:this.search,
_sort:this.sort,
_sortDir:this.sortDir,
_listKolom:this.listKolom,
data:[],
recordsTotal:0,
recordsFiltered:0,
loading:false,
responseAjax:null
}
},
methods:{
updateSort(index_kolom){
if(this._sort == index_kolom){
this._sortDir = (this._sortDir == "asc" ? "desc" : "asc")
}else{
this._sortDir = 'asc'
this._sort = index_kolom
}
},
getData(){
const that = this
this.loading = true
axios.post(this.url,this._dataPost)
.then(response=>{
that.responseAjax = response
that.data = response.data.data
that.recordsTotal = response.data.recordsTotal
that.recordsFiltered = response.data.recordsFiltered
that.loading = false
that.$emit('onDataGet',response.data.data)
})
.catch(response=>{
that.loading = false
that.responseAjax = response
})
},
gotoPage(p){
this._page = p
}
},
watch:{
_page(val){
this.getData()
},
_perPage(val){
if(this._page!==1) this._page = 1
else this.getData()
},
_sort(val){
this.getData()
},
_sortDir(val){
this.getData()
},
},
computed:{
_dataPost(){
return {
sort:this._sort,
sortDir:this._sortDir,
page:this._page,
perPage:this._perPage,
search:this._search,
...this.dataPost
}
},
total_page(){
return Math.ceil(this.recordsFiltered/this._perPage)
}
},
mounted(){
this.$nextTick(this.getData)
}
}
</script>
<template>
<div class="relative items-center">
<div class="flex item-center mb-3">
<select v-model="_perPage" :disabled="loading" class="py-1 text-sm px-2">
<option v-for="pp in _listPerPage" :value="pp" :key="pp">{{pp}}</option>
</select>
<input type="text" placeholder="search" class="w-36 ml-auto py-1 text-sm px-2" v-debounce:400ms.lock="getData" v-model="_search" :readonly="loading">
</div>
<div v-if="loading" class="absolute top-0 left-1/2 -translate-x-1/2 px-4 py-3 bg-white shadow-md rounded font-semibold">LOADING</div>
<div v-if="loading" class="w-full absolute top-14 bg-white opacity-60" style="height: calc(100% - 6.5rem);"></div>
<table class="table">
<thead>
<tr>
<th v-for="(kolom,index_kolom) in _listKolom" :key="kolom" v-on:click="updateSort(index_kolom)">
<div class="flex whitespace-nowrap cursor-pointer">
<span class="mr-auto">{{kolom}}</span>
<svg v-if="_sort==index_kolom && _sortDir=='asc'" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12" />
</svg>
<svg v-else-if="_sort==index_kolom && _sortDir=='desc'" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4" />
</svg>
</div>
</th>
</tr>
</thead>
<tbody>
<slot v-if="data.length>0" :data="data"></slot>
<tr v-else>
<td colspan="999" class="text-center">
Data Not Found
</td>
</tr>
</tbody>
</table>
<div class="flex items-center mt-2">
<div class="ml-auto shadow rounded-md overflow-hidden border-t-[1px]">
<button v-for="p in total_page" :key="p" v-on:click="gotoPage(p)" :disabled="loading" :class="{'bg-primary-light hover:bg-primary border-primary-light':_page==p,'bg-white hover:bg-gray-100 border-gray-100':_page!=p}" class="unstyled duration-100 border-x-[1px] px-3 py-2">{{p}}</button>
</div>
</div>
</div>
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment