Home » Code » Creating forms in Laravel 4

Creating forms in Laravel 4

Posted by on August 19th, 2013

Creating forms in Laravel 4
One of the very basic requirements of all online applications is that the user should be able to enter data. Web forms are the most commonly used methods for entering data into an application and so they are a fundamental thing that you need to get right.

Laravel is a framework that aims to make developing and maintaining web applications as easy as possible. One of the ways this is achieved is by having an excellent Form class that makes creating and interacting with forms extremely easy.

A lot of other frameworks seem to make working with forms much harder then they need to be. In my experience they are either too rigid or not comprehensive enough! If you are coming at this from a non-framework perspective, using a form builder might seem a little bit strange, but hopefully by the end of this tutorial you will be able to see the benefits.

So let’s look at building Laravel forms!

Creating forms for Cribbb

If you remember back to when we were building out the Controller methods of the User resource, the create and edit methods are used to display a form so the user can create or edit a record in the system.

Both of these methods simply return a View to the browser. Open those two views up now so we can create the forms to allow new records to be created and existing records to be edited.

In order to create a form in your view, you can simply use the open and close tags of the Form class:

{{ Form::open(array('url' => 'users')) }}
{{ Form::close() }}

This will create the following HTML output:

<form method="POST" action="http://localhost:8000/users" accept-charset="UTF-8">
	<input name="_token" type="hidden" value="1gDaHZGie4TwE47wIT7T7uUU5hQOKu8hfFHG6Dwj">

Notice how the Form tags are wrapped in Blade curly braces!


As you can see, the open method accepts an array of arguments. In this case I have specified an action URL, /users.

By default the form will automatically set the method to POST. As you might already know, HTML forms only accepts POST or GET methods. However, our Controller will also be listening out for PUT or DELETE methods. If you specify that this is a PUT or DELETE request, Laravel will add a hidden parameter to your form.

To set the method to PUT, simply add it to the array of arguments:

{{ Form::open(array('url' => 'users', 'method' => 'put')) }}

This will add the following hidden parameter to your form:

<input name="_method" type="hidden" value="PUT">

Laravel will understand that you want to update this resource rather than attempt to create a new one and so the update method of the Controller will be used, instead of the store method.

Routes and Methods

If you have ever worked on a big website in the past, you will understand the pain of having to change URL routes. For whatever reason you need to change URLs and so you have to find every instance of that route in your code in order to make the transition.

Laravel 4 makes this problem go away by allowing you to use named routes or set the controller method directly in the form. This means if the URL changes, your code won’t know the difference!

To use a named route, just add a route key value pair to your arguments list:

{{ Form::open(array('route' => 'route.name')) }}

To specify a Controller method, simply add an action key value pair instead:

{{ Form::open(array('action' => 'Controller@method')) }}


When you are updating a record, you need to pass the id of the record that you want to update. To do that, you simply need to set the action to an array and pass the param as the second value:

{{ Form::open(array('action' => array('Controller@method', $user->id))) }}


If you want to use the form to upload files to the server, simply specify this as another argument:

{{ Form::open(array('action' => array('Controller@method', $user->id), 'files' => true)) }}

This will add the following to the form HTML output:

<form enctype="multipart/form-data">

HTML forms provide two methods of encoding. The default is application/x-www-form-urlencoded, which is more or less the same as a query string on the end of the URL. The other, multipart/form-data, is a more complicated encoding but one that allows entire files to be included in the data.


In the first example of the HTML output of the form, you might be thinking, what is the _token?

<input name="_token" type="hidden" value="1gDaHZGie4TwE47wIT7T7uUU5hQOKu8hfFHG6Dwj">

Laravel 4 will automatically set this token in your session and include it in your forms. The token is to prevent CSRF (Cross-Site Request Forgery).

If you use the Form class you don’t have to even think about protecting against CSRF as Laravel will automatically include the token for you. However, if you don’t want to use the form builder, you can manually generate it using the token() method:


To prevent CSRF attacks, you can attach Laravel’s CSRF filter to your routes like this:

