softerize/tablelize
Tablelize is a Laravel package for building data tables from your application data with less boilerplate. It helps define columns and render clean, customizable tables in Blade, streamlining table setup for admin panels and CRUD screens.
The 0.1.6 release adds a datas option to buttons and rowActions, which is the first real bridge between this package's PHP-side config and your front-end behaviour. That makes it a good entry point: install the package, publish whatever config/assets it ships with, and render a single table with one button and one row action so you can inspect the generated HTML before wiring anything else up.
Start by looking at three things, in this order:
datas lands and where you'll debug when an attribute doesn't appear.Minimal first use case: a row action that opens a modal via a Stimulus controller.
'rowActions' => [
[
'name' => 'edit',
'route' => 'users.edit',
'datas' => [
'action' => 'click->modal#open',
'modal-id' => 'user-modal',
],
],
],
Render the table, view source, and confirm you see data-action="click->modal#open" data-modal-id="user-modal" on the anchor/button. If that works, everything else is a variation on it.
Keys are bare attribute suffixes. Pass action, not data-action. The package adds the data- prefix. Mixed prefixes in config ('data-action' => ...) will either double-prefix or silently no-op depending on the renderer version — verify once, then standardise in your own codebase.
Stimulus action descriptors are the primary use case. 'action' => 'click->controller#method' maps directly onto Stimulus's data-action syntax. For tables where rows are re-rendered or appended, this is the cleanest way to keep behaviour declarative — no document.querySelectorAll loops over [data-row-action] after every AJAX refresh.
Derive datas from the row, not from hardcoded strings. The config array is evaluated per-render, so you can compute values from the model:
'rowActions' => [
[
'name' => 'delete',
'datas' => [
'action' => 'click->confirm#prompt',
'confirm-url' => route('users.destroy', $user),
'confirm-label' => $user->name,
],
],
],
This keeps destructive-action URLs out of inline <script> blocks and avoids a global JS config object.
Wrap repetitive attribute sets in a helper. Table configs get noisy fast. A small ButtonDatas::forModal('user-modal') helper that returns the array keeps the table definition readable and gives you one place to change if the attribute naming convention shifts in a later 0.1.x release.
Test the attributes, not the button. $response->assertSee('data-action="click->modal#open"', false) is a cheap regression guard. Since datas is a pass-through with no server-side semantics, HTML-level assertions are the only meaningful coverage.
Keep the JS layer's expectations in one place. If you're on Stimulus, put the controller name in a constant shared between the PHP config and the JS registration. Renaming a controller is otherwise a silent breakage — the attributes render fine and nothing fires.
datas, not data. This is the single most likely typo and it fails silently — the option is simply ignored, the button renders, and you'll spend time inspecting the wrong layer.^0.1.6 and read the diff for 0.1.7+ before bumping, especially if you've built helpers around the attribute shape.datas without escaping; if you must, escape at the source or you've reintroduced an attribute-injection vector through the back door.data-x="1", data-x="", or be skipped. Normalise to strings ('true'/'false') yourself rather than relying on the renderer.href or class, a datas key of the same name will not override it — and it won't warn you. Use distinct keys for your own hooks.dd($buttonConfig)), then the rendered partial, then the DOM. Most "it didn't work" reports resolve at step one.datas isn't enough. If you need arbitrary non-data-* attributes (aria-*, x-on:*, wire:click), you'll need to publish and override the button Blade partial rather than fight the config. Do this deliberately — forked partials are the main upgrade-friction risk with this package.<form>, a click-> action on an <a> or <button> may submit the form. Add type="button" via whatever mechanism the package exposes, or the action fires and the page navigates simultaneously — a confusing symptom that looks like a Stimulus bug.How can I help you explore Laravel packages today?