Tự học Laravel: (16) CREATE FORM

This time, I will create a form and register the article in the database.

ADD LARAVELCOLLECTIVE / HTML PACKAGE

There are two ways to write a Form in Laravel’s View directly: write HTML and use helper functions. In this article, we will try to use the helper functions by installing the laravelcollective/html package , as we want to experience installing the package .

This package was included in Laravel 4 as a standard, but is separate from Laravel 5 and is maintained by the user community. 
http://laravelcollective.com/

INSTALL WITH COMPOSER

Install the package with the composer command.

composer require "laravelcollective/html":"^5.4.0"

The composer package is installed under vendor.

vendor
└── laravelcollective
    └── html

INCORPORATE PACKAGES INTO LARAVEL (ONLY IN VER 5.4 AND BELOW)

Edit config/app.php to incorporate laravelcollective/html into Laravel.
Note that editing this app.php is no longer necessary from Laravel version 5.5 or later. Laravel will automatically find your service provider and facade.

<?php //config/app.php
 
return [
    'providers' => [
 
        // ...
 
        Collective\Html\HtmlServiceProvider::class, 
    ],
    'aliases' => [
 
        // ...
 
        'Form' => Collective\Html\FormFacade::class,  
        'Html' => Collective\Html\HtmlFacade::class, 
    ],
];

The settings and mechanisms in this area are called service providers or facades in Laravel, but I will not explain them in detail here. I just want to keep in mind that I need to add the above configuration to config/app.php to add packages to Laravel. If you are worried about it, please try it.

Laravel itself also adds features using service providers and facades. You can check what is included by default in connfig / app.php, so take a look.

DISPLAY NEW ARTICLE INPUT FORM

ROUTING

Add a route

<?php
// routes/web.php
 
// ...
Route::get('articles', 'ArticlesController@index');
 
Route::get('articles/create', 'ArticlesController@create'); // ①
 
Route::get('articles/{id}', 'ArticlesController@show'); // (a)
// ...

A route to ArticlesController@create has been added.
As a point of caution, the above 1 will be added before (a). Otherwise, when a GET request for “articles/create” comes, “articles/{id}” will match first and ArticlesController@show will be executed. The routes are matched from the top in the order of description.

CONTROLLER

Implement the create method in ArticlesController.php. 
The contents only show the view.

<?php
namespace AppHttpControllers;
//app/Http/Controllers/ArticlesController.php
 
// ...
 
class ArticlesController extends Controller
{
 
    // ... 
    public function create()
    {
        return view('articles.create');
    }
}

VIEW

Create create.blade.php newly.

//resources/views/articles/create.blade.php
 
@extends('layout')
 
@section('content')
    <h1>Write a New Article</h1>
    <hr/>
 
    {!! Form::open() !!}
        <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', date('Y-m-d'), ['class' => 'form-control']) !!}
        </div>    
        <div class="form-group">
            {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!}
        </div>
    {!! Form::close() !!}
@endsection

A new notation has come out.

The first is the notation {!! XXXX !!}. This is a notation of a blade template, and is used when displaying the result evaluated by PHP. We used {{XXXX}} in the same notation before, but the difference is that {!! XXXX !!} is not escaped and {{XXXX}} is escaped. There is. Since HTML of Form is generated by PHP this time, {!! XXXX !!} is used so that escape processing is not performed.

The second is the notation Form::XXXX. I am using the laravelcollective/html package I installed at the beginning of this part. At first glance it looks like you are calling the static method of the Form class, but you are actually Collective\Html\FormBuildercalling an instance method of the class. Here Collective\Html\FormBuilderI think that it is good to understand that you are accessing the instance of simple using alias (alias) called Form class . This mechanism is called a facade. Details of the facade will be omitted here.

Here we use the following methods of the Form facade:

  • Form::open() Generate start tag of form
  • Form::close() Generate form closing tag
  • Form::label() Generate label tag
  • Form::input() generate input tag
  • Form::text() generate input [type = text] tag
  • Form::textarea() Generate textarea tag
  • Form::submit() generate input [type = submit] tag

The details can be confirmed by the following API reference. 
https://laravelcollective.com/docs/master/html

Then, the specification of class=”xxxx” specifies the class of Bootstrap that was introduced last time . This will make the form look cool.

Now let’s check the HTML of the generated Form. Go to 
http://localhost:8000/articles/create and view the page source in the browser function.

<form method="POST" action="http://localhost:8000/articles" accept-charset="UTF-8">
    <input name="_token" type="hidden" value="D1zCIbRcEzYrqracQtyPbDFuKcGHLHcm2aNddRig">
    <div class="form-group">
        <label for="title">Title:</label>
        <input class="form-control" name="title" type="text" id="title">
    </div>
    <div class="form-group">
        <label for="body">Body:</label>
        <textarea class="form-control" name="body" cols="50" rows="10" id="body"></textarea>
    </div>
    <div class="form-group">
        <label for="published_at">Publish On:</label>
        <input class="form-control" name="published_at" type="date" value="2018-08-27" id="published_at">
    </div>    
    <div class="form-group">
        <input class="btn btn-primary form-control" type="submit" value="Add Article">
    </div>
