ajaylove1shi / laravel-form-bridge
Bridges the gap between backend validation and frontend UI architecture by dynamically parsing Laravel FormRequest structures into clean, extensible, class-prefixed HTML5 input components.
Package info
github.com/ajaylove1shi/laravel-form-bridge
pkg:composer/ajaylove1shi/laravel-form-bridge
Requires
- php: ^8.1|^8.2|^8.3
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- illuminate/view: ^10.0|^11.0|^12.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
README
Laravel Form Bridge bridges the gap between your backend validation rules and frontend UI architecture. By reading the rules() and fields() array metadata inside your custom FormRequest classes, this package automatically generates a modular, class-based HTML5 input rendering helper matrix (UserInputs).
It provides native layout scoping capabilities, zero structural collisions using custom styling prefixes, easy integration with component engines (Bootstrap, Tailwind, etc.), customizable blade templates, and dynamic runtime macro injection.
Requirements
Before installing, ensure your technical environment meets the following conditions:
- PHP:
^8.1 | ^8.2 | ^8.3 - Laravel Framework:
^10.0 | ^11.0 | ^12.0 | ^13.0
Installation
You can install the library directly via composer:
composer require ajaylove1shi/laravel-form-bridge
Configuration
The package comes preconfigured with standard global configurations out of the box. To change the default values, publish the config asset using the vendor engine:
php artisan vendor:publish --tag=laravel-form-bridge-config
This will generate a file at config/laravel-form-bridge.php:
<?php return [ /* |-------------------------------------------------------------------------- | Default HTML Attributes |-------------------------------------------------------------------------- | These default attributes are automatically applied to every generated input. | Swap 'form-control' out for utility classes (e.g., Tailwind or Bootstrap). */ 'default_attributes' => [ 'class' => 'form-control', ], /* |-------------------------------------------------------------------------- | Global CSS & JS Hook Prefix |-------------------------------------------------------------------------- | The prefix applied to all container classes and data attributes to | prevent style/script naming collisions across your pages. */ 'prefix' => 'cfg-', ];
Laravel 8 & 9 only: Add the service provider manually in config/app.php if auto-discovery doesn't work:
'providers' => [ AjayLove1shi\LaravelFormBridge\InputServiceProvider::class, ],
Target Request Class Structure
To use the automated input scaffolding engine, your FormRequest must declare both a rules() array and an informative fields() metadata array.
Create your request file (e.g., app/Http/Requests/StoreUserRequest.php):
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class StoreUserRequest extends FormRequest { public function authorize(): bool { return true; } public function rules(): array { return [ 'name' => 'required|string|min:1|max:127', 'email' => 'required|email|max:127', ]; } /** * Provide presentation labels and helper context for frontend construction. */ public function fields(): array { return [ 'name' => [ 'label' => 'Full Name', 'placeholder' => 'Enter your full name.', 'tooltip' => 'E.g., John Doe', 'description' => 'The full name associated with your account.', ], 'email' => [ 'label' => 'Email Address', 'placeholder' => 'Enter your email address.', 'tooltip' => 'E.g., user@example.com', 'description' => 'The primary email address used for communication.', ], ]; } }
Artisan Commands
make:form-inputs
Inspects a designated FormRequest layout to construct your decoupled UserInputs layout helper structure inside your application.
php artisan make:form-inputs {RequestClassName} {--name=OptionalClassName}
Example Usage:
# Generates app/Forms/UserInputs.php reading StoreUserRequest mappings php artisan make:form-inputs StoreUserRequest # Customize the output filename explicitly php artisan make:form-inputs StoreUserRequest --name=AccountOnboardingInputs
Utilizing the Generated Class in Blade
Once generated, you can initialize your class wrapper directly inside your views or inject it using data controllers.
@php
// Initialize the helper. Override default classes or custom UI namespace hooks on the fly.
$form = new \App\Forms\UserInputs(['class' => 'shadow-sm'], 'user-profile-');
@endphp
<form method="POST" action="/profile/update">
@csrf
{!! $form->name($user->name ?? '') !!}
{!! $form->email(null, ['disabled' => true, 'placeholder' => 'locked@domain.com']) !!}
{!! $form->select('status', 'Workspace Status', [
'active' => 'Active Membership',
'pending' => 'Pending Verification'
], 'active') !!}
<button type="submit" class="btn btn-primary">Save Changes</button>
</form>
@php
$form = new \App\Forms\UserInputs(['class' => 'form-control'], 'app-form-');
@endphp
<form method="POST" action="/submit" enctype="multipart/form-data">
@csrf
{!! $form->name($user->name ?? '') !!}
{!! $form->email($user->email ?? '') !!}
<hr />
{!! $form->password() !!}
{!! $form->textarea('bio', $user->bio ?? '', ['rows' => 5, 'placeholder' => 'Tell us about yourself...']) !!}
{!! $form->date('birth_date', $user->dob ?? '') !!}
{!! $form->datetimeLocal('appointment_time') !!}
{!! $form->checkbox('agree_to_terms', 1, ['class' => 'custom-check-style']) !!}
@php
// Define your radio options key => display label
$genders = [
'male' => 'Male',
'female' => 'Female',
'other' => 'Other'
];
// Mocking an existing database value or default value
$currentSelection = $user->gender ?? 'male';
@endphp
<div class="gender-selection-group">
<label class="group-main-title">Select Gender:</label>
@foreach($genders as $key => $displayLabel)
{!! $form->radio('gender', null, [
'value' => $key,
'label' => $displayLabel,
'checked' => (old('gender', $currentSelection) === $key)
]) !!}
@endforeach
</div>
{!! $form->range('volume_level', 50, ['min' => 0, 'max' => 100]) !!}
{!! $form->color('theme_color', '#0076FF') !!}
{!! $form->file('avatar_upload') !!}
{!! $form->hidden('tracker_id', 'session_xyz_123') !!}
{!! $form->select('status', 'active', [
'active' => 'Active Member',
'pending' => 'Pending Verification',
'disabled' => 'Suspended Workspace'
], 'active') !!}
<div class="app-form-actions">
{!! $form->reset('reset_btn', 'Clear Form', ['class' => 'btn-secondary']) !!}
{!! $form->submit('submit_btn', 'Save Record', ['class' => 'btn-primary']) !!}
</div>
</form>
Available Methods & Magic Inputs
Explicit Field Generators
The artisan compiler builds native fields matching your request names directly:
$form->name($value = null, array $customAttributes = [])$form->email($value = null, array $customAttributes = [])
Dropdown Components (select)
The explicit dropdown field structure bypasses default parsing structures safely:
$form->select(string $name, string $label, array $options = [], $selected = null, array $customAttributes = [])
Magic HTML5 Input Types (__call)
Any standard or custom HTML5 input tag variant can be called on the fly through magic __call proxies.
| Syntax Pattern | Generated Core HTML Element Type |
|---|---|
$form->password('pass_field') |
<input type="password"> |
$form->textarea('bio', 'text content') |
<textarea>text content</textarea> |
$form->checkbox('agree', 1) |
<input type="checkbox"> |
$form->radio('gender', null, ['value' => 'm', 'label' => 'Male']) |
<input type="radio" value="m"> |
$form->date('birthday') |
<input type="date"> |
$form->datetimeLocal('appointment') |
<input type="datetime-local"> |
$form->hidden('user_id', 42) |
<input type="hidden"> |
$form->file('avatar') |
<input type="file"> |
Extending & Customizing HTML Globally
Customizing Blade Layout Templates
To modify the raw component HTML wrappers to suit your application design constraints or switch CSS frameworks, publish the views folder:
php artisan vendor:publish --tag=laravel-form-bridge-views
This exports cleanly formatted templates right into your main application directory at resources/views/vendor/laravel-form-bridge/:
form-group.blade.php(The shared element container block layout)input.blade.php(Standard HTML5 fields text, numbers, passwords)select.blade.php(The structural choice selectors option grids)textarea.blade.php(Long-form multiline containers)
Injecting Custom Components via Macros
Because the package uses the Macroable trait, you can extend the generator with custom fields at runtime. Register your macro extensions inside your App\Providers\AppServiceProvider.php boot method:
use AjayLove1shi\LaravelFormBridge\FormField; public function boot(): void { // Define an on-the-fly custom interactive map search component FormField::macro('locationPicker', function (string $name, string $label) { $attributes = FormField::attrs($name); return " <div class='custom-map-component'> <label class='map-label'>{$label}</label> <div id='geo-canvas-{$name}' class='map-canvas-frame'></div> <input type='hidden' name='{$name}' id='geo-input-{$name}'> </div> "; }); }
Now you can invoke it within your views exactly like a built-in input engine method:
{!! \AjayLove1shi\LaravelFormBridge\FormField::locationPicker('hq_coordinates', 'Headquarters Geo Target') !!}
Contributing
We welcome contributions from the community to make this library more stable and powerful! To submit changes:
- Fork the Project Repository.
- Create a feature branch tracking changes (
git checkout -b feature/amazing-feature). - Commit your changes safely (
git commit -m 'Add some amazing-feature'). - Push code updates to your remote fork branch (
git push origin feature/amazing-feature). - Open a formal Pull Request against our development pipeline.
License
This software package is distributed under the conditions of the MIT License. For deep-dive conditions regarding reuse permissions, please check the LICENSE.md file included inside this source root folder.