Laravel Forms and Validation

Create 4 views under a new folder called “posts”

create.blade.php
edit.blade.php
index.blade.php
show.blade.php

To our create.blade.php:

@extends('layouts.app')

@section('content')
<h1>Create Post</h1>
<form method="post" action="/posts">
    @csrf <!-- {{ csrf_field() }} -->
    <input type="text" name="title" placeholder="Enter title" />
    <input type="submit" name="submit" />
</form>

@endsection
You need to match the name of the column in posts.. is it named title? If so then the input name is correct. To save this to the posts method you just need to use the action /posts. @csrf is needed to create a token so form will work.

Find the posts routes methods by typing this:

php artisan route:list

You’ll see that the name store deals with the method POST. So find the store method in your posts controller.. this will be the function that will deal with the data when the form is submitted.

Now to see your form find the create (GET) function and add to this function:

    public function create()
    {
        return view('posts.create');
    }

The dot notation gets converted to slash in the browser.. where you can view it at base.com/posts/create.

Now get the store function to show the data submitted from the form:

    public function store(Request $request)
    {
        //return $request->all();
        //return $request->get('title');
        return $request->title;
    }

Update this to save to the database in different ways and redirect to index page like this:

    public function store(Request $request)
    {
        Post::create($request->all());
        return redirect('/posts');
    }
    public function store(Request $request)
    {
        $input = $request->all();
        $input['title'] = 'yo';
        Post::create($input);
        return redirect('/posts');
    }
    public function store(Request $request)
    {
        $post = new Post;
        $post->title = $request->title;
        $post->save();
        return redirect('/posts');
    }

Index controller should now show the index view and pass the post info:

    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

In your index view update to show all the posts information:

@extends('layouts.app')

@section('content')

<ul>
    @foreach($posts as $post)
        <li>{{$post->title}}</li>
    @endforeach
</ul>

@endsection

Now if you submit the form you’ll be redirected to the index view which will show all the posts in the database including the last one added.

To see just one post, let’s add this to our show function in PostController:

    public function show($id)
    {
        $post = Post::findOrFail($id);
        return view('posts.show',compact('post'));
    }

In your show view write this:

@extends('layouts.app')

@section('content')

<h1>{{$post->title}}</h1>

@endsection

Now if you visit url /posts/1, you’ll see the first post. Other numbers will show other posts. It will have to match the id in the database of course.

Update your index view to link to the show view like so:

@extends('layouts.app')

@section('content')

<ul>
    @foreach($posts as $post)
        <li><a href="{{route('posts.show',$post->id)}}">{{$post->title}}</a></li>
    @endforeach
</ul>

@endsection

Now let’s create our Edit controller and view.

The view:

@extends('layouts.app')

@section('content')
<h1>Edit Post</h1>
<form method="post" action="/posts/{{$post->id}}">
    <input type="hidden" name="_method" value="PUT" />
    @csrf <!-- {{ csrf_field() }} -->
    <input type="text" name="title" placeholder="Enter title" value="{{$post->title}}" />
    <input type="submit" name="submit" />
</form>

@endsection
The action needs to send the post ID and a hidden field is needed called PUT which sends it to the update function in the controller.

The controller:

    public function edit($id)
    {
        $post = Post::findOrFail($id);
        return view('posts.edit',compact('post'));
    }

Now edit the update function in the controller:

    public function update(Request $request, $id)
    {
        $post = Post::findOrFail($id);
        $post->update($request->all());
        return redirect('/posts');
    }

Now update the show view to have links to edit form:

@extends('layouts.app')

@section('content')

<h1><a href="{{route('posts.edit',$post->id)}}">{{$post->title}}</a></h1>

@endsection

Lastly we are going to use a form to delete some of this data.

Find the destroy function in PostContoller and add this:

    public function destroy($id)
    {
        $post = Post::whereId($id)->delete();
        return redirect('/posts');
    }

Since everything already links nicely.. just edit you edit view like this:

@extends('layouts.app')

@section('content')
<h1>Edit Post</h1>
<form method="post" action="/posts/{{$post->id}}">
    <input type="hidden" name="_method" value="PUT" />
    @csrf <!-- {{ csrf_field() }} -->
    <input type="text" name="title" placeholder="Enter title" value="{{$post->title}}" />
    <input type="submit" name="submit" value="UPDATE" />
</form>

<form method="post" action="/posts/{{$post->id}}">
    <input type="hidden" name="_method" value="DELETE" />
    @csrf <!-- {{ csrf_field() }} -->
    <input type="submit" name="submit" value="DELETE" />
</form>

@endsection

Notice that your method is now DELETE and we still pass the post ID through the form action tag.

Leave a Reply

Your email address will not be published. Required fields are marked *