Laravel Form builder for version 5+!

Overview

Build Status Coverage Status Total Downloads Latest Stable Version License

Laravel 5 form builder

Join the chat at https://gitter.im/kristijanhusak/laravel-form-builder

Form builder for Laravel 5 inspired by Symfony's form builder. With help of Laravels FormBuilder class creates forms that can be easy modified and reused. By default it supports Bootstrap 3.

Laravel 4

For Laravel 4 version check laravel4-form-builder.

Bootstrap 4 support

To use bootstrap 4 instead of bootstrap 3, install laravel-form-builder-bs4.

Upgrade to 1.6

If you upgraded to >1.6.* from 1.5.* or earlier, and having problems with form value binding, rename default_value to value.

More info in changelog.

Documentation

For detailed documentation refer to https://kristijanhusak.github.io/laravel-form-builder/.

Changelog

Changelog can be found here.

Installation

Using Composer

composer require kris/laravel-form-builder

Or manually by modifying composer.json file:

{
    "require": {
        "kris/laravel-form-builder": "1.*"
    }
}

And run composer install

Then add Service provider to config/app.php

    'providers' => [
        // ...
        Kris\LaravelFormBuilder\FormBuilderServiceProvider::class
    ]

And Facade (also in config/app.php)

    'aliases' => [
        // ...
        'FormBuilder' => Kris\LaravelFormBuilder\Facades\FormBuilder::class
    ]

Notice: This package will add laravelcollective/html package and load aliases (Form, Html) if they do not exist in the IoC container.

Quick start

Creating form classes is easy. With a simple artisan command:

php artisan make:form Forms/SongForm --fields="name:text, lyrics:textarea, publish:checkbox"

Form is created in path app/Forms/SongForm.php with content:

<?php

namespace App\Forms;

use Kris\LaravelFormBuilder\Form;
use Kris\LaravelFormBuilder\Field;

class SongForm extends Form
{
    public function buildForm()
    {
        $this
            ->add('name', Field::TEXT, [
                'rules' => 'required|min:5'
            ])
            ->add('lyrics', Field::TEXTAREA, [
                'rules' => 'max:5000'
            ])
            ->add('publish', Field::CHECKBOX);
    }
}

If you want to instantiate empty form without any fields, just skip passing --fields parameter:

php artisan make:form Forms/PostForm

Gives:

<?php

namespace App\Forms;

use Kris\LaravelFormBuilder\Form;

class PostForm extends Form
{
    public function buildForm()
    {
        // Add fields here...
    }
}

After that instantiate the class in the controller and pass it to view:

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller as BaseController;
use Kris\LaravelFormBuilder\FormBuilder;

class SongsController extends BaseController {

    public function create(FormBuilder $formBuilder)
    {
        $form = $formBuilder->create(\App\Forms\SongForm::class, [
            'method' => 'POST',
            'url' => route('song.store')
        ]);

        return view('song.create', compact('form'));
    }

    public function store(FormBuilder $formBuilder)
    {
        $form = $formBuilder->create(\App\Forms\SongForm::class);

        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }

        // Do saving and other things...
    }
}

Alternative example:

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller as BaseController;
use Kris\LaravelFormBuilder\FormBuilder;
use App\Forms\SongForm;

class SongsController extends BaseController {

    public function create(FormBuilder $formBuilder)
    {
        $form = $formBuilder->create(SongForm::class, [
            'method' => 'POST',
            'url' => route('song.store')
        ]);

        return view('song.create', compact('form'));
    }

    public function store(FormBuilder $formBuilder)
    {
        $form = $formBuilder->create(SongForm::class);

        if (!$form->isValid()) {
            return redirect()->back()->withErrors($form->getErrors())->withInput();
        }

        // Do saving and other things...
    }
}

If you want to store a model after a form submit considerating all fields are model properties:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Kris\LaravelFormBuilder\FormBuilder;
use App\SongForm;

