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

Livewire Forms Laravel Package

nodus-it/livewire-forms

A Laravel Livewire package for creating dynamic, reusable forms with validation and model binding. It simplifies form state management and Blade rendering, helping you build complex forms faster with less boilerplate in Livewire applications.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require nodus-it/livewire-forms. The package is 0.x, so pin an exact version ("nodus-it/livewire-forms": "0.11.2") rather than using ^0.11 — minor bumps in a pre-1.0 package can change method signatures.
  • Read in this order: README.md (usage examples) → the abstract form class in src/ → src/Fields/ (available field types and their modifiers) → resources/views/ (what actually gets rendered). Class and method names have shifted across 0.x releases; the base form class is the source of truth, not blog posts.
  • Fastest first use case: take an existing hand-written Livewire CRUD form (create/edit a Post or User) and port it. Define the form as a class, declare fields as text/select/checkbox/etc., bind an Eloquent model, and render it from Blade as a Livewire component.
  • Confirm the integration works end-to-end with one field before porting the whole form: render → type → submit → validate → save. Most setup friction is in rendering (component alias/namespace) rather than in field definition.

Implementation Patterns

  • One form class per resource. Keep field definitions, validation, and the submit handler in the same class next to each other. Resist a "god form" shared across resources; the field list becomes the de facto schema and is much easier to read when it maps 1:1 to a model.
  • Declare fields in the form's field-definition method, using the field factories (text, email, select, checkbox, date, file, etc.) and chain modifiers for label, placeholder, required, default, and options. This keeps markup out of Blade — the package's Blade views render the whole form, and your templates shrink to a single component tag.
  • Bind the model in mount() (constructor argument or explicit setter) rather than in render(). Binding once in mount() means the field values hydrate correctly and you avoid re-reading from the database on every request.
  • Validation lives with the field, but the override point is the form's rules/validation method. Put field-specific rules on the field, and cross-field or conditional rules (e.g. "company required when type = business") in the form-level override. Validate explicitly in your submit action rather than relying on Livewire's automatic updated validation, which fires per-keystroke and is noisy on large forms.
  • Buttons as actions. Define submit/cancel as buttons with handlers on the form rather than wire:click in Blade. That keeps the save() → redirect() (or dispatch('saved')) flow in one place and lets the button be reused in modals.
  • Compose, don't inherit. For a large resource, split into sections/field groups and reuse small, purpose-built form classes for sub-entities (address block, line items) instead of subclassing one big form.
  • Custom field: extend the package's base field class, point it at a Blade view, and register any JS/CSS assets through the package's asset hook. This is the intended extension point — avoid editing published vendor views, since the next patch will overwrite your changes.
  • Test with Livewire::test(YourForm::class, ['post' => $post]), then set('field', $value), call('submit'), and assert both the validation errors and the persisted row. Forms are plain Livewire components, so no special test harness is needed.

Gotchas and Tips

  • Version 0.x means pin and diff. v0.11.2 was published with an empty changelog (compare link only), so the contents are unknown from the release page alone. Practically: treat it as a bugfix-only patch, pin it, and read git diff v0.11.1..v0.11.2 before deploying to anything non-trivial. If you were on v0.11.1, a composer update should be low risk, but verify form rendering in a browser — patches to a form builder frequently touch Blade views.
  • Livewire hydration vs. closures. Fields must be serializable across requests. Build the field collection in mount()/a lifecycle hook, not in a public property assigned from a closure or an unsaved model instance.
  • Field naming and the error bag. Validation error keys follow the form's field naming convention (often nested, e.g. fields.name). When rendering errors manually or in tests, check the exact key with $this->getErrorBag()->keys() rather than guessing — mismatched keys are the most common cause of "validation isn't showing".
  • wire:model timing. Default deferred binding means the server value lags the input. Anything that depends on the current value mid-typing (dependent selects, conditional fields) needs live binding on that specific field — do it per-field, not globally, or the form gets chatty.
  • Unique rules on update. An unique rule on a bound model will fail against the record itself. Pass the record's key as an ignore value in the rule, and remember the ignore ID must come from the bound model, not from the request payload.
  • Multiple forms on one page. Set a distinct form ID per instance, otherwise field IDs and wire:model targets collide and the wrong form submits.
  • File uploads need Livewire's file-upload trait on the component and a temporary-upload disk configured; a field will render fine but silently fail to upload without it.
  • After save: redirect explicitly. Re-rendering the same mounted form after save() often leaves stale field state (particularly on create, where the model now has an ID the form doesn't know about) — redirecting to an edit route sidesteps the whole class of bugs.
  • Debugging: dump the resolved field collection before render. If a field renders with the wrong value, the problem is almost always binding (model not set in mount()) rather than the field type. Publish the package views only when you need to inspect the render tree; unpublish/restore before upgrading.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums