eom-plus/nova-depend-fill
eom-plus/nova-depend-fill is a Laravel Nova package for creating dependent form fields. When a parent field changes, dependent fields can update their options or autofill values via AJAX, making cascading selects and dynamic forms easy to build with minimal configuration.
The package is a single Nova field (eom-plus/nova-depend-fill) that lets one field's value be populated from another field's value using Nova's native dependsOn chain. It is a small, low-signal package (2 stars, 0 dependents), so treat the source as the primary documentation.
Install
composer require eom-plus/nova-depend-fill
No service provider or publish step is typically required — Nova auto-discovers fields in vendor/eom-plus/nova-depend-fill/src.
Where to look first
README.md in the package root — the usage snippet is usually the only spec.src/*.php — read the fill() / resolve() / fields() methods to confirm whether the fill is client-side (JavaScript via dependsOn) or server-side (PHP fill/resolve callback).resources/js/ — if present, this tells you whether the field reacts via Nova.$on and Nova.$emit events, which determines what works inside modals and nested forms.First use case
The canonical pattern is a dependent select or text field: pick a Country, and the Region field auto-populates from a mapping. In a Nova resource:
use EomPlus\NovaDependFill\DependFill;
public function fields(NovaRequest $request)
{
return [
Select::make('Country')
->options(['us' => 'United States', 'ca' => 'Canada']),
DependFill::make('Region')
->dependsOn('country', [
'us' => 'North America',
'ca' => 'North America',
])
->readonly(), // usually readonly so the fill isn't overwritten
];
}
Start with a static map on a single field; that is the one workflow this package exists to make trivial.
Static mapping (the core pattern). Pass a keyed array to dependsOn($field, $map). The value of $field selects the entry. This is the most reliable usage because it requires no server round-trip — worth using for enums, code-to-label lookups, and simple derived display fields.
Server-side fill on save. For anything dynamic (database lookups, computed values, currency conversion), don't rely on the field's client-side fill alone. Pair it with a saving()/prepareForValidation hook on the request or a beforeSave model observer so the value is deterministic regardless of what the browser posted:
protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute)
{
if ($request->exists($requestAttribute)) {
$model->{$attribute} = $request->input($requestAttribute);
}
}
Chaining dependent fields. Because it rides Nova's dependsOn, you can chain: Country → State → City. Declare each DependFill field as depending on the previous one, and make sure each upstream field is in the form so Nova's reactivity has a source. Chains silently break if any intermediate field is hidden via hideFromDetail/conditional canSee().
Reusing across create and update. Nova fields are shared between create and update by default. If the source field is only editable on create, gate the fill with ->onlyOnForms() / ->exceptOnForms() rather than branching the field list.
Combining with native Nova dependsOn. The package's dependsOn is not the same as Nova's built-in ->dependsOn(...) used to re-render a field. If you need both reactivity (field redraws) and value fill, check the source — you may need to apply the package method and Nova's separately, which can lead to ordering surprises.
Including in detail/index views. If you want the mapping to apply to read-only detail pages, confirm the field implements resolve() for display. If it doesn't, fall back to an asHtml() computed field for detail views and reserve DependFill for forms.
composer.json and be prepared to fork. Read the source before trusting it in a production resource.Region that doesn't match the Country mapping. Always re-derive or validate server-side; never let a dependent field be the only guard on a business rule.dependsOn doesn't fire on programmatic changes. If you set a field's value from JavaScript or a default() that changes after mount, the dependent fill may not recompute. Test with defaults, withMeta, and modals (Nova's modal forms use a separate component tree).npm run dev/npm run prod in your app after install so Nova's mix picks up the field bundle. Vite-era Nova (4/5) vs Mix-era Nova (3) is a common mismatch — if the field renders blank, that's the first place to look.readonly() vs disabled(). A filled field is usually better as readonly() (submitted, so your server-side check can compare) than disabled() (not submitted, so the old value persists). Choose deliberately.dependsOn chains do not cross HasMany/BelongsTo boundaries. A field in a nested HasMany form cannot depend on a top-level field without custom event plumbing.meta() output (it's in the JSON Nova ships to the frontend) to confirm the mapping actually reaches the browser. If the map is large, watch for the payload being stripped by ->withMeta() collisions when two fields share the same key.How can I help you explore Laravel packages today?