Alpinejs Table is a Laravel package to inject a simple table view component into any Laravel project.
Built with Laravel, Alpine.js, Moment.js, @bevacqua/rome, and Tailwind CSS .
- Sorting rows by cell values (ascending & descending)
- Filtering data by text match or dropdown
- Filtering by date picker (if cell value is date format)
- Customizable pagination, header title, and cell values
- Dependencies
- Installation
- Basic Usage (bundled)
- Basic Usage (standalone)
- Integration with your own js/css
- Built-in Filters
- Customization
- Extra Options:
- Appendix
- Notes
- Contributors
- License
- Support
Recommended:
- Laravel 5.7 or newer (which supports
ServiceProvider::loadViewsFrom()
) - PHP 7.1 or newer
You can use this package in older versions of Laravel, but extra installation steps are required (as demonstrated below).
composer require tttstudios/alpinejs-table
- Unzip the code and put it under
your-repo/packages/tttstudios/
folder, so it looks like this:
├── your-repo
│ ├── app
│ ├── config
│ ├── composer.json
│ ├── vendor
│ └── packages
│ └── tttstudios
│ └── alpinejs-table
- Add one line to
your-repo/composer.json
:
"autoload": {
"psr-4": {
"Tttstudios\\AlpinejsTable\\": "packages/tttstudios/alpinejs-table/src/"
},
}
- Then, add one line to
your-repo/config/app.php
:
'providers' => [
Tttstudios\AlpinejsTable\Providers\AlpinejsTableServiceProvider::class
]
- Lastly, refresh composer's autoload file by running:
composer dump-autoload
-
Copy all the source files under
alpinejs-table/resources/views
to your own repo'sviews/alpinejs-table
folder. -
Use Laravel Blade's
@include()
syntax to use them in view files. See examples below.
Alpinejs Table is shipped with 3 Blade Aliases:
Blade Alias | Description |
---|---|
AlpinejsTableBundle |
import a bundled javascript file with all its dependencies (including Alpine.js ) |
AlpinejsTableHtml |
import a blade view file |
AlpinejsTableCss |
import all styles required by the table |
You can use Alpinejs Table out of the box. Simply pass an array to AlpineHtml()'s collection
in any blade view.
- Format data into an array:
// ExampleController.php:
public function index() {
$users=\App\User::get()->map(function ($user) {
return [
'status' => $user->status,
'name' => $user->name,
'email' => $user->email,
];
})->all();
return view('example', compact('users'));
}
- Pass array to blade view:
<!-- in example.blade.php -->
<!--Import styles-->
<style> @AlpinejsTableCss() </style>
<!--Import js scripts-->
<script> @AlpinejsTableBundle() </script>
<!--Import table html-->
@AlpinejsTableHtml(['collection' => $users])
And this is what you get:
Prerequisite: Copy all the files under alpinejs-table/resources/views
to your own repo's views/alpinejs-table
folder.
# in example.blade.php:
<style> @include('alpinejs-table.css') </style>
<script> @include('alpinejs-table.js-bundle') </script>
@include('alpinejs-table.html', ['collection' => $users])
If your app already has Alpine.js imported, then you don't need to import the bundled javascript file. Instead, you can call AlpineJsTableCore
. Example:
# in example.blade.php:
<style> @AlpinejsTableCss() </style>
<!-- Without importing Alpine.js: -->
<script> @AlpinejsTableCore() </script>
@AlpinejsTableHtml(['collection' => $users])
# in example.blade.php:
<style> @include('alpinejs-table.css') </style>
<!-- Without importing Alpine.js: -->
<script> @include('alpinejs-table.js-core') </script>
@include('alpinejs-table.html', ['collection' => $users])
You can tell that Alpinejs Table is using moment.js to parse date & time, and use Tailwind CSS to compose styles. If your app has imported them in global scope, or if you want to integrate Alpinejs Table's source code into your app's bundled js & css, simple follow these steps (Laravel ≥5.7 only):
- Publish Alpinejs Table's assets by running:
php artisan vendor:publish --tag=alpinejs-table
- The command above will copy these files into your repo:
# js:
/resources/js/plugins/rome-modified.js
/resources/js/plugins/alpinejs-table.js
# css:
/resources/sass/plugins/alpinejs-table.scss
- Then you can import Alpinejs Table's core js into your own
app.js
:
// Source File: /resources/js/app.js
import 'alpinejs';
import AlpinejsTablePlugin from './plugins/alpinejs-table.js'
// Make it accessible in global ssope:
window.AlpinejsTablePlugin = AlpinejsTablePlugin;
- And you can import Alpinejs Table's styles into your own
app.scss
:
/* Source File: /resources/sass/app.scss */
@tailwind base;
@tailwind components;
@import 'plugins/alpinejs-table';
@tailwind utilities;
- Lastly, you only need to import
AlpinejsTableHtml
alone:
<!-- in example.blade.php -->
@AlpinejsTableHtml(['collection' => $users, 'options'=>$options])
Alpinejs Table generates a text filter for each column by default, which means, all columns can be filtered by text matching out of the box, unless you intentionally disable it.
For limited data types, you may need a dropdown filter. For example: status
may only have 2 valid values: Active
or Pending
. In this case, you can set it as a dropdown filter.
Example:
- Format data into an array:
// ExampleController.php:
public function index() {
$users=\App\User::get()->map(function ($user) {
return [
'status' => $user->status,
'name' => $user->name,
'email' => $user->email,
];
})->all();
$options=[
'dropdowns' => ['status'],
];
return view('example', compact('users', 'options'));
}
- Pass array to blade view:
<!-- in example.blade.php -->
<style> @AlpinejsTableCss() </style>
<script> @AlpinejsTableBundle() </script>
@AlpinejsTableHtml(['collection' => $users, 'options' => $options])
And this is what you'll get:
If some column is in date format. You may find it useful to define dates
in options.
Example:
// ExampleController.php:
public function index() {
$users=\App\User::get()->map(function ($user) {
return [
'status' => $user->status, // "Active" or "Pending"
'name' => $user->name,
// must be in ISO 8601 format, e.g.: 2020-05-27T18:26:58+00:00
'birthday' => $user->birthday->toIso8601String()
];
})->all();
$options=[
'dropdowns' => ['status'],
'dates' => ['birthday'],
];
return view('example', compact('users', 'options'));
}
Voila! The birthday column turns into a date picker automatically. Thank @bevacqua/rome for this great date picker plugin.
You can even set your own date format:
$options=[
'dates' => ['birthday'],
'dateFormat' => 'YYYY/M/D',
];
Alpinejs Table has a default cell width of 200px
for each column. You may customize the width of each cell by passing a javascript closure to cellWidth(key)
Example:
$options=[
// make sure the syntax is for Javascript:
'cellWidth(key)'=>'
if(key=="status")
return `120px`;
if(key=="email")
return `400px`;
return `200px`;
',
];
Refresh the page and you can get the new layout:
Alpinejs Table displays 10 entries per page by default. You can easily override it by setting perPage
in options
:
Example:
$options=[
'perPage' => 24
];
You can also set the options to allow visitors on change perPage on the fly:
$options=[
'perPageOptions' => [24, 48, 96]
];
Then You can see the settings in effect in bottom right of the table:
By default, Alpinejs Table transforms key
into title case and display in header. For example: user_email
will be transformed into User Email
.
In case you need to customize the title, you can use titleRenderer(key)
:
Example:
// ExampleController.php:
$options=[
'titleRenderer(key)'=>'
if(key=="id")
return `User ID`;
// by default: return nothing
'
];
Result:
Sometimes you need to display a transformed content for some cells. For example, you may want to show red font color for users with "Pending" status, or even add different action buttons for different cells .
Here comes the magic of cellRenderer(key,cell,row)
:
Example:
// ExampleController.php:
public function index() {
$users=\App\User::get()->map(function ($user) {
return [
'id' => $user->id,
'status' => $user->status,
'name' => $user->name,
'email' => $user->email,
];
})->all();
$options=[
'cellRenderer(key,cell,row)'=>'
if(key == "status" && cell.value == "Pending")
return `<span style="color:red">` + cell.value + `</span>`;
if(key == "name")
{
const isPending = row.status.value == "Pending";
return cell.value
+ `<a class="`+(isPending ? "btn-dark" : "btn-green") + ` float-right" href="/users/` + row.id.value + `">`
+ (isPending ? "Approve" : "Details")
+`</a> `;
}
return cell.value; // default
'
];
return view('example', compact('users', 'options'));
}
Result:
The column will not be displayed, but its value can still be accessed by row
in closures.
Example:
// ExampleController.php:
$options=[
'notVisible' => ['id']
'cellRenderer(key,cell,row)'=>'
if(key=="name")
return `<b style="color:blue">ID #`
+ row.id.value
+ "</b>: "
+ cell.value;
return cell.value;
'
];
Result:
The column can not be sorted, but its value can still be accessed by row
in closures.
Example:
// ExampleController.php:
$options=[
'notSortable' => ['email']
];
Result:
The column can not be filtered by text or dropdown, but its value can still be accessed by row
in closures.
Example:
// ExampleController.php:
$options=[
'notFilterable' => ['email']
];
Result:
Parameter | type | Example Value | Description |
---|---|---|---|
dropdowns | array | ['status'] | Set dropdown filter to a column |
dates | array | ['birthday'] | Set date filter to a column |
dateFormat | string | 'YYYY/M/D' | Set date format to a date filter |
perPage | integer | 24 | Set "per page" for pagination |
perPageOptions | array | [24, 48, 96] | Set perPage options for pagination |
notVisible | array | ['id', 'password'] | Hide columns from showing in table |
notSortable | array | ['email'] | Hide sort button from columns |
notFilterable | array | ['action'] | Hide filter from columns |
cellWidth(key) | js closure | 'return `200px`; ' | Customize cell width for any column |
titleRenderer(key) | js closure | 'if(key=="id") return `User ID`; ' | Customize title width for column header |
cellRenderer(key,cell,row) | js closure | 'return cell.value; ' | Customize cell content |
Alpinejs Table load all data into a single javascript instance. Performance can be compromised if there are too many data.
Alpinejs Table is open-sourced software licensed under the MIT license.
Alpinjs Table is presented by the web developing team at TTT Studios. We are a Digital Innovation Studio based out of Vancouver, Canada, delivering custom software and solutions that are designed and developed 100% in-house. The technologies we work with include AR & VR, IoT, AI, security & encryption, and cloud computing.