Tự học Laravel: (21) VIEW PARTIAL

Last time, I corrected the article list that is displayed after new article registration. This time, I will add an article edit screen. Since the form on the editing screen is almost the same as the form on the new registration screen, we will use the View’s Partial function to turn the form into a common part.

ROUTING

Add a route

// routes/web.php
 
Route::get('articles', 'ArticlesController@index');
Route::get('articles/create', 'ArticlesController@create');
Route::get('articles/{id}', 'ArticlesController@show');
Route::post('articles', 'ArticlesController@store');
Route::get('articles/{id}/edit', 'ArticlesController@edit'); 
Route::patch('articles/{id}', 'ArticlesController@update'); 

Added routes to ArticlesController@edit and ArticlesController@update. If you use update, you will use patch instead of get, so be sure to make a mistake.

CONTROLLER

Add edit and update methods to ArticlesController.

//app/Http/Controllers/ArticlesController.php
 
    public function edit($id) {
        $article = Article::findOrFail($id);
 
        return view('articles.edit', compact('article'));
    }
 
    public function update(ArticleRequest $request, $id) {
        $article = Article::findOrFail($id);
 
        $article->update($request->validated());
 
        return redirect(url('articles', [$article->id]));
    }
}

edit can be learned and created with content, and there is no new element.

For update, $request and $id are received as arguments. $request uses the ArticleRequest class, which inherits from Form Request . By using Form Request, you can automatically check the form input data and redirect to the previous screen when there is an error. In the update method, the article corresponding to $id is acquired, and the article is updated with the input data and redirected to the article display screen.

VIEW

Create edit.blade.php Copy and modify create.blade.php created earlier.

//resources/views/articles/edit.blade.php
 
@extends('layout')
 
@section('content')
    <h1>Edit: {{ $article->title }}</h1>
 
    <hr/>
 
    @if ($errors->any())
        <ul class="alert alert-danger">
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    @endif
 
    {!! Form::model($article, ['method' => 'PATCH', 'url' => ['articles', $article->id]]) !!}
    <div class="form-group">
        {!! Form::label('title', 'Title:') !!}
        {!! Form::text('title', null, ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('body', 'Body:') !!}
        {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('published_at', 'Publish On:') !!}
        {!! Form::input('date', 'published_at', $article->published_at->format('Y-m-d'), ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::submit('Edit Article', ['class' => 'btn btn-primary form-control']) !!}
    </div>
    {!! Form::close() !!}
 
@endsection

The following four points have been modified from create.blade.php.

  • Display article title in page title
  • Changed the creation of Form tag from From::open to Form::model.
    Use Form::model to attach the value of $article to the form.
    Specify PATCH as METHOD, and pass the id of $article as a parameter to url.
  • Change the initial value of the input item of published_at from date (‘Y-m-d’) to the value of $article->published_at. Since $article->published_at specifies a date mutator in the Article class, an instance of the Carbon class is returned when it is referenced. Convert to a string with the format() method and use it as the initial value.
  • Change submit button title to ‘Edit Article’

Here, let’s check the source of the generated form by accessing html://localhost:8000/articles/{id}/edit with a WWW browser.

  • Please replace the {id} part of the URL with the id of the data that exists in the articles table of DB
...
<form method="POST" action="http://localhost:8000/articles/1" accept-charset="UTF-8">
    <input name="_method" type="hidden" value="PATCH">
...

Since the form method in the WWW browser only supports GET and POST, we use hidden to tell Laravel that it is a PATCH method.

Here, since the Form was generated using the Form facade of the laravelcollective / html package, the hidden item specifying the method was automatically inserted. If you want to write form tags manually without using the Form facade, you need to write hidden items yourself. In that case, use @method directive of Blade template. Also use @csrf directive which embeds CSRF token.

<form action="/foo/bar" method="POST">
    @method('PATCH')
    @csrf
    ...
</form>

Please refer to here for the method specification of Form. https://laravel.com/docs/master/routing#form-method-spoofing

VIEW PARTIAL

Up to this point, although the article editing function has been implemented, the same code is duplicated in the new article creation form and the article editing form, and it is made common using View’s Partial function.

PARTIALIZING ERROR DISPLAY

Create form_errors.blade.php

//resources/views/errors/form_errors.blade.php
 
@if ($errors->any())
    <ul class="alert alert-danger">
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

Modify edit.blade.php to use form_errors.blade.php.

//resources/views/articles/edit.blade.php
 
@extends('layout')
 
@section('content')
    <h1>Edit: {!! $article->title !!}</h1>
 
    <hr/>
 
    @include('errors.form_errors')
 
    {!! Form::model($article, ['method' => 'PATCH', 'url' => ['articles', $article->id]]) !!}
 
        ...
        ...
 
    {!! Form::close() !!}
 
@endsection

Use @include to reference form_errors.blade.php. Since form_errors.blade.php was created in the errors directory under resources/views, specify ‘errors.form_errors’.

Like this, the blade template file extracted for @include purpose is called Partial in Laravel.

PARTIALIZATION OF THE FORM PART AND HOW TO PASS VALUES ​​TO PARTIAL

Create form.blade.php

//resources/views/articles/form.blade.php
 
<div class="form-group">
    {!! Form::label('title', 'Title:') !!}
    {!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::label('body', 'Body:') !!}
    {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::label('published_at', 'Publish On:') !!}
    {!! Form::input('date', 'published_at', $published_at, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::submit($submitButton, ['class' => 'btn btn-primary form-control']) !!}
</div>

The initial value of published_at assumes that the $published_at variable is passed. Also, the title of the submit button assumes that the $submitButton variable is passed.

Modify edit.blade.php to use form.blade.php.

//resources/views/articles/edit.blade.php
 
@extends('layout')
 
@section('content')
    <h1>Edit: {!! $article->title !!}</h1>
 
    <hr/>
 
    @include('errors.form_errors')
 
    {!! Form::model($article, ['method' => 'PATCH', 'url' => ['articles', $article->id]]) !!}
        @include('articles.form', ['published_at' => $article->published_at->format('Y-m-d'), 'submitButton' => 'Edit Article'])
    {!! Form::close() !!}
 
@endsection

We refer to form.blade.php using @include. Passing in the published_at and submitButton values.

ADD EDIT BUTTON

Finally, add an edit button on the article display screen.

//resources/views/articles/show.blade.php
 
@extends('layout')
 
@section('content')
    <h1>{{ $article->title }}</h1>
 
    <hr/>
 
    <article>
        <div class="body">{{ $article->body }}</div>
    </article>
 
    <br/>
 
    <div>
        <a href="{{ action('ArticlesController@edit', [$article->id]) }}"
          class="btn btn-primary">
            Update
        </a> 
        <a href="{{ action('ArticlesController@index') }}"
          class="btn btn-secondary float-right">
            List
        </a>
    </div>
@endsection

Added a link to “articles/{id}/edit” in a tag as an edit button.
The tag is designated as Bootstrap class and displayed as a button. 
I use the action()helper function to generate a URL.

Similarly, we added back to the list button.

ACTION CONFIRMATION

Up to here, the editing screen of the article is completed. I will check the operation.

  • Access http://localhost:8000/articles and select an article to view
  • Click the edit button on the article display screen
  • Change the article
  • Confirm that the content of the article has been changed on the display screen

EXERCISE

Please modify create.blade.php as well as edit.blade.php to use partial.

SUMMARY

You can do the following things.

  • Link data to a form using Form::model
  • Partization of views using Partial
  • How to pass values ​​to Partial

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.