Laravel Form Class

Laravel Form Class

Getting the beginnings of our RESTful application up and running was a big accomplishment for us! At this point, we’d like to jump into Laravel Forms and learn how Laravel handles form operations so that we can easily create or delete a blog post from our web interface, rather than populating our database via the mysql console, phpMyAdmin, or some other means. Let’s get our form on!

Our First Laravel Form

In the Blogposts Controller, the create() method would be used to display a form to the user so they could enter some information to create a new blogpost. Let’s go ahead and set up that method now:

public function create()
	return View::make('blogposts.create');

This instructs our application to fetch the create view from the blogposts folder and render a view. If we want this to work, we’re going to need to create a view! Navigating to our app/views/blogposts folder, we can now create the view that will display the form. Following convention, this file will be named create.blade.php and will look something like this:



Create a New Blog Post

{{ Form::open( [ 'route' => '' ] ) }}
{{ Form::label('title', 'Title: ') }} {{ Form::text('title', '', array('class' => 'form-control')) }}
{{ Form::label('body', 'Body: ') }} {{ Form::textarea('body', '', array('class' => 'form-control')) }}
{{ Form::submit('Create Post', array('class' => 'btn btn-info')) }}
{{ Form::close() }} @stop

Alright! Let’s take a look at what we’ve got here. First, we can see this view @extends from layouts.default just like our other view files. In the @section(‘content’) we find our first inkling of a form. We use the Form::open method to open the form. By default, the Form::open method will POST to the current URI, but in keeping with our RESTful development style so far, we are going to want to POST to the blogposts collection. By passing in the array of [ 'route' => '' ] we can ensure the action is correct. The resulting HTML on our page will look something like this as a result of this coding convention:

<form method="POST" action="http://you.rock/blogposts" accept-charset="UTF-8"><input name="_token" type="hidden" value="ucAk7v1Y9BEhUXF68bONk3bOwW2gnTo7mPVOqdsZ">

We can see the method is POST, the action is http://you.rock/blogposts, and an added freebie is the automatic creation of a hidden input token to aid in security. As a refresher, it may help to run php artisan routes to remind us of the relationship between URI, Name, and Action. Here we are referencing the named route which should POST to /blogposts (it does) and use the store() method of the BlogpostsController (it will)!

| Domain | URI                            | Name              | Action                      | BeforeFilters | After Filters |
|        | GET blogposts                  | blogposts.index   | BlogpostsController@index   |                |               |
|        | GET blogposts/create           | blogposts.create  | BlogpostsController@create  |                |               |
|        | POST blogposts                 |   | BlogpostsController@store   |                |               |
|        | GET blogposts/{blogposts}      |    | BlogpostsController@show    |                |               |
|        | GET blogposts/{blogposts}/edit | blogposts.edit    | BlogpostsController@edit    |                |               |
|        | PUT blogposts/{blogposts}      | blogposts.update  | BlogpostsController@update  |                |               |
|        | PATCH blogposts/{blogposts}    |                   | BlogpostsController@update  |                |               |
|        | DELETE blogposts/{blogposts}   | blogposts.destroy | BlogpostsController@destroy |                |               |

Let’s see what the remaining Laravel helper methods are buying us in terms of HTML output to the browser:

<form method="POST" action="http://you.rock/blogposts" accept-charset="UTF-8"><input name="_token" type="hidden" value="JUhDwq5ey407X1FyiONL9qWZvJx0pRq61SJa5DMV"><div> <label for="title">Title: </label>  <input class="form-control" name="title" type="text" value="" id="title"> 

  <label for="body">Body: </label>  <textarea class="form-control" name="body" cols="50" rows="10" id="body"></textarea> 
  <input class="btn btn-info" type="submit" value="Create Post"> 


Basic Styling With Bootstrap

You’ll also notice from the code above that you can assign a class to form elements by passing in an array to the third parameter if the element has a name and id field like so {{ Form::textarea('body', '', array('class' => 'form-control')) }} , or the second parameter if it does not like so {{ Form::submit('Create Post', array('class' => 'btn btn-info')) }}

Excellent! We now have a form that can accept input from a user, let’s check it out shall we?! We can visit http://you.rock/blogposts/create to see it 🙂

laravel form class

Hey! That’s looks pretty good, you clean up nice 🙂

Handle The Form Submission

