var url ='https://api.mockaroo.com/api/b5f38710?count=20&key=cdbbbcd0'
new Vue({
el: '#datagrid',
data: {
columns: {
id: 'ID',
nick: 'Nick name',
first: 'First name',
last: 'Last name'
},
users: [],
query: '',
prevKey: 'id',
orderDesc: false
},
methods: {
async loadUsers () {
var result = await axios.get(url)
this.users = result.data
this.query = ''
this.prevKey = 'id'
this.orderDesc = false
},
clearQuery () {
this.query = ''
},
sortUsers (e) {
var key = e.target.dataset.key
if (this.prevKey === key) {
this.users.reverse()
this.orderDesc = !this.orderDesc
} else {
this.users = _.sortBy(this.users, key)
this.orderDesc = false
this.prevKey = key
}
},
filterUsers (users) {
return _.filter(users, user =>
_.find(user, prop =>
new RegExp(this.query, 'i').test(prop)
)
)
},
updateQuery: _.debounce(function (e) {
this.query = e.target.value
}, 350)
}
})
#datagrid {
width: 98%;
margin: 10px auto;
padding: 2px;
background-color: white;
border: 2px solid #3F51B5;
overflow: hidden;
}
.table {
display: table;
width: 100%;
font-size: 14px;
font-family: Arial, sans-serif;
color: #263238;
}
.thead {
display: table-header-group;
}
.tbody {
display: table-row-group;
}
.tr {
display: table-row;
}
.td {
display: table-cell;
position: relative;
}
.thead .td {
padding: 5px 14px;
background-color: #3F51B5;
color: white;
font-weight: bold;
text-align: center;
cursor: pointer;
}
.tbody .td {
padding: 4px;
color: #263238;
text-align: center;
}
.tr .td:not(:last-child) {
border-right: 2px solid white;
}
.tbody .tr:hover .td {
background-color: #C5CAE9;
}
.tbody .tr:hover .td:not(:last-child) {
border-right: 2px solid #C5CAE9;
}
.tools {
margin: 10px;
box-sizing: border-box;
}
.tools:after {
content: "";
display: block;
clear: both;
}
.source {
display: block;
float: left;
}
.search {
float: right;
}
.thead .tdarrow {
paddingdisplay: 5px 14px;inline-block;
background-colorposition: #3F51B5;absolute;
colorwidth: white;0;
font-weightheight: bold;0;
textmargin-alignleft: center;5px;
cursormargin-top: pointer;
}5px;
.tbody .td {
border-left: 6px padding:solid 4px;transparent;
colorborder-right: #263238;6px solid transparent;
text-aligntransition: center;all .6s;
}
.tbodyasc .tr:last{
border-childbottom: 6px solid white;
}
.tddesc {
paddingborder-bottomtop: 0;6px solid white;
}
.users-move {
transition: transform .6s;
}
.users-enter-active, .users-leave-active {
transition: all .6s;
}
.users-enter, .users-leave-to {
opacity: 0;
transform: translateY(30px);
}
.arrow {
display: inline-block;
position: absolute;
width: 0;
height: 0;
margin-left: 5px;
margin-top: 5px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
transition: all .6s;
}
.asc {
border-bottom: 6px solid white;
}
.desc {
border-top: 6px solid white;
}
<script src="https://unpkg.com/[email protected]/underscore-min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
<div id="datagrid">
<div class="tools">
<button class="source" @click="loadUsers">
Load some fake data from mockaroo.com
</button>
<div class="search">
<input type="text" @input="updateQuery" :value="query">
<button class="clear" @click="clearQuery">clear</button>
</div>
</div>
<div class="table">
<div class="thead" @click="sortUsers">
<div class="tr">
<span class="td" data-key="id">
ID
<span
v-if="prevKey === 'id'"
:class="['arrow'for="(col, orderDesc ? 'desc' : 'asc']">
</span>
</span>
key) in <spancolumns" class="td" data-key="nick">
Nick name
<span
v-if="prevKey === 'nick'"
:class="['arrow', orderDesc ? 'desc' : 'asc']">
</span>
</span>
<span class="td" data-key="first">
First name
<span
v-if="prevKey === 'first'"
:class="['arrow', orderDesc ? 'desc' : 'asc']">
</span>
</span>key=key>
<span class="td" data-key="last">
{{ Lastcol name}}
<span
v-if="prevKey === 'last'"key"
:class="['arrow', orderDesc ? 'desc' : 'asc']">
</span>
</span>
</div>
</div>
<transition-group name="users" tag="div" class="tbody">
<div class="tr" v-for="row in filterUsers(users)" :key="row.id">
<span class="td" v-for="column in row">{{ column }}</span>
</div>
</transition-group>
</div>
</div>