Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Values Field Laravel Package

norman-huth/nova-values-field

norman-huth/nova-values-field adds a flexible values field to Laravel Nova for editing repeatable lists or key-value data in the admin UI, storing structured JSON on Eloquent models. Useful for settings, metadata, tags, and other custom attributes.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a single-purpose Nova field: it stores an ordered list of values (a JSON array) instead of a key/value map. It is only worth adopting if you have a Nova resource that needs a free-form repeatable list — tags, aliases, allow-listed emails, feature flags, sizes, etc. — and you don't want the key column Nova's KeyValue forces on you.

Because the repository is archived (last release 2025-06-03, 6 stars, zero dependents), treat it as source material rather than a long-lived dependency:

  1. Vet compatibility first. Open composer.json and confirm the laravel/nova constraint matches your installed Nova major. Nova fields break silently between majors, so this is the go/no-go check.
  2. Install or vendor.
    • Quick path: composer require norman-huth/nova-values-field and verify the field appears.
    • Safer path for an archived package: copy src/ into app/Nova/Fields/Values.php and the compiled assets into public/vendor/, adjusting the namespace. You inherit the maintenance burden either way, so own the code.
  3. Read two files first. src/*Field.php (the PHP API surface — methods, jsonSerialize, fill) and resources/js/field.js + components/FormField.vue (what the UI actually submits). The Vue component defines the real data shape; the PHP class is usually a thin wrapper.
  4. Prepare storage. Add a json/jsonb column (nullable), and cast it on the model:
    protected $casts = ['tags' => 'array'];
    
  5. First use case. Attach it to a resource form and confirm round-tripping before building anything on top:
    use NormanHuth\NovaValuesField\Values;
    
    Values::make('Tags', 'tags')
        ->rules(['nullable', 'array'])
        ->help('One value per row, order is preserved.');
    

Implementation Patterns

Basic form + detail wiring. The field is a form input; index and detail views need explicit display logic because an array doesn't render meaningfully by default:

Values::make('Aliases', 'aliases')
    ->rules(['nullable', 'array', 'max:20'])
    ->resolveUsing(fn ($value) => is_array($value) ? $value : [])
    ->displayUsing(fn ($value) => collect($value ?? [])->implode(', '))
    ->onlyOnForms(); // pair with a Text field for index if needed

Normalize on the model, not the field. Field-level fill behavior is the least reliable part of a small third-party package. Enforce shape with a mutator or cast so imports, seeders, console commands, and API writes stay consistent:

public function setAliasesAttribute($value): void
{
    $this->attributes['aliases'] = json_encode(
        array_values(array_filter((array) $value, fn ($v) => filled($v)))
    );
}

Validation lives outside the field. Rely on standard Laravel rules (array, max:, distinct) rather than any field-provided helpers, since the package is unmaintained. Validate per-item constraints with aliases.* rules:

->rules(['nullable', 'array', 'max:10', 'aliases.*' => ['string', 'max:50']])

Pair with dependsOn for conditional lists. A typical real workflow: a type Select controls whether a values list is shown, then the list feeds downstream logic (e.g., allowed MIME types, environment names).

Use it as a lightweight repeater. For single-column repeaters (ports, CIDR blocks, env var names), this beats installing a full repeater package — but only if your team accepts a vendored asset.

Read/write outside Nova. With the array cast, ordinary code works: $model->aliases[] = 'new'; $model->save();. This is the main reason the field is usable at all despite being archived — it produces plain JSON, not an opaque format.

Integration tip: if you need ordering with drag-and-drop, confirm the Vue component actually emits in display order. If not, sort on save (array_values, sort) rather than fighting the JS.

Gotchas and Tips

  • Archived = frozen. No Nova 5/6 fixes, no PHP 8.4+ patches, no security review. Either fork it into your app or accept that a Nova upgrade may require rewriting the Vue component yourself. Keep the copied source in version control with a comment explaining provenance.
  • Nova version drift is the top risk. A field authored against Nova 4 will often half-work on Nova 5: the form renders, but fill or detail hydration silently drops the array. Test create, update, and detail view before shipping.
  • null vs []. Nova will submit an empty array on save; a fresh record is null. Guard every read with ?? [] and decide deliberately whether empty means null or [] in the database — inconsistent handling causes "why did this record change?" bugs.
  • JSON vs jsonb ordering. On Postgres, jsonb does not preserve array order semantics the way json does for some operations. If list order is meaningful, store as json (or sort explicitly on read).
  • Duplicates are allowed. There's no key to dedupe against, so ['a','a'] is valid. Add a distinct rule if that's wrong for your use case.
  • Index columns look bad. The raw array serializes to ["a","b"] in the index table. Always supply displayUsing, or hide the column on index.
  • Rebuilding assets. If you vendored the source and edited the Vue component, run npm install && npm run dev inside the package and republish assets — a stale public/vendor/.../field.js is the usual "my changes did nothing" cause.
  • Clear Nova's asset cache after upgrading or republishing: php artisan nova:publish and hard-refresh. Nova caches the manifest aggressively.
  • Debugging payloads. dd(request()->all()) in the controller, or inspect nova_request in the browser devtools, to confirm the JS emits { value: [...] } and not { value: {0: 'a'} } — PHP will happily cast a keyed object to an array and hide the problem until JSON re-encodes as an object.
  • Extension point worth knowing: the cleanest way to add behavior (max items, item prefix/suffix, CSV paste) is to subclass the field in app/Nova/Fields/ and override jsonSerialize/fill plus copy the Vue component — don't monkey-patch vendor/.
  • Testing. In feature tests, assert against the cast array (assertDatabaseHas with json_encode([...])), not the field object; Nova field classes are hard to unit test meaningfully.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect