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 Input Group Laravel Package

eom-plus/nova-input-group

View on GitHub
Deep Wiki
Context7

Getting Started

Install into your Nova 4 app (peer-installs against laravel/nova, so no version gymnastics):

composer require eom-plus/nova-input-group

Nova auto-discovers the service provider and JS assets — no nova:publish or npm install in the consuming app for the compiled field. Where to look first:

  1. The package README for the exact field class namespace and the fluent API (likely ->prepend() / ->append(), or ->prefix() / ->suffix() — the two conventions are interchangeable in most Nova input-group packages, so confirm the actual method names before you code against them).
  2. vendor/eom-plus/nova-input-group/src/ to see which Nova field it extends (almost certainly Laravel\Nova\Fields\Text, which is good — you inherit every Text method for free).
  3. vendor/eom-plus/nova-input-group/resources/js/components/FormField.vue to see how the prefix/suffix is rendered and what meta keys drive it.

First use case: a currency or unit field where a bare input looks unfinished. Wire it up in a Resource's fields():

use EomPlus\NovaInputGroup\InputGroup;

InputGroup::make('Price')
    ->prepend('$')
    ->append('.00')
    ->rules('required', 'numeric', 'min:0'),

That's the whole loop — field renders, stores a plain string exactly like Text, and Nova handles everything else.

Implementation Patterns

Treat this as a presentation wrapper on Text, not a new data type. The submitted value is unchanged, so all your rules, casts, and observers keep working.

Currency without a separate column. Store the raw decimal (1999.00) and use the group for visual context in the form:

InputGroup::make('Price', 'price_cents')
    ->prepend('$')
    ->step(0.01)          // inherited from Text if supported
    ->rules('numeric', 'min:0'),

Units on numeric fields. Weight, duration, percentages — the suffix does the labelling so you can drop the help text:

InputGroup::make('Weight')->append('kg')->rules('required', 'numeric'),
InputGroup::make('Discount')->append('%')->rules('between:0,100'),
InputGroup::make('Duration')->append('minutes')->rules('integer'),

URL / handle prefixes. Especially nice for website or social handles where users fumble the scheme:

InputGroup::make('Website')
    ->prepend('https://')
    ->rules('url')
    ->hideFromIndex(),

Then normalise in your mutator/Saving event, because the prefix is not prepended to the stored value.

Consistent resource-wide styling. If half your resources need money fields, wrap it in a helper:

// app/Nova/Fields/Money.php
class Money extends InputGroup
{
    public function __construct($name, $attribute = null, $resolveCallback = null)
    {
        parent::__construct($name, $attribute, $resolveCallback);
        $this->prepend('$')->rules('numeric', 'min:0');
    }
}

Combining with Nova built-ins. ->help(), ->placeholder(), ->nullable(), ->sortable(), ->default(), ->onlyOnForms(), ->readonly() all still apply if they're inherited from Text. Reach for ->withMeta([...]) only if the package documents extra meta keys.

Detail/index views. Input groups usually render as a plain value on the index and detail pages. If you want the $ visible there too, use ->displayUsing(fn ($value) => '$'.number_format($value, 2)) rather than relying on the prepend.

Gotchas and Tips

  • Prefix/suffix are display-only. The input's value sent to Laravel is what the user typed — no stripping, no concatenation. Never validate assuming the prefix is present ('url' will fail on https:// if you actually typed a full URL).
  • Don't use it as a mask. This is an input group (static addon text), not an inputmask. For credit cards, phone formats, or thousands separators, pair it with a proper masking field or format on the model instead. Mixing the two usually fights the Vue component.
  • Pin the version in composer.json. 3 stars, 0 dependents and a very low ecosystem score means you're on the bleeding edge of an unmaintained-looking package. Use an exact constraint ("eom-plus/nova-input-group": "1.0.*") so a silent composer update in CI doesn't break the field on a Friday deploy.
  • Verify the class namespace from the README before you import — I've seen these packages ship EomPlus\NovaInputGroup\InputGroup, EomPlus\NovaInputGroup\Field, and Operative\NovaInputGroup\InputGroup across versions. An editor autocomplete is faster than guessing.
  • Nova 5 compatibility is unknown. The README targets Nova 4; the Vue 2 → Vue 3 / Inertia boundary is where small Nova packages die. If you're planning a Nova 5 upgrade, grep your resources for this field and budget a swap to Text + ->displayUsing() or a Stack field.
  • Debugging rendering issues: open Vue DevTools on the form, inspect the FormField component's field prop — every meta value the package passes through is visible there. If prepend isn't showing, the meta key name is wrong for your version, not a CSS problem. Also check that the compiled dist/js/field.js is being served (browser Network tab) — if it 404s, run php artisan nova:publish and re-clear php artisan view:clear.
  • Extension points are thin. There's no nova-input-group.php config in this package; if you need more than the README exposes, subclass the field and override jsonSerialize() (PHP side) or copy FormField.vue into your own custom field. For anything truly custom (buttons, dropdown addons, live-calculated suffixes), build a dedicated Nova field — don't bend this one.
  • Test the store path early. Because it's just Text underneath, a quick php artisan tinker store or a Dusk/feature test through the Nova form will confirm the field serialises correctly before you replicate it across ten resources.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin