JSFiddle - React, Tailwind, and code Playground
by Manna
HTML
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.3/lodash.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app" class="container">
<h1>
Active Users
<button v-if="users.length" @click="fetchUsers" class="btn btn-primary">
<span class="glyphicon glyphicon-refresh"></span>
Refresh with latest activity
</button>
</h1>
<input v-model="filterQuery" placeholder="Filter users" class="form-control">
<table v-if="filteredUsers.length" class="table">
<thead>
<tr>
<th v-for="column in tableColumns">
<a @click="orderByField = column.field">
{{ column.title }}
</a>
</th>
</tr>
</thead>
<tbody is="transition-group" name="user-list">
<tr v-for="user in filteredUsers" :key="user.id">
<td v-for="column in tableColumns">
{{ getField(user, column.field) }}
</td>
</tr>
</tbody>
</table>
<p v-if="statusMessage" class="well">
{{ statusMessage }}
</p>
</div>
CSS
th a { cursor: pointer; }
h1 button { float: right; }
.user-list-enter, .user-list-leave-active {
display: none;
}
.user-list-move {
transition: transform .5s;
}
JavaScript
new Vue({
el: '#app',
data: {
tableColumns: [
{
title: 'Name',
field: 'name'
}, {
title: 'Company',
field: 'company.name'
}, {
title: 'Website',
field: 'website'
}
],
users: [],
filterQuery: '',
orderByField: 'name',
fetchError: false
},
computed: {
filteredUsers: function () {
var vm = this
return _.orderBy(
vm.users.filter(function (user) {
var regex = new RegExp(vm.filterQuery, 'i')
return (
regex.test(user.name) ||
regex.test(user.company.name) ||
regex.test(user.website)
)
}),
vm.orderByField
)
},
statusMessage: function () {
if (this.fetchError) {
return 'There was a problem fetching the users. JSONPlaceholder might be down.'
}
if (this.users.length) {
if (!this.filteredUsers.length) {
return 'Sorry, no matching users were found.'
}
} else {
return 'Loading...'
}
}
},
created: function () {
this.fetchUsers()
},
methods: {
fetchUsers: function () {
var vm = this
vm.users = []
vm.fetchError = false
fetch('https://jsonplaceholder.typicode.com/users')
.then(function (response) { return response.json() })
.then(function (users) { vm.users = users })
.catch(function () { vm.fetchError = true })
},
getField: function (object, field) {
return _.at(object, field)[0]
}
}
})