mimosu/nova-split-date-input
A Laravel Nova field that splits date entry into separate day, month, and year inputs, making date selection clearer and less error-prone for users. Drop-in replacement for the default date field with a simple, focused interface.
mimosu/nova-split-date-input is a Laravel Nova custom field that replaces the standard date picker with separate day / month / year inputs, while still persisting a single date value to your model. v1.0.0 is the initial tagged release, so there is no migration path to worry about — but the release notes contain only a changelog link, so treat the repository (src/, resources/js/, composer.json) as the source of truth before adopting.
composer require mimosu/nova-split-date-input
composer.json against your installed laravel/nova major. Custom fields are tightly coupled to Nova's frontend toolchain; a mismatch usually surfaces as a field that renders nothing or throws in the browser console.npm install && npm run prod) and php artisan nova:publish. If it ships a compiled dist/js/field.js, this step is a no-op.use Mimosu\NovaSplitDateInput\SplitDate; // confirm namespace in src/
public function fields(NovaRequest $request)
{
return [
SplitDate::make('Birthday')
->rules('nullable', 'date'),
];
}
If the field doesn't appear at all, the problem is almost always asset compilation, not PHP.
Basic resource usage. Treat it as a normal Nova field — everything on Laravel\Nova\Fields\Field (->nullable(), ->rules(), ->sortable(), ->hideFromIndex(), ->help()) applies, because the split UI is a presentation concern over one underlying attribute.
Model side stays conventional. Cast the column normally so the rest of your app is unaffected:
protected $casts = [
'birthday' => 'date:Y-m-d',
];
The field should round-trip a Y-m-d string. Keep the DB column a date (or string if you deliberately store partial dates) — the split input is not a reason to change your schema.
Validation lives on the parent field. Attach rules to the field itself rather than trying to validate three sub-inputs:
SplitDate::make('Birthday')
->rules('required', 'date', 'before:today')
->messages(['before' => 'Birthday must be in the past.']);
Remember date accepts 2024-02-31 in some PHP versions only loosely — add date_format:Y-m-d if you need strictness.
Display formatting for index/detail. Use Nova's standard helpers so the split UI only applies to forms:
SplitDate::make('Birthday')
->displayUsing(fn ($value) => $value?->format('d M Y'))
->onlyOnForms(); // or ->hideFromIndex()
Reuse across resources. Subclass the field once in your app (App\Nova\Fields\Birthday extends SplitDate) and bake in rules, formatting, and default order there. This keeps ~10 resources consistent and gives you a single place to patch if the underlying package needs a fix.
Filters and sorting work against the raw column, not the three sub-inputs — nothing special is needed, but only enable ->sortable() if the column is actually a sortable date/string, not a JSON blob.
Customising persistence. If your column format differs (e.g. d/m/Y legacy data), override resolveUsing / fillUsing on a subclass rather than post-processing in the model, so the transformation stays scoped to the Nova layer.
'', null, or even 0000-00-00 depending on how the field's fill hydrates. Always pair the field with ->nullable() plus a nullable rule, and test clearing an existing value on an update form — this is the single most common bug with split date fields.required + date) or a legitimate partial date (store as string). Don't leave it to chance.date value parsed as midnight UTC then displayed in local time — fix with an explicit date:Y-m-d cast and displayUsing formatting that ignores timezone.nova:publish, check whether dist/js/field.js exists in the package, and confirm nova.mix.js was used for the build. Re-run npm run prod after any package update.composer.json and re-test on every Nova upgrade. A field built for Nova 4's Field contract may need changes for Nova 5.birthday_day. If you've hand-rolled separate _day/_month/_year attributes elsewhere, don't mix the two approaches on one form.fillUsing/resolveUsing, use ->help()/->stacked() to control label layout (three boxes need horizontal room — test on a narrow viewport), and check for a publishable config/view before patching vendor code.1.x tags for a package this young.How can I help you explore Laravel packages today?