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

Form Laravel Package

hafijul233/form

Hafijul233/Form is a Laravel package for building dynamic forms with a fluent PHP API. Define fields, validation rules, and layouts in code, then render ready-made markup. It streamlines complex form creation and submission handling in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install

composer require hafijul233/form

Laravel's package auto-discovery should register the service provider. Verify with php artisan about (Providers section) or check vendor/hafijul233/form/composer.json for the extra.laravel.providers entry — if it isn't auto-discovered, add it to config/app.php manually.

Version note (0.2.0). The current release is 0.2.0 (from 0.1.4). The only change is a fix for inline styles leaking into rendered markup (PR #57). Nothing else in the API surface moved, so if you evaluated 0.1.x the rest of this assessment still holds — just install ^0.2 and re-check one rendered form to confirm the markup is clean.

Publish what's publishable

php artisan vendor:publish --provider="Laraflow\Form\FormServiceProvider"

List tags first if the package registers them (--tag=config, --tag=views) so you don't dump assets you don't want. Then php artisan config:clear.

Look here first

  1. README.md — the canonical API surface for a 16-star package; it's usually ahead of any docs site.
  2. src/ — especially the facade, the builder class, and the Components/ or Fields/ directory. That directory listing is your available field types.
  3. config/form.php — bootstrap version, view namespace, default classes, and any inline-style defaults.
  4. resources/views/ — the Blade templates you'll override when the markup doesn't match your design system.
  5. tests/ — the fastest way to learn intended usage; assert against real rendered strings.

First use case: a login form in Blade

Add Bootstrap CSS/JS to your layout (the package renders Bootstrap markup; it does not ship CSS). Then in resources/views/auth/login.blade.php:

{!! Form::open(['route' => 'login', 'method' => 'post']) !!}
    {!! Form::email('email', old('email'), ['label' => 'Email', 'required' => true]) !!}
    {!! Form::password('password', ['label' => 'Password', 'required' => true]) !!}
    {!! Form::checkbox('remember', 'Remember me') !!}
    {!! Form::submit('Sign in', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}

If the facade alias differs (Form vs FormBuilder), alias it in config/app.php or use Laraflow\Form\Facades\Form; at the top of the file. Getting one form rendering end-to-end — fields, labels, error state, old input — tells you more about this package than any doc.

Implementation Patterns

Blade-first, not controller-first. This package is a rendering layer, not a form-object abstraction. Compose in Blade, keep validation in Form Requests, and let the builder handle markup. Don't try to make it do what Laravel's FormRequest + Blade components already do — that's how you end up fighting it.

Model binding for edit screens. Most builders in this family accept a value object or array as a second/third argument, so an edit form repopulates without a value on every field:

{!! Form::model($post, ['route' => ['posts.update', $post], 'method' => 'put']) !!}
    {!! Form::text('title') !!}
    {!! Form::textarea('body') !!}
    {!! Form::select('status', $statuses) !!}
{!! Form::close() !!}

Confirm the exact binding signature in src/ — if there's no model() helper, pass $post->title explicitly per field and use old('title', $post->title) so validation redirects still win.

Reusable partials beat long templates. Extract repeated groupings into resources/views/partials/forms/*.blade.php and @include them with a data array. This is the cheapest way to get consistency without writing a custom component.

Layout wrappers for grid control. Bootstrap forms need form-group/mb-3 plus row/col-* for horizontal layouts. Pass wrapper options per call or set global defaults in config/form.php and override per-field — per-field overrides keep global config sane.

Custom field types. When you need something the package doesn't ship (a toggle switch, a currency input, a searchable select), find the base component class in src/ and either extend it or register a Blade view override. Prefer the view override: it survives package upgrades far better than subclassing internals.

Integrate with Form Requests, not with the builder. Validation rules, messages, and old()/$errors come from Laravel. The builder just needs to read $errors->has($name) — verify it does this automatically; if not, pass ['error' => $errors->first('email')] manually.

AJAX/Livewire boundary. For anything dynamically re-rendering (Livewire, Inertia, Alpine), use the builder only for the initial server render, or drop it entirely for those fields. Mixing a PHP string builder with client-side reactivity gets ugly fast — the builder has no concept of state changes.

Buttons and actions as a block. Use Form::submit() + Form::button() with consistent classes; if you have several actions (save / save-and-continue / cancel), wrap them in one partial so the button order and spacing are defined in a single place.

Gotchas and Tips

Bootstrap version drift is the #1 failure mode. A package built for Bootstrap 4 emits form-group and custom-select; Bootstrap 5 wants mb-3 and form-select. Nothing errors — it just looks wrong. Check the package's composer/README for the target version before wiring it into a BS5 app, and expect to override views if they mismatch.

Inline styles: fixed in 0.2.0, but check anyway. 0.1.4 and earlier could emit inline style="..." attributes on wrapper elements (fixed in 0.2.0, PR #57), which fights any CSP with style-src restricted and breaks utility-class theming. If you're on 0.1.x, upgrade; if you were on 0.1.x and had hand-patched the published views to strip those attributes, re-publish/compare against the 0.2.0 views so you aren't shipping a stale override that reintroduces the problem — and diff them again after any future inline-style changes. If you maintain a strict CSP, verify with {{ Form::text('x') }} in a scratch route and grep the raw string for style=.

Unescaped output. {!! !!} is required for the builder's HTML. The flip side: any value you pass in is now your responsibility. Confirm the package escapes field values and labels internally (grep for e( or htmlspecialchars in src/). If it doesn't, escape user-supplied values yourself before passing them.

old() and error state. The most common bug report on packages like this: after a failed validation redirect, the form comes back empty. Either use model() binding, or pass old('field', $default) explicitly. Test the sad path (submit invalid → redirect back) on day one; it's the thing you'll otherwise discover in production.

CSRF. Form::open() may or may not inject the token. Grep the open-tag template. If it doesn't, add @csrf inside, or set it in config. A silent 419 on every POST is a miserable first-hour bug.

Config caching in production. php artisan config:cache will freeze config/form.php. Any per-environment class/view settings need to be env-driven before you cache, not hardcoded.

Override views, don't fork. Publish the view namespace and edit the copies in resources/views/vendor/.... Never edit vendor/ — the next composer update silently reverts your work. Re-diff your overrides after each release: 0.2.0 touched the markup (inline styles), so an override copied from 0.1.x may now be strictly worse than upstream.

Low adoption = high bus factor. 16 stars, 0 dependents, a single maintainer. That's fine for internal tooling, risky for a long-lived product. Pin an exact version in composer.json, commit composer.lock, and keep a thin wrapper (your own Blade partials) so swapping the builder out later is a one-file change rather than a grep across 60 templates. Note that 0.1.4 → 0.2.0 was a minor bump in a 0.x package — by semver that's allowed to carry breaking changes, and you only find out by reading the changelog (here: a bugfix only). Prefer ^0.2 with a lockfile over a floating constraint, and read each release note before bumping.

Debugging rendered markup. When something looks off, dump the string: {{ Form::text('x') }} in a scratch route or dd(Form::text('x')->render()). Component bugs are almost always a missing wrapper class or a config default being appended twice — read the raw HTML, don't guess from the browser. Inline attributes (style, stray class) are the usual fingerprint, which is exactly what 0.2.0 addressed.

Watch for macro/registration order. If the package exposes macros or a Form::component()-style registry, registration must happen in a service provider boot() before any view renders. Registering in a controller or middleware is a classic "works locally, 500s under Octane/queue" trap.

Tests as documentation. With sparse docs, write a handful of assertSee tests against your own form partials. They double as upgrade guards when the next release (cadence looks active) changes markup — and an assertDontSee('style=', false) assertion is a cheap, permanent regression check for the class of bug 0.2.0 fixed.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console