class SongFormController extends Controller
{
    public function store(FormBuilder $formBuilder)
    {
        $form = $formBuilder->create(\App\Forms\SongForm::class);
        $form->redirectIfNotValid();
        
        SongForm::create($form->getFieldValues());

        // Do redirecting...
    }

You can only save properties you need:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Kris\LaravelFormBuilder\FormBuilder;
use App\SongForm;

class SongFormController extends Controller
{
    public function store(FormBuilder $formBuilder, Request $request)
    {
        $form = $formBuilder->create(\App\Forms\SongForm::class);
        $form->redirectIfNotValid();
        
        $songForm = new SongForm();
        $songForm->fill($request->only(['name', 'artist'])->save();

        // Do redirecting...
    }

Or you can update any model after form submit:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Kris\LaravelFormBuilder\FormBuilder;
use App\SongForm;

class SongFormController extends Controller
{
    public function update(int $id, Request $request)
    {
        $songForm = SongForm::findOrFail($id);

        $form = $this->getForm($songForm);
        $form->redirectIfNotValid();

        $songForm->update($form->getFieldValues());

        // Do redirecting...
    }

Create the routes

// app/Http/routes.php
Route::get('songs/create', [
    'uses' => 'SongsController@create',
    'as' => 'song.create'
]);

Route::post('songs', [
    'uses' => 'SongsController@store',
    'as' => 'song.store'
]);

Print the form in view with form() helper function:

<!-- resources/views/song/create.blade.php -->

@extends('app')

@section('content')
    {!! form($form) !!}
@endsection

Go to /songs/create; above code will generate this html:

<form method="POST" action="http://example.dev/songs">
    <input name="_token" type="hidden" value="FaHZmwcnaOeaJzVdyp4Ml8B6l1N1DLUDsZmsjRFL">
    <div class="form-group">
        <label for="name" class="control-label">Name</label>
        <input type="text" class="form-control" id="name">
    </div>
    <div class="form-group">
        <label for="lyrics" class="control-label">Lyrics</label>
        <textarea name="lyrics" class="form-control" id="lyrics"></textarea>
    </div>
    <div class="form-group">
        <label for="publish" class="control-label">Publish</label>
        <input type="checkbox" name="publish" id="publish">
    </div>
</form>

Or you can generate forms easier by using simple array

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller as BaseController;
use Kris\LaravelFormBuilder\FormBuilder;
use Kris\LaravelFormBuilder\Field;
use App\Forms\SongForm;

class SongsController extends BaseController {

    public function create(FormBuilder $formBuilder)
    {
        $form = $formBuilder->createByArray([
                        [
                            'name' => 'name',
                            'type' => Field::TEXT,
                        ],
                        [
                            'name' => 'lyrics',
                            'type' => Field::TEXTAREA,
                        ],
                        [
                            'name' => 'publish',
                            'type' => Field::CHECKBOX
                        ],
                    ]
            ,[
            'method' => 'POST',
            'url' => route('song.store')
        ]);

        return view('song.create', compact('form'));
    }
}

Contributing

Project follows PSR-2 standard and it's covered with PHPUnit tests. Pull requests should include tests and pass Travis CI build.

To run tests first install dependencies with composer install.

After that tests can be run with vendor/bin/phpunit

Comments
  • Many to Many collection displayed as select

    Many to Many collection displayed as select

    Not really an issue but I wouldn't know where else to ask.

    I have a Movie with a belongsToMany languages association.

    Let's say a Movie has 2 languages (english and spanish).

    I'm trying to show 2 selects with a list of all languages, where the first one has 'english' as selected and the second one has 'spanish'. option value should be the language id.

    This is my attempt, within MovieForm:

    $this
    ->add('languages', 'collection', [
      'type' => 'select',
      'property' => 'name',
      'choices' => $this->model->languages()->lists('id', 'name')
    ])
    

    This is obviously wrong (shows an empty select), but I'm not sure how to accomplish this, the documentation is not very clear about this. I'd like to avoid using a child LanguageForm as it would just display a select.

    opened by koichirose 36
  • Pass Model to ChildForm

    Pass Model to ChildForm

    How do i pass a model reference to childs forms?

        public function buildForm()
        {
            $this
                ->add('User', 'form', [
                    'class' => 'App\Forms\UserForm',
                    'formOptions' => [],
                    'model' => $user,
                ])->add('Company', 'form', [
                    'class' => 'App\Forms\CompanyForm',
                ]);
        }
    

    'model'=>$user is not working...form is rendered, but empty

    opened by mstaack 33
  • Fix `mergeOptions` behavior

    Fix `mergeOptions` behavior

    \Kris\LaravelFormBuilder\FormHelper::mergeOptions merges options with rules option behavior incorrectly. It should replace the rules entirely or just appends new rules. The current strategy may cause the merged rules duplicated, and has no way to "replace" the default rules entirely.

    opened by yaquawa 24
  • Laravel 5.2.32 or greater breaks form

    Laravel 5.2.32 or greater breaks form

    When updating to Laravel 5.2.32 or greater, I get the following error when trying to display a form with a button. Removing the button works.

    Relationship method must return an object of type lluminate\Database\Eloquent\Relations\Relation

    /* EditMediaForm.php */
    
    public function buildForm()
    {
         $this->add('filename', 'text')
             ->add('alt_attribute', 'text')
             ->add('save', 'submit', ['attr' => ['class' => 'btn btn-primary']]);
    }
    
    opened by vincehollywood 23
  • Add default classes to a field.

    Add default classes to a field.

    It's currently only possible to set one class for a form field. When you set a default class in your laravel-form-builder.php file and then set a new class in your form builder array then only the last class will be added.

    In this commit I've created the following things:

    1. Default classes on the field wrapper for all fields (form-TYPE) in addition to the class that you set in wrapper_class.
    2. Additional class on the field wrapper for choice fields (form-TYPE and form-type-CHOICETYPE
    3. Wrapper class on the choice options wrapper (form-CHOICETYPE)
    4. You can add additional classes without overwriting the defaults (I've added a array_merge_map_recursive function for this).
    opened by jvdlaar 23
  • Add form composition

    Add form composition

    This PR adds the ability to take a child form and add its fields directly to the parent form.

    Added makeField() as an abstracted method of generating the FormField Added compose which is used the same way as add() just only needing $options and the $modify flag. It creates the child form as usual via the new makeField() function, then just adds all the fields from that child form, to the parent form.

    I've thrown this together as it fixed my issue of trying to use child forms to help with composition of forms but it messed up using model binding, and this is the best solution anyway I just hadnt thought of it till now :P

    opened by theshaunwalker 23
  • Set data for child forms and create named forms.

    Set data for child forms and create named forms.

    Not sure if this was bug or missing feature, but I was not able to pass data for child forms. Now its possible. Also added new method in FormBuilder to create named forms like Symfony does. Form field names become like youname[fieldname].

    opened by tormit 22
  • Add a `ContainerType` field

    Add a `ContainerType` field

    This PR adds a ContainerType field which solves #572. It was branched from #577 , so you might only want to see the diff at https://github.com/kristijanhusak/laravel-form-builder/commit/d016cba31cabfded082919f0bebaa8efa106bc06

    ContainerType field acts as a "container", which means even it has children fields, but it'll make the hierarchy of it's children as same as itself. In other words, the field's attributes and rules are be replaced by its children's ones(similar to ChildFormType). With this, users can easily implement fieldset or similar things by just specifying a custom template.

    Usage

    <?php
    
    namespace App\Forms;
    
    class MyForm extends Form
    {
        public function buildForm()
        {
            $this
                ->add('date', 'container', [
                    'label' => 'DATE',
                    'fields' => [
                        [
                            'type' => 'date',
                            'name' => 'start_date',
                            'options' => [
                                'label' => false,
                                'rules' => 'required|date|max:255',
                            ],
                        ],
                        [
                            'type' => 'date',
                            'name' => 'end_date',
                            'rules' => 'date|max:255',
                            'options' => [
                                'label' => false,
                                'rules' => 'date|max:255',
                            ],
                        ]
                    ],
                ]);
        }
    }
    
    opened by yaquawa 20
  • #246 +Form->getValidatedValues()

    #246 +Form->getValidatedValues()

    Adds a public $form->getValidatedValues() function to extract all Request values according to the submitted form, not according to the submitted data. Uses all fields' getAllAttributes() to collect a flat list of all attributes, including all child forms and theirs etc.

    The main function (getValidatedValues) is somewhat of a misnomer, because it doesn't actually validate, and the returned values don't have to be validated in order to call it, but I couldn't find a better name.

    Usage: instead of

    $values = $request->all();
    

    call

    $values = $form->getValidatedValues();
    
    opened by rudiedirkx 19
  • Added a new method `Form::group`.

    Added a new method `Form::group`.

    Alternative PR to #580 which implemented a new group method. It was branched from #577 you can compare the changes at here (I'm going to rebase this on master once #577 get merged)

    Usage

    $form
        ->add('foo')
        ->group(function (FieldGroup $fieldGroup) {
            $fieldGroup->add('bar');
            $fieldGroup->add('foobar');
            $fieldGroup->group(function (FieldGroup $subFieldGroup) {
                $subFieldGroup->add('sub_bar');
                $subFieldGroup->add('sub_foobar');
            });
        })
        ->group(function (FieldGroup $fieldGroup) {
            $fieldGroup->add('baz');
        })
        ->add('qux');
    

    Outputs:

    <form method="GET" action="http://localhost" accept-charset="UTF-8">
        <div class="form-group">
            <label for="foo" class="control-label">Foo</label>
            <input class="form-control" name="foo" type="text" id="foo">
        </div>
        <fieldset class="form-group">
            <div class="form-group">
                <label for="bar" class="control-label">Bar</label>
                <input class="form-control" name="bar" type="text" id="bar">
            </div>
            <div class="form-group">
                <label for="foobar" class="control-label">Foobar</label>
                <input class="form-control" name="foobar" type="text" id="foobar">
            </div>
            <fieldset class="form-group">
                <div class="form-group">
                    <label for="sub_bar" class="control-label">Sub bar</label>
                    <input class="form-control" name="sub_bar" type="text" id="sub_bar">
                </div>
                <div class="form-group">
                    <label for="sub_foobar" class="control-label">Sub foobar</label>
                    <input class="form-control" name="sub_foobar" type="text" id="sub_foobar">
                </div>
            </fieldset>
        </fieldset>
        <fieldset class="form-group">
            <div class="form-group">
                <label for="baz" class="control-label">Baz</label>
                <input class="form-control" name="baz" type="text" id="baz">
            </div>
        </fieldset>
        <div class="form-group">
            <label for="qux" class="control-label">Qux</label>
            <input class="form-control" name="qux" type="text" id="qux">
        </div>
    </form>
    
    opened by yaquawa 18
  • Add help_block doesn´t work

    Add help_block doesn´t work

    Hello,

    i have the problem that i can't add the help_block (dynamic).

    The Code:

    <?php
    //In buildForm():
    $customOptions = [];
    $withHelpBlock = true;
    // Add Some Other Options (these Options work)
    if($withHelpBlock)
    $customOptions = array_merge($customOptions, ['help_block' => ['text' => 'Please select your Company','tag' => 'p','attr' => ['class' => 'help-block']]]);
    }
    $this->add('company','select',$customOptions);
    

    And the result is an Select Input with all other options that i define, but without the helpblock.

    So it is the same as in the documentation... Can you help? Or is that a Bug? Laravel 5.2 and laravel-form-builder 1.7.10 Thank You! @kristijanhusak

    opened by LKaemmerling 17
  • accept closure attributes (eg wrapper.class)

    accept closure attributes (eg wrapper.class)

    This change accepts attributes to be closures (resolved by Laravel's value()). That's not useful for most fields, because all context is present where the field is defined. But it is useful for collection fields, because you define the same attributes for all the items/child forms. This way you can dynamically add different attributes for different items:

    class ParentForm {
    	function buildForm() {
    		$this->add('items', 'collection', [
    			'type' => 'form',
    			'prototype' => false,
    			'empty_model' => fn() => new ChildModel,
    			'options' => [
    				'class' => ChildForm::class,
    				'wrapper' => [
    					// current
    					'class' => 'non-dynamic class',
    					// new, optional syntax
    					'class' => function(\Kris\LaravelFormBuilder\Fields\FormField $field) {
    						$model = $field?->getForm()?->getModel();
    						return 'use $model->id to add highlight class';
    					},
    				],
    			],
    		]);
    	}
    }
    

    I use this to highlight some collection items if they contain problems.

    $field is the collection item field. In this case a ChildFormType because type = form. It could be a InputType, which doesn't have a getForm() and doesn't really know anything useful. It's most useful for child forms.

    opened by rudiedirkx 0
  • always try to return a real makeNewEmptyModel

    always try to return a real makeNewEmptyModel

    This is probably too invasive, and maybe still broken, but it's a way to always get an empty model, even if you don't set empty_model. Because currently the parent's model is used for the child's model and that's just weird (wrong class) and wrong (if fields/columns/properties match, the parent's values are used).

    opened by rudiedirkx 0
  • Smarter formatInputIntoModels for non-Models

    Smarter formatInputIntoModels for non-Models

    empty_model only works for Eloquent models, but it's also useful for an array of data. In GET that's used for the prototype and empty_row children. In POST it's used as a basis to put POST data into. Without empty_model, the parent model is used, which is weird. (That hasn't changed.) So it's always nice to have an empty_model, even if it's not a real Model.

    opened by rudiedirkx 0
Releases(1.51.2)
A powerful form builder, for Laravel and other frameworks (stand-alone too)

Former A Laravelish way to create and format forms Former outputs form elements in HTML compatible with your favorite CSS framework (Bootstrap and Fou

null 1.3k Dec 22, 2022
Laravel Livewire (TALL-stack) form generator with realtime validation, file uploads, array fields, blade form input components and more.

TALL-stack form generator Laravel Livewire, Tailwind forms with auto-generated views. Support Contributions Features This is not an admin panel genera

TinaH 622 Jan 2, 2023
A demo of how to use filament/forms to build a user-facing Form Builder which stores fields in JSON.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Dan Harrin 41 Dec 24, 2022
Composer package which adds support for HTML5 elements using Laravels Form interface (e.g. Form::date())

Laravel HTML 5 Inputs Composer package which adds support for HTML5 elements by extending Laravel's Form interface (e.g. Form::date()) Adds support fo

Small Dog Studios 11 Oct 13, 2020
Provides a Eloquent query builder for Laravel or Lumen

This package provides an advanced filter for Laravel or Lumen model based on incoming requets.

M.Fouladgar 484 Jan 4, 2023
Laravel Mysql Spatial Builder Extension

magutti-spatial V2 Laravel Builder Mysql Spatial Extension Laravel Builder extensions to calculate distances between two Spatial points using Mysql na

Marco Asperti 4 Oct 2, 2022
A TWBS menu builder for Laravel

Laravel Menu Builder A menu builder for Laravel 4-5 using Bootstrap's markup. Документация на Русском Note that this package is shipped with no styles

Alexander Kalnoy 24 Nov 29, 2022
A simple to use query builder for the jQuery QueryBuilder plugin for use with Laravel.

QueryBuilderParser Status Label Status Value Build Insights Code Climate Test Coverage QueryBuilderParser is designed mainly to be used inside Laravel

Tim Groeneveld 149 Nov 11, 2022
A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)

Laravel MongoDB This package adds functionalities to the Eloquent model and Query builder for MongoDB, using the original Laravel API. This library ex

Jens Segers 6.3k Jan 7, 2023
Laravel API architecture builder based on artisan commands.

??‍?? API-Formula Laravel API architecture builder based on artisan commands. This package provides a nice and fluent way to generate combined control

Krševan Lisica 1 Jan 16, 2022
A Laravel Admin Starter project with Page Builder, Roles, Impersonation, Analytics, Blog, News, Banners, FAQ, Testimonials and more

Laravel CMS Starter Project A Laravel CMS Starter project with AdminLTE theme and core features. Preview project here User: [email protected]

Ben-Piet O'Callaghan 306 Nov 28, 2022
Builder - A handful of tools for Rapid Laravel Development

Grafite Builder Grafite has archived this project and no longer supports or develops the code. We recommend using only as a source of ideas for your o

Grafite Inc 997 Dec 22, 2022
A DynamoDB based Eloquent model and Query builder for Laravel.

Laravel DynamoDB A DynamoDB based Eloquent model and Query builder for Laravel. You can find an example implementation in kitar/simplechat. Motivation

Satoshi Kita 146 Jan 2, 2023
Razorpay payment gateway integration in laravel with submit form and storing details in payment table.

Integrating razorpay payment gateway in laravel with submit form and storing payment details in payment table. How to settup the project in your local

Mohammed-Thamnees 3 Apr 15, 2021
Laravel Livewire form component with declarative Bootstrap 5 fields and buttons.

Laravel Livewire Forms Laravel Livewire form component with declarative Bootstrap 5 fields and buttons. Requirements Bootstrap 5 Installation composer

null 49 Oct 29, 2022
🧙‍♀️ Arcanist takes the pain out of building multi-step form wizards in Laravel.

Installation Arcanist requires PHP 8 and Laravel 8. composer require laravel-arcanist/arcanist Documentation You can find the full documentation here

Arcanist 378 Jan 3, 2023
A TALL-based Laravel Livewire component to replace the (multiple) select HTML input form with beautiful cards.

TALL multiselect cards A TALL-based Laravel Livewire component to replace the (multiple) select HTML input form with beautiful cards. Table of content

Frederic Habich 19 Dec 14, 2022
Generate form validators for Laravel: an extension of way/generators

Laravel Form Validator Contents Introduction Installation Usage Example Tests Introduction After using Jeffrey Way's Generator and his Validator packa

John Evans 6 Jan 14, 2022
Rapid form generation with Bootstrap 3 and Laravel.

Important: This package is not actively maintained. For bug fixes and new features, please fork. BootForms BootForms builds on top of my more general

Adam Wathan 423 Jun 14, 2022