chinleung/nova-autofill
chinleung/nova-autofill is a Laravel Nova package that adds autofill behavior to resource forms, helping populate fields automatically and reduce repetitive manual entry. It streamlines admin data entry and makes Nova forms faster to complete with less typing.
chinleung/nova-autofill adds a field-level autofill capability to Laravel Nova, letting one field's value drive the value of other fields in the same form. v1.1.2 is a compatibility patch that adds Laravel 9 support — no API changes, no deprecations.
Install
composer require chinleung/nova-autofill
No service provider registration or publishing step is required; the package ships a Nova field macro/trait that is available as soon as it is autoloaded. After upgrading from v1.1.1, run composer update chinleung/nova-autofill and confirm your laravel/nova constraint resolves to a Nova 4 line (the Laravel 9-compatible branch).
Where to look first
README.md for the exact callback signature and the list of supported field types.src/ — usually a Field macro registration plus a concern that gets applied to Nova fields. Read the macro registration first; it tells you precisely which methods you can chain and in what order.app/Nova/*.php resources, to spot the fields that are pure derivations of other fields (slugs, totals, display names).First use case — derive a slug
use Laravel\Nova\Fields\Text;
use Illuminate\Support\Str;
Text::make('Title')
->autofill(), // trigger field
Text::make('Slug')
->autofill(fn ($value) => Str::slug($value)),
Open the create form, type in Title, and Slug populates on change. That single loop — trigger field, dependent field, cheap pure callback — is the whole package. Everything else is refinement.
One trigger, many targets. Returning an associative array lets a single trigger populate several fields at once:
Text::make('Title')
->autofill(fn ($value) => [
'slug' => Str::slug($value),
'meta_title' => Str::limit($value, 60),
]);
This is the pattern to reach for by default — one callback, one round trip, several fields filled.
Computations from sibling fields. Totals, tax, deposit amounts. Keep the arithmetic in the callback thin and delegate to a domain object or value class so the same logic can be reused in a model mutator or an observer.
Lookups against Eloquent. Filling an address or a price from a selected related record:
BelongsTo::make('Customer', 'customer', CustomerResource::class)
->autofill(fn ($id) => [
'email' => Customer::find($id)?->email,
]);
Always guard with ?-> — the id can be null when the user clears the select.
Clearing as a first-class result. Return null (or '' for text fields) rather than leaving stale values behind when the trigger is emptied. Users notice leftover data in a form far more than they notice a missing autofill.
Extract callbacks as the resource grows. Once a callback exceeds ~10 lines, move it to a method on the Nova resource or an invokable class (app/Nova/Autofills/ProductPricing.php) and reference it from autofill(). Nova resources get unreadable fast, and a plain class is testable without booting Nova.
Compose with default() and fillUsing(). default() runs on form load; autofill runs on change. Use default() for the initial value and autofill for subsequent updates. If you also use fillUsing()/resolveUsing(), keep them focused on hydration from the model and let autofill own the write-back — mixing the two on one field is where confusing "why did my value revert?" bugs come from.
Test at the HTTP layer. The callback executes server-side as part of a Nova field request, so a $this->actingAs($user)->putJson('/nova-api/...') test against the resource will exercise it. Assert on the response payload rather than trying to unit-test the closure in isolation.
Customer::find() or an external API call in a callback will hammer your database while the user types. Cache the lookup, key the callback off an id rather than a free-text field, and prefer triggers that change once (a select) over ones that change on every keystroke.fields() for that resource/context is silently dropped. The same applies to fields hidden by canSee() — the value won't land.$request carries a model; use $request->resourceId if you need to branch.autofill alone and add default()/fillUsing() back one at a time. Reverting to the model's stored value on the next form load usually means a resolveUsing is winning.logger() inside the callback plus a glance at the browser network tab is the fastest loop. If nothing fires at all, the problem is almost always that the trigger field lacks the autofill marker or the package's asset wasn't republished after a Nova upgrade (php artisan nova:publish).laravel/framework and laravel/nova constraints; if you were pinned below Laravel 9, this release is what unblocks the upgrade, and you should re-run your Nova asset publish step as part of it.App\Nova\Fields\AutofilledText) is worthwhile once more than two or three resources use it, so you can standardise debounce, empty-value handling, and authorization checks in one place.How can I help you explore Laravel packages today?