Creare una tabella con ordine, ricerca e paginazione in Alpine.js
In questo articolo vediamo come creare una tabella tipo DataTable con Alpine.js.
Per la parte dello stile ho usato Bootstrap, ma ovviamente non è obbligatorio.
I dati li prendiamo da uno dei miei url; siete liberi di usarlo per i vostri test.
Cominciamo dal codice Javascript:
document.addEventListener('alpine:init', () => {
Alpine.data('getItems', () => ({
items: null,
sortCol: null,
sortAsc: false,
pageSize: 10,
curPage: 1,
search: "",
async init() {
let resp = await fetch('https://www.mattepuffo.com/api/book/get.php');
let data = await resp.json();
data.books.forEach((d, i) => d.id = i);
this.items = data.books;
},
nextPage() {
if ((this.curPage * this.pageSize) < this.items.length) this.curPage++;
},
previousPage() {
if (this.curPage > 1) this.curPage--;
},
sort(col) {
if (this.sortCol === col) this.sortAsc = !this.sortAsc;
this.sortCol = col;
this.items.sort((a, b) => {
if (a[this.sortCol] < b[this.sortCol]) return this.sortAsc ? 1 : -1;
if (a[this.sortCol] > b[this.sortCol]) return this.sortAsc ? -1 : 1;
return 0;
});
},
get pagedItems() {
if (this.items) {
if (this.search === '') {
return this.items.filter((row, index) => {
let start = (this.curPage - 1) * this.pageSize;
let end = this.curPage * this.pageSize;
if (index >= start && index < end) return true;
});
} else {
return this.items.filter((item) => {
return item.title
.toLowerCase()
.includes(this.search.toLowerCase())
||
item.author
.toLowerCase()
.includes(this.search.toLowerCase());
});
}
} else {
return [];
}
},
})
);
});
Il codice è abbastanza flessibile; per applicarlo ad un fonte dati diversa dovete cambiare solo la url e i campi in cui cercare.
Questo l'HTML:
<div class="row">
<div class="col-12 mb-3">
<section class="card">
<div class="card-body">
<div x-data="getItems()">
<input type="search"
class="form-control mb-3"
placeholder="Cerca..."
x-ref="searchField"
x-model="search"
x-on:keydown.window.prevent.slash="$refs.searchField.focus()">
<table class="table table-no-more table-bordered table-striped mb-3">
<thead>
<tr>
<th @click="sort('title')">Title</th>
<th @click="sort('author')">Author</th>
</tr>
</thead>
<tbody>
<template x-if="!items">
<tr>
<td colspan="4"><i>Loading...</i></td>
</tr>
</template>
<template x-for="item in pagedItems" :key="item.id">
<tr>
<td x-text="item.title"></td>
<td x-text="item.author"></td>
</tr>
</template>
</tbody>
</table>
<button class="btn btn-primary" @click="previousPage">Previous</button>
<button class="btn btn-primary" @click="nextPage">Next</button>
</div>
</div>
</section>
</div>
</div>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="./js/script.js"></script>
Dvoreste anche aggiungere le icone sui nomi delle colonne per indicare meglio che la tabella è ordinabile.
Enjoy!
javascript html alpinejs
Commentami!