How to sort dates in table using vue.js
I solved this by making a TableHeader
component it says semantic cause i used semantic-ui... sorry for the spanglish in the code, must of 'em are cognates anyway. Also, this code is working, but if you see improvements to the code/answer let me know please!
As you can see, i really don't sort at front... i make a new request with the sorted items.
<template> <th @click="cycleSort(sth, $event)"> <span><span>{{ sth.texto }} </span><i class="icon" :class="sth.icon"></i><sub v-if="sth.posicion > 0"><small>{{ sth.posicion }}</small></sub></span> </th></template><script>export default { name: "SemanticTableHeader", props: { sth : { type : Object, default: () => {} }, sths : { type : Array, default: () => { return [] } }, filtrosOrder : { type : Array, default: () => { return [] } }, isSearching : { type : Boolean, required : true } }, methods: { cycleSort(sth, event) { if(this.isSearching == true){ return false; } switch (sth.direction) { case null: sth.direction = 'asc'; sth.icon = 'sort ascending'; break; case 'asc': sth.direction = 'desc'; sth.icon = 'sort descending'; break; case 'desc': sth.direction = null; sth.icon = 'sort disabled'; break; default: sth.direction = null; sth.icon = 'sort disabled'; } this.manejaCambioHeader(sth); }, manejaCambioHeader: _.debounce(function (sth) { var self = this; console.log(this.filtrosOrder); let auxUser = _.find(this.filtrosOrder, function(o) { return o.id == sth.id; }); if( auxUser != null ){ auxUser.direction = sth.direction; if(auxUser.direction == null){ for (var i=0 ; i < this.filtrosOrder.length ; i++){ if (this.filtrosOrder[i].id === auxUser.id) { let auxSths = _.find(self.sths, function(o) { return o.id == sth.id; }); auxSths.posicion = 0; this.filtrosOrder.splice(i, 1); } } } }else{ this.filtrosOrder.push({ id: sth.id, direction: sth.direction }); } for (var i=0 ; i < self.filtrosOrder.length; i++){ let auxSths = _.find(this.sths, function(o) { return o.id == self.filtrosOrder[i].id; }); auxSths.posicion = i + 1; } console.log(this.filtrosOrder); this.$emit('sortHeaderChanged', sth); }, 400), },}</script><style lang="css" scoped>th span{ cursor: pointer !important; -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */}i.icon{ margin: 0em -0.2em 0em 0em;}</style>
In my Index views i just load the component and use it like this
<template> <table> <thead> <tr> <semantic-table-header v-for="sth in sths" :key="sth.key" :sth="sth" :sths="sths" :isSearching="isSearching" :filtrosOrder="filtros.orderBy" @sortHeaderChanged="fetchIndex" ></semantic-table-header> <th></th> </tr> </thead> <tbody> <tr v-for="contact in contacts" :key="contact.key" :class="[contact.justAdded ? 'justAdded' : '']"> </tr> </tbody> </table></template>export default { name: "ContactsIndex", data:() => ({ filtros:{ orderBy:[ { id: 'nombre', direction: 'asc' } // orderBy is calculated through the headers component ] }, sths:[ { id: 'nombre', texto: 'Nombre', icon: 'sort ascending', direction: 'asc', posicion: 1 }, { id: 'telefonos', texto: 'Teléfono(s)', icon: 'sort disabled', direction: null, posicion: 0 }, { id: 'emails', texto: 'Correo Electrónico(s)', icon: 'sort disabled', direction: null, posicion: 0 }, { id: 'estatus', texto: 'Estatus', icon: 'sort disabled', direction: null, posicion: 0 } ], contacts: [], }), created() { this.fetchIndex(); }, methods: { resetFilters() { // this function is to reset filters and headers Object.assign(this.$data.filtros, this.$options.data().filtros); this.$data.sths = this.$options.data().sths; this.fetchIndex(); }, fetchIndex() { let self = this; // this is a wrapper i made for an axios post call you can replace it with a normal call singleIndexRequest('/api/v1/contacts/index', self).then(response => { self.contacts = response.data.contacts; }); }, }}