</form>

POST has been set for method. 
The current URL (/articles/create) is set to action. This will be changed later.
<input name=”_ token” type=”hidden” value=”…”> was automatically inserted. This is to be inserted token automatically for CSRF measures.

laravelcollective/htmlIf you want to write form tags manually without using a package, you need to insert a CSRF token yourself. In that case, use the Blade template’s @csrfdirective.

<form method="POST" action="/profile">
    @csrf
    ...
</form>

Please refer to here for CSRF measures. https://laravel.com/docs/master/csrf

SAVE NEW ARTICLE

Implements the process of saving to DB when Form is submitted.

ROUTING

Add a route

<?php
// app/Http/routes.php
 
// ...
Route::get('articles', 'ArticlesController@index');
Route::get('articles/create', 'ArticlesController@create');
Route::get('articles/{id}', 'ArticlesController@show');
// 
Route::post('articles', 'ArticlesController@store');
 
// ...

A route to ArticlesController@store has been added.
I’m adding post instead of get.

Up until now, Route::XXX was used as it is said, but in fact this is also a facade. The reality is Illuminate\Routing\Router. As it is a built-in facade of Laravel, it is originally defined in config/app.php.

CONTROLLER

Implement the store method in ArticlesController.php.

<?php
namespace AppHttpControllers;
 
use App\Article;
use App\Http\ControllersController;
 
class ArticlesController extends Controller {
 
    // ...
 
    public function create() {
        return view('articles.create');
    }
 
    public function store() {
        // ① 
        $inputs = \Request::all();
 
        // ② 
        dd($inputs);
    }
}

\Request::all()I get all the form input value in 

  1. This Request class is also a facade, the reality is Illuminate\Http\Request
  2. In order to use the facade class in the controller’s namespace, you need to specify it as a global class, so \be sure to put a (backslash) in front of the class name . 
  3. Please refer to the official site document for details of Request.
  4. This part only checks the values ​​entered in the form. dd() is a handy function for debugging that displays the value received as an argument on the screen.

VIEW

Modify the create.blade.php created earlier.

// resources/views/articles/create.blade.php
 
// ...
 
{!! Form::open(['url' => 'articles']) !!}
 
// ...

I passed an argument to Form::open() and specified url.

Let’s check the generated HTML of Form.

<form method="POST" action="http://localhost:8000/articles" accept-charset="UTF-8">
  ...

The url for action has changed. Now, when you press the submit button, ArticlesController @ store will be executed.

CONFIRMATION OF REQUEST CONTENTS

Here, http://localhost:8000/articles/create to access Let’s add the article.

It is successful if it is displayed on the screen as follows.

array:4 [▼
  "_token" => "D1zCIbRcEzYrqracQtyPbDFuKcGHLHcm2aNddRig"
  "title" => "title entered"
  "body" => "The article you entered"
  "published_at" => "2018-08-27"
]

The contents of the request sent from Form was confirmed by display of dd().
This dd() displays the contents of the variable and aborts processing there.

STORE ARTICLES IN DB

Complete the store method of ArticlesController.php.

class ArticlesController extends Controller {
 
    // ...
 
    public function store() {
        $inputs = \Request::all();
 
        // dd($inputs);
 
        // ①
        Article::create($inputs);
 
        // ②
        return redirect('articles');
    }
}
  1. I have created data in the Articles table using the mass assignment function I did earlier. Remember to set fillable variables in the Article model.
  2. The previous controller methods used the view() method to display the view, but here we use redirect() to redirect to the article list URL.

ACTION CONFIRMATION

Once again, http://Localhost:8000/articles/create to access Let’s add the article. 
It is successful if it is redirected to the list screen after article registration and the title of the registered article is displayed.

NEW BUTTON FOR ARTICLE LIST

Finally, let’s display a new article creation button in the article list.

//resources/views/articles/index.blade.php
 
@extends('layout')
 
@section('content')
    <h1>
        Articles
        <a href="articles/create" class="btn btn-primary float-right">Create New</a>
    </h1> 
    <hr/> 
    @foreach($articles as $article)
        ...
        ...
    @endforeach
@endsection

Add a link tag to ‘articles/create’.
Set the bootstrap class to “btn btn-primary” and display the link tag like a button. 
The button is “right” with “float-right”.

Input check, next time …

SUMMARY

It became possible to do the following things

  • Add laravelcollective/html package
  • Create and display a Form
  • Get form input value with Request::all()
  • How to use the facade
  • Data storage to DB in the flow of View->Controller->Model

Leave a Reply

Your email address will not be published.

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