Skip to content

Instantly share code, notes, and snippets.

@jacobshenning
Last active April 23, 2024 16:39
Show Gist options
  • Save jacobshenning/425df35d6e9d78d0db38d17e47fa32d6 to your computer and use it in GitHub Desktop.
Save jacobshenning/425df35d6e9d78d0db38d17e47fa32d6 to your computer and use it in GitHub Desktop.
An alpine datatable
// Alpine JS datatable
window.datatable = function (data) {
return {
source: data,
data: data,
// Pagination
current_page: 0,
items_per_page_value: 5,
get items_per_page() {
return this.items_per_page_value;
},
set items_per_page(value) {
this.items_per_page_value = parseInt(value);
},
items() {
let start = this.current_page * this.items_per_page,
end = this.data.length;
if (this.current_page * this.items_per_page < this.data.length - this.items_per_page) {
end = this.current_page * this.items_per_page + this.items_per_page;
}
return this.data.slice(start, end);
},
atStart() {
return this.current_page === 0;
},
atEnd() {
return this.current_page >= Math.floor((this.data.length - 1) / this.items_per_page);
},
first() {
if (!this.atStart()) {
this.current_page = 0;
}
},
previous() {
if (!this.atStart()) {
this.current_page--;
}
},
next() {
if (!this.atEnd()) {
this.current_page++;
}
},
last() {
if (!this.atEnd()) {
this.current_page = Math.floor((this.data.length - 1) / this.items_per_page);
}
},
// Sorting
columns_sorted: [],
sort(column) {
if (this.columns_sorted[column] == undefined) {
this.columns_sorted[column] = true;
}
if (this.columns_sorted[column]) {
this.data.sort((a, b) => (a[column] > b[column]) ? 1 : -1);
} else {
this.data.sort((a, b) => (a[column] > b[column]) ? -1 : 1);
}
this.columns_sorted[column] = !this.columns_sorted[column];
},
// Search
search(search, values) {
this.first();
results = [];
for (i in this.source) {
for (x in values) {
let value = this.source[i][values[x]];
if (value.toUpperCase().indexOf(search.toUpperCase()) > -1) {
results.push(this.source[i]);
break;
}
}
}
this.data = results;
}
}
}
{{-- Begin datatable --}}
<div x-data="{{ $resources->toJson() }}
<div class="controls">
<select x-model="items_per_page">
<option value="5">5</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="100">100</option>
</select>
<input x-on:keyup="search($event.target.value, ['column_1', 'column_2])" type="text">
</div>
<table>
<thead>
<tr>
<th x-on:click="sort('column_1')>
<span>Column 1 </span>
<i x-show="columns_sorted['column_1'] === undefined" class="icon-sort"></i>
<i x-show="columns_sorted['column_1'] === true" class="icon-sort-down"></i>
<i x-show="columns_sorted['column_1'] === false" class="icon-up"></i>
</th>
<th x-on:click="sort('column_2')>Column 2</th>
</tr>
</thead>
<tbody>
<template x-for="resource in resources">
<tr>
<td :text="resource.column_1"></td>
</tr>
<tr>
<td :text="resource.column_2"></td>
</tr>
</template>
</tbody>
</table>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment