Install & Download:
# NPM
$ npm i vue-datasetDescription:
The vue-dataset library provides a set of components that allows you to filter, sort, and paginate any data (like lists, cards, tables) in Vue applications.
Basic Usage:
1. Import components into your app.
import {
Dataset,
DatasetItem,
DatasetInfo,
DatasetPager,
DatasetSearch,
DatasetShow
} from 'vue-dataset';2. The example shows how to filter, sort, and paginate datasets in a card layout.
<template>
<div>
<h3>Custom filters</h3>
<div class="row mb-1">
<div class="col-md-6 mb-2 mb-md-0">
<div class="btn-group">
<button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === '' && 'active']" @click.prevent="onlineFilter = ''">
<span class="badge bg-white text-secondary">{{ users.length }}</span> All
</button>
<button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Active' && 'active']" @click.prevent="onlineFilter = 'Active'">
<span class="badge bg-success text-white">{{ filterList(users, {'onlineStatus': 'Active'}).length }}</span> Active
</button>
<button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Away' && 'active']" @click.prevent="onlineFilter = 'Away'">
<span class="badge bg-warning text-white">{{ filterList(users, {'onlineStatus': 'Away'}).length }}</span> Away
</button>
<button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Do not disturb' && 'active']" @click.prevent="onlineFilter = 'Do not disturb'">
<span class="badge bg-danger text-white">{{ filterList(users, {'onlineStatus': 'Do not disturb'}).length }}</span> Do not disturb
</button>
<button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Invisible' && 'active']" @click.prevent="onlineFilter = 'Invisible'">
<span class="badge bg-secondary text-white">{{ filterList(users, {'onlineStatus': 'Invisible'}).length }}</span> Invisible
</button>
</div>
</div>
<div class="col-md-6">
<input type="text" class="form-control" placeholder="Name starts with" @input="startWithInput($event)">
</div>
</div>
<hr class="mb-1" />
<h3>Sorting</h3>
<div class="row mb-2">
<div class="col-md-6 mb-2 mb-md-0">
<button type="button" class="btn btn-outline-secondary" @click="firstNameAsc = !firstNameAsc">First name {{ firstNameAsc ? 'asc' : 'desc' }}</button>
</div>
</div>
<hr />
<dataset
v-slot="{ ds }"
:ds-data="users"
:ds-filter-fields="{ onlineStatus: onlineFilter, name: startsWithFilter }"
:ds-sortby="[sortFirstName]"
:ds-search-in="['balance', 'birthdate', 'name', 'company', 'email', 'phone', 'address', 'favoriteAnimal']"
:ds-search-as="{ birthdate: searchAsEuroDate }"
>
<div class="row mb-2">
<div class="col-md-6 mb-2 mb-md-0">
<dataset-show />
</div>
<div class="col-md-6">
<dataset-search ds-search-placeholder="Search..." :wait="300" />
</div>
</div>
<div class="row">
<div class="col-md-12">
<dataset-item class="form-row mb-3" style="overflow-y: auto; max-height: 400px;">
<template v-slot="{ row, rowIndex }">
<div class="col-md-4">
<div class="card mb-2">
<div class="card-body pt-3 pb-2 px-3">
<h5 class="card-title text-truncate mb-2" :title="`Index: ${ rowIndex }`">
<span :class="['font-16', statusClass[row.onlineStatus]]">⬤</span> {{ row.name }}
</h5>
<h6 class="card-subtitle text-truncate text-muted">{{ row.email }}</h6>
<p class="card-text text-truncate mb-0">{{ row.balance }}</p>
<p class="card-text text-truncate text-right">{{ isoDateToEuroDate(row.birthdate) }}</p>
</div>
</div>
</div>
</template>
<template v-slot:noDataFound>
<div class="col-md-12 pt-2">
<p class="text-center">No results found</p>
</div>
</template>
</dataset-item>
</div>
</div>
<div class="d-flex flex-md-row flex-column justify-content-between align-items-center">
<dataset-info class="mb-2 mb-md-0" />
<dataset-pager />
</div>
</dataset>
</div>
</template>export default {
name: 'Example',
data: function () {
return {
users: users,
startsWith: '',
onlineFilter: '',
statusClass: {
Active: 'text-success',
Away: 'text-warning',
'Do not disturb': 'text-danger',
Invisible: 'text-secondary'
},
firstNameAsc: true
};
},
computed: {
sortFirstName () {
return this.firstNameAsc ? 'firstName' : '-firstName';
}
},
created () {
this.startWithInput = debounce((e) => {
this.startsWith = e.target.value;
}, 300);
},
methods: {
filterList,
isoDateToEuroDate,
searchAsEuroDate,
updateData () {
const updatedUsers = clone(users).slice(5, 10);
this.users = updatedUsers;
},
startsWithFilter (value) {
return value.toLowerCase().startsWith(this.startsWith.toLowerCase());
}
}
};3. This example shows to how create a data table.
<template>
<div>
<dataset
v-slot="{ ds }"
:ds-data="users"
:ds-sortby="sortBy"
:ds-sort-as="{ birthdate: isoDateToDate }"
:ds-search-in="['balance', 'birthdate', 'name', 'company', 'email', 'phone', 'address', 'favoriteAnimal']"
:ds-search-as="{ birthdate: searchAsEuroDate }"
>
<div class="row">
<div class="col-md-6 mb-2 mb-md-0">
<dataset-show />
</div>
<div class="col-md-6">
<dataset-search ds-search-placeholder="Search..." :wait="300" />
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="table-responsive">
<table class="table table-striped d-md-table">
<thead>
<tr>
<th scope="col">#</th>
<th v-for="(th, index) in cols" :key="th.field" :class="['sort', th.sort]" @click="click($event, index)">
{{ th.name }} <i class="gg-select float-right"></i>
</th>
</tr>
</thead>
<dataset-item tag="tbody">
<template v-slot="{ row, rowIndex }">
<tr>
<th scope="row">{{ rowIndex + 1 }}</th>
<td>{{ row.name }}</td>
<td>{{ row.email }}</td>
<td>{{ isoDateToEuroDate(row.birthdate) }}</td>
</tr>
</template>
</dataset-item>
</table>
</div>
</div>
</div>
<div class="d-flex flex-md-row flex-column justify-content-between align-items-center">
<dataset-info class="mb-2 mb-md-0" />
<dataset-pager />
</div>
</dataset>
</div>
</template>export default {
name: 'Example',
data: function () {
return {
users: users,
cols: [
{
name: 'Name',
field: 'name',
sort: ''
},
{
name: 'Email',
field: 'email',
sort: ''
},
{
name: 'Birthdate',
field: 'birthdate',
sort: ''
}
]
};
},
computed: {
sortBy () {
return this.cols.reduce((acc, o) => {
if (o.sort) {
o.sort === 'asc' ? acc.push(o.field) : acc.push('-' + o.field);
}
return acc;
}, []);
}
},
methods: {
click (event, i) {
let toset;
const sortEl = this.cols[i];
if (!event.shiftKey) {
this.cols.forEach(o => {
if (o.field !== sortEl.field) {
o.sort = '';
}
});
}
if (!sortEl.sort) {
toset = 'asc';
}
if (sortEl.sort === 'desc') {
toset = event.shiftKey ? '' : 'asc';
}
if (sortEl.sort === 'asc') {
toset = 'desc';
}
sortEl.sort = toset;
},
isoDateToEuroDate,
isoDateToDate,
searchAsEuroDate
}
};Preview:

Changelog:
v1.1.18 (08/31/2023)
- bugfixes
v1.1.17 (11/06/2022)
- bugfixes
v1.1.16 (08/07/2022)
- fixed set active page to last page
v1.1.15 (07/18/2022)
- fixed table spacing
v1.1.14 (06/12/2022)
- Bug Fixes
v1.1.13 (04/20/2022)
- Bug Fixes
v1.1.12 (01/22/2022)
- Bug Fixes
v1.1.10/11 (01/08/2022)
- Bug Fixes
v1.1.9 (09/27/2021)
- fix: added iteration index
v1.1.8 (09/19/2021)
- Bug Fixes
v1.1.7 (08/09/2021)
- Bug Fixes
v1.1.6 (08/05/2021)
- Bug Fixes
v1.1.5 (07/24/2021)
- Bug Fixes
v1.1.2 (05/07/2021)
- Update