wamesk/laravel-nova-inline-toggle
Laravel Nova inline toggle field: flip boolean values straight from index and detail views without opening an edit form. A drop-in switch for any boolean column with configurable labels, colors, and optional confirmation—making admin workflows faster. Works with Nova 4 and 5.
InlineToggle is a Laravel Nova field package that renders a toggle switch directly in your resource tables and detail views, so users can flip a boolean without opening the edit form. Start by requiring the package and confirming the field resolves in a resource:
composer require <vendor>/nova-inline-toggle
php artisan nova:publish # only if the package ships publishable assets
First place to look is app/Nova/<YourResource>.php. Drop the field into fields() and give it the underlying column as the second argument (attribute name):
use Vendor\InlineToggle\InlineToggle;
public function fields(NovaRequest $request)
{
return [
InlineToggle::make('Active', 'is_active'),
];
}
The fastest first use case is a moderation/status column on an index view — e.g. is_active, is_featured, is_published — where an admin wants to flip state in one click from the resource list. Render it, click it, and verify the model attribute actually persists; that single loop validates the whole integration before you build on it.
Index vs. detail placement. The field works in both contexts, but the mental model differs: on index the toggle is an inline mutation (fires immediately, usually an AJAX update); on detail it's a form control until saved. Decide per column and keep the attribute identical in both so you don't end up with two sources of truth.
Readonly guarding (v1.1.0). Use ->readonly() for audit-sensitive columns, or make it conditional so only privileged users can toggle:
InlineToggle::make('Active', 'is_active')
->readonly(fn () => ! $request->user()->can('update', $this->resource)),
Because the readonly option is now enforced on both index and detail, this is the correct way to lock a column down rather than relying on policy checks in a custom callback. Note readonly() is still enforced server-side only if your resource's updateFields/authorizedToUpdate protects the attribute — treat the UI guard as convenience, not security.
Reactive behaviour with dependsOn() (v1.1.0). This is the headline feature: you can hide or mutate the toggle based on another field's value, using the same signature as core Nova dependency callbacks:
InlineToggle::make('Active', 'is_active')
->dependsOn('status', function (InlineToggle $field, NovaRequest $request, FormData $formData) {
if ($formData->status === 'archived') {
$field->hide();
}
// or: $field->readonly(true); $field->help('Archived records cannot be toggled');
});
Day-to-day patterns that pay off:
archived, deleted, locked).Select/BelongsTo and hide the toggle until a category is chosen, reducing noise on the create form.->readonly(false)) at the top of the callback if you rely on state transitions.(InlineToggle $field, NovaRequest $request, FormData $formData). Don't reuse a Field-typed closure from a core Nova field; the concrete InlineToggle type is required for hide()/readonly() chaining.Integration tips.
updating event to log toggles if you need an audit trail; the index toggle is a fast path and easy to miss in activity logs.indexQuery scoping or filterable column states, test the toggle against a filtered list — inline toggles sometimes fire against the row id while the local UI state diverges from the server response.->sortable() and ->textAlign('center') on index if the toggle is a prominent column; it's still a Nova field, so standard display options apply.Asset/module resolution. v1.1.0 externalizes laravel-nova in the webpack config. If you build or extend the package's JS (or have a stale compiled bundle), you now must resolve laravel-nova through Nova's own module aliasing at runtime. Symptoms of a mismatch are a Cannot find module 'laravel-nova' in the browser console or a field that renders but never responds to clicks. Fix: npm run prod (or the package's build script) after upgrade, clear public/vendor caches, and ensure your nova.mix.js/webpack config inherits Nova's external config.
Readonly ≠ authorization. The new readonly support prevents accidental toggling in the UI, but don't assume it blocks the request. If your InlineToggle mutates via the standard resource update endpoint, verify authorizedToUpdate and field-level rules reject unauthorised changes. For sensitive booleans, prefer a policy-backed custom endpoint over relying on the field option.
dependsOn only reacts to declared fields. The dependency only fires when the named field exists and is present in the current field set. If you conditionally include status via canSee, the callback silently never runs and the toggle stays visible/editable. Debug by confirming the dependency field is rendered on the same form.
FormData vs. model state. In the callback, $formData holds the in-flight form values, not the persisted model. On index-style toggles there may be no form data at all, so guard for null/missing keys:
$status = $formData->status ?? $this->resource->status ?? null;
Index toggles and optimistic UI. Clicking the toggle usually updates optimistically; if the server rejects the change (validation, policy, readonly race), the UI may not roll back cleanly. Test with a deliberately failing request to see how the field handles the error, and surface a toast/notification on failure.
Upgrade checklist for 1.1.0.
composer update the package and rebuild assets (npm run prod).php artisan nova:clear / view + config caches.dependsOn callbacks only after confirming the dependency field renders in every context you care about.composer.json constraints: if the package externalizes Nova modules, pin the Nova major version you test against.Extension point. The package is JS-backed, so the cleanest customisations are (a) Nova field methods (->help(), ->rules(), ->readonly() with closures) and (b) dependsOn callbacks. Avoid forking the compiled JS — the v1.1.0 webpack change makes forked bundles fragile across Nova upgrades.
How can I help you explore Laravel packages today?