Skip to content

Instantly share code, notes, and snippets.

@aguinaldotupy
Created January 16, 2020 10:12
Show Gist options
  • Select an option

  • Save aguinaldotupy/fee1a6e50f661873246c68408b6321d2 to your computer and use it in GitHub Desktop.

Select an option

Save aguinaldotupy/fee1a6e50f661873246c68408b6321d2 to your computer and use it in GitHub Desktop.
<template>
<div class="col-12">
<div class="row">
<div class="col-12">
<table :class="classTable" cellspacing='0' width='100%'>
<thead>
<tr>
<th v-for="col in columnsComputed" @click="sort(col['data'])">{{ col['name'] }}
<span v-if="col['data'] === current_sort">
<i class="" :class="[current_sort_dir === 'asc' ? 'fe-arrow-up' : 'fe-arrow-down']" />
</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in sortedRows">
<td v-for="col in columnsComputed">{{ row[col['data']] }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<pagination
:current-page="stateCurrentPage"
:total-pages="totalPages"
:items-per-page="elementsPerPage"
:total-items="totalItems"
@page-changed="pageOneChanged">
</pagination>
</div>
</div>
</template>
<script>
import Pagination from "./Pagination";
export default {
name: "Table",
components: {Pagination},
data(){
return {
stateCurrentPage: 1,
current_sort: '',
current_sort_dir: 'asc',
}
},
props: {
currentSortDir: {
type: String,
required: false,
default: undefined,
},
currentSort: {
type: String,
required: false,
default: undefined
},
columns: {
type: Array,
required: false,
default: () => {
return []
}
},
rows: {
type: Array,
required: true
},
classTable: {
type: String,
required: false,
default: 'table table-hover mb-2'
},
currentPage: {
type: Number,
required: false,
default: 1,
coerce: (val) => parseInt(val)
},
elementsPerPage: {
type: Number,
required: false,
default: 5,
coerce: (val) => parseInt(val)
},
},
created() {
if(this.currentSort !== undefined){
this.current_sort = this.currentSort;
} else {
this.current_sort = this.columnsComputed[0]
}
if(this.currentSortDir !== undefined){
this.current_sort_dir = this.currentSortDir
}
},
methods: {
numberPages() {
return Math.ceil(this.rows.length / this.elementsPerPage);
},
sort(sort) {
//if s == current sort, reverse
if(sort === this.current_sort) {
this.current_sort_dir = this.current_sort_dir === 'asc' ? 'desc' : 'asc';
}
this.current_sort = sort;
},
pageOneChanged (pageNum) {
this.stateCurrentPage = pageNum;
this.$emit('page-changed', this.stateCurrentPage);
}
},
computed: {
sortedRows() {
return this.rows.sort((a, b) => {
let modifier = 1;
if(this.current_sort_dir === 'desc') modifier = -1;
if(a[this.current_sort] < b[this.current_sort]) return -1 * modifier;
if(a[this.current_sort] > b[this.current_sort]) return 1 * modifier;
return 0;
}).filter((row, index) => {
let start = (this.stateCurrentPage-1)*this.elementsPerPage;
let end = this.stateCurrentPage*this.elementsPerPage;
if(index >= start && index < end) return true;
});
},
columnsComputed() {
if (this.rows.length === 0) {
console.debug("without rows");
return [];
} else if(this.columns.length > 0){
console.debug("Columns props", this.columns);
return this.columns;
}
let columns;
columns = [];
Object.keys(this.rows[0]).forEach((key) => {
columns.push({name: key, data: key})
});
console.debug("Columns in rows", columns);
return columns;
},
totalPages(){
return this.numberPages();
},
totalItems(){
return this.rows.length;
}
}
}
</script>
<style scoped>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment