masoudi/nova-textlist-field
A lightweight Laravel Nova field for managing simple text lists—tags, bullet points, or short entries—with add/remove rows in forms and clean, readable display on index and detail views. Useful when a full relation or JSON field is overkill.
This package is an archived, low-usage Nova field. Verify compatibility with your Nova/PHP version before adopting it; if it works, treat it as a small utility field rather than a long-term dependency.
Confirm installability
composer.json for the exact namespace and Laravel/Nova constraints.composer require masoudi/nova-textlist-field in a disposable branch. If constraints block it, fork the repo and relax them rather than forcing --ignore-platform-reqs in production.app/Nova/Fields if needed.Add a storage column
text or json column, not string:Schema::table('posts', function (Blueprint $table) {
$table->json('bullet_points')->nullable();
});
protected $casts = [
'bullet_points' => 'array',
];
Register the field on a Nova resource
use Masoudi\NovaTextlistField\TextList;
public function fields(Request $request)
{
return [
TextList::make('Bullet Points', 'bullet_points')
->rules(['nullable', 'array'])
->help('One item per line'),
];
}
First use case
Flat-list model pattern
Use the field for a flat array column and pair it with an array cast. Validate items as strings:
TextList::make('Ingredients', 'ingredients')
->rules(['nullable', 'array'])
->rulesFor('ingredients.*', ['string', 'max:100']);
If the field stores a delimited string instead of JSON, adjust the cast and validation accordingly. Read the field’s fill()/resolve() methods to confirm the data shape.
Index and detail display
Arrays rarely render well by default in Nova index tables. Normalize display early:
TextList::make('Tags', 'tags')
->displayUsing(fn ($value) => is_array($value)
? implode(', ', $value)
: (string) $value)
->onlyOnForms(); // or use a separate formatted field on index
For detail views, either let the field render or replace it with a Text field that joins the array.
Form-only editing with computed display
A common workflow is to edit with TextList but show a polished value elsewhere:
TextList::make('Keywords', 'keywords')
->onlyOnForms()
->rules(['nullable', 'array']),
Text::make('Keywords', function () {
return collect($this->keywords ?? [])->implode(', ');
})->onlyOnDetail(),
Migration from comma-separated input
If existing data is a comma-separated string, do not point the field at it without a migration. Normalize first:
$model->keywords = array_filter(array_map('trim', explode(',', $model->keywords)));
$model->save();
Then cast to array and switch the column to json/text.
Fork-and-extend pattern
Given the archived status, the most realistic long-term pattern is to copy the field into your app and own it:
app/Nova/Fields/TextList.php.App\Nova\Fields.make, rules, displayUsing) close to Nova’s native field conventions so resources do not need rewrites later.This also lets you add features the package may lack, such as reordering, item-level validation messages, or a separator configuration.
--ignore-platform-reqs as a permanent fix; fork and update composer.json, or vendor the class locally.resolve() and fill() methods before writing migrations or casts.array rules. If it stores a string, do not validate as array. Mixed expectations lead to “Array to string conversion” errors.null, [], and '' consistently. Add an accessor or mutator if the field returns inconsistent empty states.displayUsing or hide the field from index and show a joined Text field instead.resolve, fill, and sometimes fillUsing. If the package was built for an older Nova version, test create, update, and detail screens explicitly.displayUsing, resolveUsing, fillUsing, and rules methods over editing package internals. If you must edit, fork immediately so upgrades are deliberate.How can I help you explore Laravel packages today?