Now that we have a good looking form, and we can see we are able to happily enter text into it in order to craft our next blog masterpiece, we’re going to need our controller to handle the data that actually gets sent in via the form. We’ll do this with the store() method. We know this because if we check our routes we see the line POST blogposts | | BlogpostsController@store for the URI, Name, and Action respectively. By specifying {{ Form::open( [ 'route' => '' ] ) }} in our create.blade.php file, we have set up the correct routing.

Update the store() Method in the BlogpostsController

Let’s first see how Laravel handles the capturing of the data that get’s entered into the form. We can add the simple snippet here to see this:

public function store()
    return Input::all();

Now let’s be brave and type some random text into our form fields and hit the submit button to see what happens:


    "_token": "JUhDwq5ey407X1FyiONL9qWZvJx0pRq61SJa5DMV",
    "title": "Twitter Bootstrap is Fun to Use",
    "body": "Try out the new and improved Twitter Bootstrap.  It freshens breath and makes your website awesome"


Well Jumping Jackhammers, would you take a look at that? We can see that it is easy to test our forms first before anything actually hits the database. Now we can update the store() method further. Check it out:

public function store()
	$blogpost = new Blogpost;
	$blogpost->title = Input::get('title');
	$blogpost->body = Input::get('body');
	//  create a slug out of the Title
	$slug = strtolower($blogpost->title);
	$slug = str_replace(' ', '-', $slug);
	$blogpost->slug = $slug;

	return Redirect::route('blogposts.index');

Lets run through what’s happening here.

  • Create a new instance of a Blogpost Model
  • Assign the Title text to the $blogpost->title property
  • Assign the Body text to the $blogpost->body property
  • Use native PHP to create a slug out of the Title text
  • Assign the slug to the $blogpost->slug property
  • Save the Blogpost Model to the database
  • Redirect the user to the index page

Looks reasonable to me, should we hit the Create Post button? I think we should, here we go:

laravel new blog post

Well check it out friends. What is that I see as the last entry on our index page? Yes, it is in fact The History of Twitter Bootstrap. Our store() method worked as intended!

Delete A Blogpost via Destroy

We’re now able to create blogposts with our small Laravel application, what fun we are having! It might be nice to also have the ability to delete a blogpost. How can we do that? Referring again to our RESTful style of development, we’ll need to send a DELETE request to /blogposts/{blogposts} as shown in our routes DELETE blogposts/{blogposts} | blogposts.destroy | BlogpostsController@destroy.

Let’s craft up a button in our show.blade.php view so that when we view posts individually, there will also be an option to delete the post on that page.


	{{ $blogpost->title }} 


{{ $blogpost->title }}

{{ $blogpost->body }}

@foreach( $blogpost->tags as $tag ) {{ $tag->name }} @endforeach {{ Form::open(array('route' => array('blogposts.destroy', $blogpost->slug), 'method' => 'delete')) }} {{ Form::close() }} @stop

We’ve seen this view before but let’s have a look at the new code that is creating a button to allow us to delete a blogpost. First we’ll need to use a form and specify the method in order for us to send a DELETE request to blogposts.destroy. Notice we are also using the slug as the wildcard by specifying it as the second parameter in Form::open(array('route' => array('blogposts.destroy', $blogpost->slug), 'method' => 'delete')).

Next we have to be sure the action is routing to the correct URI. We can do this by specifying the named route like so {{ URL::route('blogposts.destroy', $blogpost->slug) }}.

Last up, we’ll simply close the form via Form::close().

Let’s drill down on our newly created post by visiting http://you.rock/blogposts/the-history-of-twitter-bootstrap to see our new delete button!

laravel delete button

Cool! Don’t click that delete button just yet!

Update The destroy() method

The delete button is now in place, and we have specified via the named route blogposts.destroy, to hit the destroy() method in the Blogposts Controller. Here is the code to make it actually do something. In this case, delete:

public function destroy($id)
   $column = 'slug'; // This is the name of the column you wish to search
   $blogpost = Blogpost::where($column , '=', $id)->first(); //  find the name to id association
   return Redirect::route('blogposts.index');		 

What should happen here? Let’s go through it.

  • Assign ‘slug’ to the variable $column
  • Use the Blogpost Model to find the post by slug and assign it to $blogpost
  • Delete that blogpost by calling $blogpost->delete()
  • Redirect the user to the index page

Let’s test it out now, go ahead and hit that delete button!
laravel blog delete

Success! We can see upon clicking the delete button, we are directed back to the index page, and if you notice in the list of posts, The History of Twitter Bootstrap is no longer there! Soon, we can add Laravel Validation to our small app as well!