Skip to content

Instantly share code, notes, and snippets.

@easierbycode
Last active March 29, 2019 03:35
Show Gist options
  • Save easierbycode/f1dc159436f8a85fe68219863464710e to your computer and use it in GitHub Desktop.
Save easierbycode/f1dc159436f8a85fe68219863464710e to your computer and use it in GitHub Desktop.
<template>
<table class='table is-fullwidth is-striped is-hoverable is-narrow'>
<sorted :songs="songs" @sortedSongs='sort_songs' />
<paginated :items='sortedSongs' />
</table>
</template>
<script>
import MusicData from '@/assets/list.json'
import PaginatedTableBody from '@/components/PaginatedTableBody'
import MusicSort from '@/components/MusicSort'
export default {
components: {
'paginated': PaginatedTableBody,
'sorted': MusicSort
},
data() {
return {
songs: MusicData,
sortedSongs: MusicData
}
},
methods: {
sort_songs(data) {
this.sortedSongs = data;
}
}
}
</script>
<style>
</style>
<template>
<thead>
<th style='width: 30%'>
<a @click="change_sort('artist')">
Artist
<font-awesome-icon icon='chevron-up' v-if="sortBy === 'artist' && sortDirection === 'asc'"/>
<font-awesome-icon icon='chevron-down' v-if="sortBy === 'artist' && sortDirection === 'desc'"/>
</a>
</th>
<th style='width: 30%'>
<a @click="change_sort('title')">
Title
<font-awesome-icon icon='chevron-up' v-if="sortBy === 'title' && sortDirection === 'asc'"/>
<font-awesome-icon icon='chevron-down' v-if="sortBy === 'title' && sortDirection === 'desc'"/>
</a>
</th>
<th style='width: 30%'>
<a @click="change_sort('album')">
Album
<font-awesome-icon icon='chevron-up' v-if="sortBy === 'album' && sortDirection === 'asc'"/>
<font-awesome-icon icon='chevron-down' v-if="sortBy === 'album' && sortDirection === 'desc'"/>
</a>
</th>
<th style='width: 20%'>
<a @click="change_sort('genre')">
Genre
<font-awesome-icon icon='chevron-up' v-if="sortBy === 'genre' && sortDirection === 'asc'"/>
<font-awesome-icon icon='chevron-down' v-if="sortBy === 'genre' && sortDirection === 'desc'"/>
</a>
</th>
</thead>
</template>
<script>
export default {
props: {
songs: {
type: Array,
required: true
}
},
data() {
return {
sortBy: '',
sortDirection: 'asc'
}
},
methods: {
change_sort(column) {
if (this.sortBy === column && this.sortDirection === 'asc') {
this.sortDirection = 'desc';
} else {
this.sortDirection = 'asc';
}
this.sortBy = column;
this.sort_songs();
},
sort_songs() {
if (this.sortBy === '') {
this.$emit('sortedSongs', this.songs);
return this.songs;
}
let sortModifier = (this.sortDirection === 'asc') ? 1 : -1;
let sortedSongs = this.songs.slice().sort((a, b) => {
let colA = a[this.sortBy].toUpperCase();
let colB = b[this.sortBy].toUpperCase();
if (colA < colB) {
return -1 * sortModifier;
}
if (colA > colB) {
return 1 * sortModifier;
}
return 0;
});
this.$emit('sortedSongs', sortedSongs);
}
}
}
</script>
<style>
</style>
<template>
<tbody>
<template v-for='(song, index) in paginatedItems'>
<tr v-bind:key="index">
<td>{{ song.artist }}</td>
<td>{{ song.title }}</td>
<td>{{ song.album }}</td>
<td>{{ song.genre }}</td>
</tr>
</template>
</tbody>
</template>
<script>
export default {
props: {
items: {
type: Array,
required: true
},
per_page: {
type: Number,
required: false,
default: 50
}
},
data() {
return {
page: 1
}
},
computed: {
totalPages() {
return Math.ceil(this.items.length / this.per_page);
},
paginatedItems() {
return this.items.slice(0, this.page * this.per_page);
},
created() {
window.addEventListener('scroll', e => {
if (this.page >= this.totalPages) return;
if (window.innerHeight + window.pageYOffset >= document.body.offsetHeight - 100) {
this.page++;
}
})
}
},
watch: {
items() {
this.page = 1;
}
}
}
</script>
<style>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment