Laravel 編集フォームを作る

Laravel

この記事のゴール

  • Laravel でDBに登録したデータの編集フォームを作る

前提条件

  • 一覧表示、新規登録フォームは作ってある。

 ※まだの場合は、前回の記事を参考にしてください。

これからやる作業

  • コントローラー編集
  • ルーティング
  • Bladeテンプレート作成、編集
  • ブラウザで確認

コントローラー編集

[app/Http/Controllers/TodoController.php] を編集して保存します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Todo;

class TodoController extends Controller
{
    public function index()
    {
        return view('todo.index', [
            'pageTitle' => 'TODOリスト',
            'todos' => Todo::all(),
        ]);
    }

    public function retrieve($id)
    {
        return view('todo.detail', [
            'pageTitle' => 'TODO詳細',
            'todo' => Todo::find($id),
        ]);
    }

    public function create()
    {
        return view('todo.create', [
            'pageTitle' => 'TODO新規登録',
        ]);
    }

    public function store(Request $request)
    {
        $this->validate($request, Todo::$rules);
        $todo = new Todo();
        $todo->fill($request->except('_token'))->save();
        return redirect(route('todo.index'));
    }

    public function edit($id)
    {
        return view('todo.edit', [
            'pageTitle' => 'TODO編集',
            'todo' => Todo::find($id),
        ]);
    }

    public function update(Request $request, $id)
    {
        $this->validate($request, Todo::$rules);
        $todo = Todo::findOrFail($id);
        $todo->fill($request->except('_token', '_method'))->save();
        return redirect(route('todo.detail', ['id' => $id]));
    }
}

41行目から55行目までを追記しています。

edit() は編集フォーム表示用、update() はバリデーションとDB登録用です。

ルーティング

[routes/web.php] を開いて次の2行を追記して保存します。

    Route::get('/edit/{id}', [TodoController::class, 'edit'])->whereNumber('id')->name('edit');
    Route::patch('/update/{id}', [TodoController::class, 'update'])->whereNumber('id')->name('update');

編集フォームの edit() はGETメソッドですが、

フォームデータを受け取る update() はPATCHメソッドです。

どちらもID指定です。

Bladeテンプレート作成、編集

編集フォームのBladeテンプレートを作ります。

フォルダ [resouces/views/todo/] 内に新規ファイル [edit.blade.php] を作成して、

次のように編集して保存してください。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{$pageTitle}}</title>
        <style>
            .error-input {
                background-color: #ffee33;
            }
            .error {
                background-color: #ffcccc;
                color: #ff0000;
            }
        </style>
    </head>
    <body>
        <h1>{{$pageTitle}}</h1>
        <a href="{{route('todo.detail', ['id' => $todo->id])}}">取消</a><br />
        @if($errors->any())
        <ul>
            @foreach($errors->all() as $error)
            <li class="error">{{$error}}</li>
            @endforeach
        </ul>
        @endif
        <form method="POST" action="{{route('todo.update', ['id' => $todo->id])}}">
            @csrf
            @method('patch')
            <label>やること:</label>
            <input type="text" name="todo" size="40" maxlength="255"
                value="@error('todo') {{old('todo')}} @else {{$todo->todo}} @enderror"
                class="@error('todo') error-input @enderror" /><br />
                状態:
                <input type="radio" name="done" value="0"
                    {{old('done') == 0 ? 'checked' : ($todo->done == 0 ? 'checked' : '')}}
                /><label>未完</label> 
                <input type="radio" name="done" value="1"
                    {{old('done' == 1 ? 'checked' : ($todo->done == 1 ? 'checked' : ''))}}
                /><label>完了</label><br />
            <button type="submit" id="submit">登録</button>
        </form>
    </body>
</html>

TODO詳細画面へ戻る「取消」のリンクを18行目に設置しています。

間違えてクリックしないように「登録」ボタンと離して設置しています。

28行目でLaravelに渡すメソッドを指定しています。

これが無いと、ルーティングで指定したPATCHメソッド扱いされず、

404 not found になります。

項目「done」の部分の処理が面倒ですが、やっていることとしては、

1.バリデーションエラーで戻ってきたら、送信した値を優先。

2.レコードのデータの値が一致したらチェック。

3.それ以外は何もしない。

次に、既存のTODO詳細ページのBladeテンプレートに、編集ページへのリンクを設置します。

[resouces/views/todo/detail.blade.php] を次のように編集して保存してください。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{$pageTitle}}</title>
    </head>
    <body>
        <h1>{{$pageTitle}}</h1>
        @isset($todo)
        <p>
            <a href="{{route('todo.edit', ['id' => $todo->id])}}">[編集]</a><br />
            やること: {{$todo->todo}}<br />
            状態:{{$todo->done ? '完了' : '未完'}}
        </p>
        @else
        <p>情報がありません。</p>
        @endisset
        <a href="{{route('todo.index')}}">todo一覧</a>
    </body>
</html>

11行目に編集画面へのリンクを追記しています。

ブラウザで確認

ブラウザのアドレスバーに http://localhost/todo/1 と入力してアクセスします。

「編集」のリンクをクリックします。

編集画面が表示されたら、内容を変更して「登録」ボタンをクリックします。

バリデーションを通過してDBレコードの更新が完了すると、

TODO詳細画面へリダイレクトします。

修正した内容が反映されています。

一応、一覧画面へも移動して確認してみましょう。

修正した内容が反映されています。

今回はここまでです。次回はレコード削除を予定しています。

お疲れさまでした。

コメント

タイトルとURLをコピーしました