Route::post('users', array('before' => 'csrf', function()

Form Model binding

For the majority of the time when you are working with forms, you will want to bind the input to a model. So for instance, if you are updating a user’s record, you will want the form to bind to the User model. By binding the form to the model, you can automatically populate it so when you generate the form the fields will automatically be set with the user’s data.

To bind a form to a model, use the model() method, like this:

{{ Form::model($user, array('route' => array('user.update', $user->id))) }}

{{ Form::close() }}

Now if you were to go to /users/1/edit the form will automatically be populated with the data of user 1 without you having to actually do anything!

If, for example, your user tries to update their details with data that does not pass your validation rules, the edit form will be regenerated but the incorrect data will appear in the updated fields rather than the model data. This means that your form will not only auto populate from the model, but it will also intuitively re-populate if their was a validation error, allowing the user to correct their mistakes.

Laravel’s order of preference flows like this:

  1. Session Flash Data (Old Input)
  2. Explicitly Passed Value
  3. Model Attribute Data

So the model attribute data will be set as default, but if the user has entered data that does not pass the validation, that data will take preference to enable the user to quickly correct their mistake.

Pretty cool huh?


No form would be complete without Labels and so Laravel makes it incredibly easy to generate them:

{{ Form::label('email', 'E-Mail Address') }}

If you want to specify a class for your label, simply add a third parameter:

{{ Form::label('email', 'E-Mail Address', array('class' => 'awesome')) }}

Text, Text Area, Password, Hidden and Form Fields

Generating Text fields, Text areas, Password, Hidden and Form fields are about as easy and intuitive as you would expect from Laravel:

Text field:

// Regular text field
{{ Form::text('username') }}

// Text field with a default value
{{ Form::text('email', 'Your email') }}

Text area:

// Regular text area
{{ Form::textarea('description') }}

// Text area with a default value
{{ Form::textarea('description', 'Description…') }}

Password field:

// Regular password field
{{ Form::password('password') }}

// Password field with a default value
{{ Form::text('password', 'Password') }}

Hidden field:

// Regular hidden field
{{ Form::hidden('secret_code') }}

// Hidden field with a default value
{{ Form::hidden('secret_code', 'shhhh') }}


{{ Form::file('image') }}

Checkboxes and Radio Buttons

Checkboxes and Radio buttons also have a very simple syntax. Like the previous fields, the first argument allows to you set a name for the field, the second argument allows you to set a value, and for checkboxes and radio buttons the third optional argument allows you to specify whether this field should be automatically be set to checked:

{{ Form::checkbox('admin', 'yes', true) }}

{{ Form::radio('gender', 'female', true) }}

Drop Down Lists

With drop down lists, you simply need to pass a name for the element, an array of options and an optional default value.

Simple drop down list:

{{ Form::select('Network', array(
  'facebook' => 'Facebook',
  'twitter' => 'Twitter',
  'cribbb' => 'Cribbb'
)) }}

With a selected default

{{ Form::select('Network', array(
  'facebook' => 'Facebook',
  'twitter' => 'Twitter',
  'cribbb' => 'Cribbb'), 'cribbb') }}

You can also pass a multidimensional array to create a grouped drop down list:

{{ Form::select('cribbbs', array(
  'laraval' => array("design", "development"),
  'startups' => array("advice", "strategy"),
  'business' => array("marketing", "sales")
)) }}


And finally creating submit button or a button element is as easy as this:

// Submit button
{{ Form::submit('Register') }}

// Button element
{{ Form::button('Find out more') }}


And there you have it, everything a sane person would ever want to know about creating forms in Laravel 4. Forms are pretty much essential to all web applications, and so Laravel makes it incredibly easy to generate them with a clean and simple syntax.

I also really like how Laravel can generate CSRF tokens and allow you to use PUT and DELETE methods without you having to do anything complicated. Imagine if you had to try and build that functionality yourself?!

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

To view a full listing of the tutorials in this series, click here.

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

Join the Culttt

Become an insider and join the Culttt

  • Pingback: Building out RESTful Controller methods in Laravel 4 | Culttt

  • Jordan Lane

    There is a small typo here: To use a named route, just add a route key value pair to your *augments* list:

    • http://culttt.com/ Philip Brown

      Thanks Jordan :)

      • kaliten

        what are the basic things to learn laravel?

  • snapey

    Very clear Philip.

    Here’s a little documented tip regarding checkboxes that might help someone. Browsers don’t send unchecked fields back when you submit the form. This means that if you just pass the input to your model, the boolean that you hoped to change will never get unset.
    Where you have a checkbox, be sure to check if the input field is set, and if not, create an input element it and set it false before you pass to your model.

    • http://culttt.com/ Philip Brown

      Thank you :)

      Yeah that checkbox thing has got me a couple of times in the past. It’s so annoying!

  • fraserk

    Thanks, really appreciate this.

    • http://culttt.com/ Philip Brown

      Thank you sir :)

  • Ward Kennes

    Great tutorial, is it possible to add maybe a demo too in your posts.
    I really like the way you write your posts!

    Thanks a lot!

    • http://culttt.com/ Philip Brown

      Thank you :)

      You can just grab a copy of the code from GitHub and have play about yourself :)

  • Eric

    I tested laravel4 and FuelPHP, I develop in Symfony2 and I have already programmed in ZendFramework, wholesale … I programmed and tested as in codeigniter and kohana Cakephp so many framework in order to compare.

    What you stipulate here on form creation, supposedly “easy”, you could already do in codeigniter in exactly the same way …
    And so I am also able to perceive the creation of form in Laravel, FuelPHP and Kohana is very similar (except where kohana validation rules and form submission is not really well thought out I think).

    This is all well and good that these frameworks Symfony2 greatly influences, but real large applications with many forms we find ourselves really stuck and limited to produce a lot of code instead of reusing.
    Under FuelPHP can design their forms so poo object with class Fieldset () but there again I found incomplete and the template system option is not really good (damage). Laravel do not have and I did not find anything about it.

    The stumble is to create its field types or forms with reusable validation rules, and it is not the case under Laravel as FuelPHP or kohana. Laravel FuelPHP and are very similar, FuelPHP allows even more Polivalente native Laravel that already why use template engine “blade” when there are already many very powerful template engine that will do well? As Smarty but especially Twig! (very well thought out again).

    It really perceive limits Laravel and FuelPHP on large project and that they do not play in the same course as Zend framework2 or even Symfony2.

    The class formbuilder Symfony2 is extremely well thought out (despite a few small changes that could make it.
    But Laravel FuelPHP and should do better because their form class are for small form, but no more.

    It is better to use pure html form creation rather than their class believe me, because you have much more freedom in handling fields js and html rather than their class.

    • http://culttt.com/ Philip Brown

      Wow, thank you for the comment Eric! You sound like you have a lot of experience with using form builders in frameworks!

      What aspects of ZF2 and Symfony2 make the form build much better than Laravel of Fuel?

      I’m sure I remember Taylor Otwell stating somewhere that he feels the Laravel form builder is, as you say, not as good as writing pure HTML.

      However, again as you say, I think it is really helpful for newbies who are building their first projects and they don’t need to the complication of having to write exactly the right form elements for everything to work correctly. Particularly when it comes to CSRF protection or making PUT or DELETE requests.

      Thank you sir, your insight is much appreciated :)

      • Eric

        management forms in Symfony2 zendframework 2 and go in the same direction. In ZF2 they completely remade the class form to make it more customizable, idem in Symfony2 knowing already in Symfony1 form creation was quite early.

        An example that could be done under Laravel or FuelPHP, Sub FuelPHP I posted a comment just to extenaliser management rules already, as a form with many fields, I do not see a great add add_rules amount in my controller. So I create a class that reads in a “Rules” folder where I just returned a table of rules depending on the type of field, which greatly reduces my controllers. But I have to redo there to advices Harron Verton to better integrate it into the framework.

        Indeed, as you say, for beginners it might complicate the matter, but not made​​, as in Symfony2 nothing prevented you manage your forms as you would in Laravel or FuelPHP.

        The advantage is that you can really outsource your types of form fields and your rules to better factoryser your code.

        It has really been a full approach. Eg in Laravel or FuelPHP like many other frameworks, the form is an object, the validation rules are objects too, but the types of fields are not treated as objects. An object can be extended, so nested.

        Regarez in the link I provided you approach Syfmony2, as compared Laravel could have a “Form” folder in the module (pardon package or bundle I do not know lol) or the app controller.
        Form in this case we have a collection of form fields. As well as validation rules that could directly implemented in our field types or outsource these rules to the factoring as appropriate.

        Symfony2 in a class field type does not necessarily contain “One field” form, you can absolutely create several types of fields.
        Form / loginType.php in my login kind I have

        a method add (‘field name’, {type text field or other}, array (‘label’ rules … etc …)
        I will create a field type:
        – login
        – password
        – Stay connected checkbox etc …

        I will now create another type of fields that will be called eg Form / LoginFullType.php
        My class loginFullType will not extend the Form calss but LoginType class and I’m going to add fields.
        – Select country
        – RadioU button sex male or female
        – Uplodat avatar

        And I would call in my view (not to mention the controller) loginFull the form and so on.
        Everything is customizable in Symfony2 This means that nothing prevents me from having a different template form and LoginType loginFullType thing we can not do well in Laravel or FuelPHP regrettably.

        We can do the same with the rules of form fields. Mostly you can often find the same type of fields in several forms, so that logically we should call the same rule of fields for the same type of fields that will be in several forms. Do you see the concept?
        This allows us to create the most complex forms as dynamic addition of groups of fields such as addresses, imagine that you need to create a button (add) to add javascript dynamically a group address field? How would we as Laravel or FuelPHP? It would have to duplicate code so abundant.

        • http://culttt.com/ Philip Brown

          Ah yeah, I see what you mean.

          I don’t think I could ever put in the dedication to make something as robust as a Form package. Is the Symfony 2 one available through Composer?

          It would be amazing if there was just a de facto package in the PHP community that worked perfectly.

          But with there being so many different variations, options and required implementations, do you think that would be even possible?

          • Eric

            Yes I think this is what I thought, because I had seen on the Symfony2 documentation that management form was also a bundle, a service more precisely, just as doctrine or propel the twig template engine, etc. …
            I have not tested yet to see the implementation of the bundle and Form validation inside Laravel 4 regarding FuelPHP I strongly believe that I would have to create an adapter so you can use the bundle form Symfony2 as Laravel draws heavily Symfony2, it is true that SENSIO lab strongly influences the development php in the web world. And although Symfony2 is French, I do not deny that I have to hit me documentation in English to understand the framework lool finally anymore because they were translated into French, but it is a very good initiative that promote doc in English and not in french first, this issue is better communication.
            I would prefer to still see the implementation of a better form management treatment developed by Taylor to see how it would work rather than having to use the Symfony2 bundle, to see something else can be.

            If I have time to develop in Laravel and this has not been done, I think I’d rather crérais a package that would extend the package and Form validation Laravel order to manage its field types and validation so full oop object as in Symfony2 about, hoping to set my class as perfectly as possible, because I have not yet mastered some Concepte poo in php.
            I also noticed that in Laravel, Kohana and FuelPHP managements error messages were less easy to implement than in codeigniter or zend and Symfony2, it’s a shame knowing that Laravel, kohana and FuelPHP the outcome of the philosophy of codeigniter.

            For example frontend side, if you want to manage retoure error messages, it is necessary to place a former condition (if isset ($ errors ['input my name']) $ errors ['input my name']: null , While in codeigniter and other frameworks just had to add form_errors (‘email’); much simpler to implement unless I have not yet seen how.

          • http://culttt.com/ Philip Brown

            Yeah, I would love to see an amazing Form class available, it would be even better if it wasn’t too coupled with a specific framework.

            PHP is only just getting around to using framework agnostic packages after years of forcing the developer to fully commit to a single framework, so one step at a time! :P haha

            I think a lot can be taken from other frameworks and languages, so hopefully something does come a long. Like I said above, I can imagine it being pretty difficult to really make a robust Form package that would fit into any framework or that can be used in vanilla PHP. Kudos to anyone who manages to do it :)

          • Eric

            yes indeed, SensioLabs creators symfony on this plan is done things by giving convetions architecture and development in some standard isp-0 and co and their own convention, which standardizes a little all developments for a framework. I think it’s actually great as you say, before we were forced to learn, develop or use a module for such framework, but now I think the trend will be to factor all its dev according to this convention has sensiolab the direction shown. Laravel have the same philosophy, so that a package (if it is standalone) can be easily adapted to another framework.
            Alas, I’m not sure FuelPHP follow the same direction (I’m not sure) why phile sturgeon left the team FuelPHP probably. We will see later

          • http://culttt.com/ Philip Brown

            Yeah exactly. The quicker PHP can get to the same position as Ruby Gems the better in my opinion!

  • http://dailyloonie.com/ Mat

    Hey Phil

    Really appreciate the tutorials. One more suggestion for the comment box (as always, no biggie) – distinguishing the form button vs. form submit:

    {{ Form::button(‘Find out more’, array(‘type’ => ‘submit’)) }}

    Think you meant to do that and just overlooked it, but if not please disregard =)

    • http://culttt.com/ Philip Brown

      Good catch Mat :) thank you!

  • Richard

    What does the from look like?
    {{ Form::label(‘email’, ‘E-Mail Address’) }}
    Where does the Email address end up on the form?
    Is this code in an HTML Page?
    Please clarify?

    • http://culttt.com/ Philip Brown

      What does the HTML look like? Well it depends on what tags you use.

      The elements of the form follow the order that you write them.

      Yes, you would write this in your View template.

      Try experimenting with how these work in one of your Views. I’m sure you will find the answers to all of your questions.

  • Diaz N

    Hi Philip Brown , how I can check the checked property of a checkbox, I try

    checkbox =>{{Form::checkbox(‘same_as_billing’, false)}}



    But doesn’t work

    • http://culttt.com/ Philip Brown

      Hmm, it depends on what the context is. Is the same_as_billing bit already completed by the user on a different page? Or do you want it to happen dynamically once the user has selected it whilst on the same page? You will want to be using Javascript if you are trying to build the second option.

  • Erik

    The question I’ve recently run into is this:

    submit form -> route w/ parameters using form values as route parameter values.

    @philip_brown:disqus do you have a trick up your sleeve to make this possible? or must I use a middle-ground route and redirect?




    none.com/one/two/three (passing in additional parameters in query string as needed).

    • http://culttt.com/ Philip Brown

      Hmm, I’m not sure what you are trying to achieve to be honest. If you could give me an example that would help.

      You can just submit a form using GET as the method if you want to use query params. (I might be misunderstanding what you mean?)

  • Nicolas LA

    How do you deal with creating inputs of related models in a form? I found this solution: http://stackoverflow.com/questions/20684932/nesting-models-relations-in-forms-laravel but I didn’t find any other idea on that topic, what’s your opinion?

    • http://culttt.com/ Philip Brown

      You can use bracket notation to select related items.

      For example:
      {{ Form::text('user[last_name]', null) }}

      This would select $customer->user->last_name

      • Nicolas LA

        Ok that’s what I thought, thanks for your answer and your so useful posts!

        • http://culttt.com/ Philip Brown

          No problem Nicolas :)

  • Surge

    How does one deal with setting the default value of a dropdown to the selected value?

  • richoid

    Using the “Form::model($user, array(..” pattern… I’m getting “Undefined variable” error. In my case it is $profile, not $user… and there is definitely a app/models/Profile.php. The mysql table used is called ‘profiles’, though, is that a problem?

    here’s the actual form open:

    {{ Form::model($profile, ['method' => 'post', 'route' => 'reportStore']) }}

    Also, the controller that made the view has a constructor for $profile.

    Any ideas?

    • http://culttt.com/ Philip Brown

      You need to pass an instance of $profile to the view.

      • richoid

        thanks for your time…

        I’ve got $user_profile = Profile::where(‘user_id’, $user->id)->first();


        return View::make(‘reports.reports_b’, compact($user_profile));

        in the controller… but is there a way to do it generically, in case there’s no matching profile?

        FULL CODE of the ProfilesController reportProfileCreate :

        public function reportProfileCreate()


        //NOTE: this provides continuity from the first report form, before presenting the second

        //we set the first form into the session to keep the relationships alive

        $report_id = Session::get(‘report_id’);

        $report_input = Session::get(‘report_input’);

        //this matches the user by their email (if registered)

        $user = DB::table(‘users’)->where(‘email’, $report_input['report_email'])->first();

        if(isset($user)){ // if there is a match, pull in the profile to pass it to the view

        $user_profile = Profile::where(‘user_id’, $user->id)->first();

        Session::put(‘user_profile’, $user_profile);

        } else {

        $user_profile = null;


        return View::make(‘reports.reports_b’, compact($user_profile));


        • richoid

          Oh, hey… would this work (in the above):

          View::composer(‘reports_b’, function($view)
          { $view->with(‘profileModel’, Profile::where(‘report_id’, $id)); });

          I’d never seen view composers before.

          • richoid


          • http://culttt.com/ Philip Brown

            You would only use Form::model if you were editing an existing entity. If you are creating a new entity use Form::open

          • richoid

            Ooooh… so this would be an ‘edit’ form, but not a ‘create’ form, and the model would bind only then. Makes sense. Yay.


          • http://culttt.com/ Philip Brown

            Yeah, that’s spot on! :)

          • dreamingInCode

            I usually extract the form part out to a partial so I can use it in both the create.blade and the edit.blade and I model bind them both. I pass in a empty object for the create and bind to that. That way if I redirect back with errors I don’t have to mess with any of that, the old data is still there

          • http://culttt.com/ Philip Brown

            Yeah that’s how it works in Rails. I actually prefer using a partial. Thank you for the suggestion :)

  • Zocios

    What if you want to include a variable value in the label name? So, in your example, instead of the second label parameter being ‘E-Mail Address’, it were ‘$email’? There seems to be no way to do this without getting an error. Enclosing the parameter in another set of curly braces doesn’t work. Thanks.

    • http://culttt.com/ Philip Brown

      What error are you getting? It should work correctly.

      • Zocios

        Thanks much for the prompt reply! I kept at it, and figured out the solution — simply use double quotes inside the braces around the variable value, including if (as in my case) the variable is actually an array value, to match the variable name in the associated text input. For example, this works perfectly: {{ Form::label(“dt[$dues_type_id]“, $dues_type->name) }}

        • http://culttt.com/ Philip Brown

          Ah cool, glad you got it sorted! :)

  • Wall05

    When I try to bind the form to the controller, it states that user is an undefined variable. Why?

    • http://culttt.com/ Philip Brown

      I guess user must be undefined. Have you got a code sample?

      • Wall05

        I needed to pass ->with(‘user’, $this->user->find(1)) from the controller.

        • http://culttt.com/ Philip Brown

          Ah right, yeah you need to pass an instance of the object. I wouldn’t do the query inside of the route redirect though.

  • Roelof

    If I want to bind a model can I better use form:open then form:model on creating ???
    also when I want to edit it ?

    • http://culttt.com/ Philip Brown

      You use open when you create, and bind when you edit. When you are first creating a new item, there is nothing to bind.

  • Deanna Riddlespur

    For some reason when I try to update it is not saving the information that is entered

    • http://culttt.com/ Philip Brown

      Hmm, well that could any number of reasons. Is your code on Github?

      • Deanna Riddlespur
        • http://culttt.com/ Philip Brown

          Do you have a specific example of where it isn’t working?

          • Deanna Riddlespur

            When i go to edit the site it will bring up the edit form but when you hit submit it brings up a blank page and does not save the data into the database. I have this working in simple php but cannot get it converted for my project

            Thank you

          • http://culttt.com/ Philip Brown

            It’s because this if statement isn’t being satisfied https://github.com/webdevdea/DynamiX4/blob/master/app/controllers/PagesController.php#L185

            By the way, you shouldn’t be running MySQL statements in your controller like that as you are vulnerable to SQL injection.

          • Deanna Riddlespur

            Thanks, I will be working on that project later today. Question… Where should the sql statements be? I am new to laravel, just about to graduate from school, very very jr developer over here . Please and thank you

          • http://culttt.com/ Philip Brown

            You should use Laravel’s Eloquent ORM instead http://laravel.com/docs/4.2/eloquent

            It’s much easier than using SQL statements :)

          • Deanna Riddlespur

            Yes but since I am learning, my partner and I will change that once we get this fully functional. It will be an application used inside the company and outsiders should not be allowed to access it. Thank you for your help

          • Deanna Riddlespur

            How to satisfy it?

          • http://culttt.com/ Philip Brown

            You need to make a GET request with that parameter set.

Supported by