Docker×Laravel8でもくもく会アプリを作成の編集画面編になります。
前回の記事の続きになりますので、まだの方は以下をご参照ください。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
編集画面を作成するステップ
編集画面を作成するステップは、登録画面を作成するステップとほぼ同じです。また、画面も登録画面もあまり変わりません。
ルーティングを追加する
編集画面用に、ルーティングを追加します。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\EventController;
use App\Http\Controllers\CategoryController;
// もくもく会一覧画面
Route::get('/', [EventController::class, 'index'])
->name('event.index');
// もくもく会詳細画面
Route::get('/event/{id}', [EventController::class, 'show'])
->name('event.show');
// もくもく会登録画面
Route::get('/event/register', [EventController::class, 'register'])
->name('event.register');
// もくもく会登録処理
Route::post('/event/create', [EventController::class, 'create'])
->name('event.create');
// もくもく会編集画面
Route::get('event/edit/{id}', [EventController::class, 'edit'])
->name('event.edit');
// カテゴリー一覧画面
Route::get('/category/index', [CategoryController::class, 'index'])
->name('category.index');
コントローラーにeditアクションを追加する
次にEventControllerにeditアクションを追加していきます。
/**
* 編集画面
*/
public function edit(Request $request, $id)
{
return view('event.edit');
}
editのbladeファイルを作成する
resources/views/event/edit.blade.phpのファイルを作成します。
とりあえず中身は共通のものでいいでしょう。
@extends('layouts.app')
@section('content')
@endsection
これで、/event/edit/1にアクセスした時に、ナビゲーションまで表示されていればOKです。
一覧画面から編集画面に遷移できるようにする
最後に一覧画面から編集画面に遷移できるようにします。
<div class="btn-filed ml-auto">
<a href="{{ route('event.show', ['id' => $event->event_id]) }}" class="btn btn-primary mr-3">{{ '詳細' }}</a>
<a href="{{ route('event.edit', ['id' => $event->event_id]) }}" class="btn btn-info mr-3">{{ '編集' }}</a>
<button class="btn btn-danger mr-3">{{ '削除' }}</button>
</div>
これでもくもく会一覧画面の編集ボタンを押すと、それぞれのもくもく会の編集画面にいきます。
編集画面のレイアウトを完成させる
編集画面は、登録画面とほぼ同じなので、まずは登録画面をコピペしましょう。
@extends('layouts.app')
@section('content')
<div class="container">
<form action="{{ route('event.create') }}" method="POST">
@csrf
{{-- タイトルフォーム --}}
<div class="form-group">
<label for="title">{{ 'タイトル' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}" name="title" id="title" value="{{ old('title') }}">
@if ($errors->has('title'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('title') }}
</span>
@endif
</div>
{{-- カテゴリープルダウン --}}
<div class="form-group w-50">
<label for="category-id">{{ 'カテゴリー' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<select class="form-control{{ $errors->has('category_id') ? ' is-invalid' : '' }}" id="category-id" name="category_id">
@foreach ($categories as $category)
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endforeach
</select>
@if ($errors->has('category_id'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('category_id') }}
</span>
@endif
</div>
{{-- 開催日をカレンダーで選択 --}}
<div class="form-group w-25">
<label for="date">{{ '開催日' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="date" class="form-control{{ $errors->has('date') ? ' is-invalid' : '' }}" name="date" id="date" value="{{ old('date') }}">
@if ($errors->has('date'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('date') }}
</span>
@endif
</div>
{{-- もくもく会開催時間 --}}
<div class="form-group w-50">
<div class="row">
{{-- 開始時間 --}}
<div class="col">
<label for="start_time">{{ '開始時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('start_time') ? ' is-invalid' : '' }}" name="start_time" id="start_time" value="{{ old('start_time') }}">
@if ($errors->has('start_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('start_time') }}
</span>
@endif
</div>
{{-- 終了時間 --}}
<div class="col">
<label for="end_time">{{ '終了時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('end_time') ? ' is-invalid' : '' }}" name="end_time" id="end_time" value="{{ old('end_time') }}">
@if ($errors->has('end_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('end_time') }}
</span>
@endif
</div>
</div>
</div>
{{-- 参加費フォーム --}}
<div class="form-group w-25">
<label for="entry-fee">{{ '参加費' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('entry_fee') ? ' is-invalid' : '' }}" name="entry_fee" id="entry-fee" value="{{ old('entry_fee') }}">
@if ($errors->has('entry_fee'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('entry_fee') }}
</span>
@endif
</div>
{{-- もくもく会の詳細 --}}
<div class="form-group">
<label for="content">{{ '詳細' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<textarea class="form-control{{ $errors->has('content') ? ' is-invalid' : '' }}" name="content" id="content" rows="10" placeholder="もくもく会の詳細を記載してください。">{{ old('content') }}</textarea>
@if ($errors->has('content'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('content') }}
</span>
@endif
</div>
<button type="submit" class="btn btn-success w-100">
{{ 'もくもく会を更新する' }}
</button>
</form>
</div>
@endsection
ただ、このままだとcategoriesがないよ!っていうエラーが出るので、コントローラーでcategoriesを定義してビューに変数を渡します。
/**
* 編集画面
*/
public function edit(Request $request, $id)
{
// カテゴリー一覧を取得
$categories = $this->category->allCategoriesData();
return view('event.edit', compact('categories'));
}
categoriesは、registerアクションのcategoriesと同じ内容になります。
とりあえず、登録画面のように編集画面も用意できました。
編集画面はDBの値を初期表示させておく
編集画面は、登録画面と違って初期表示にはすでにDBに登録されている値をフォームに表示させておきます。
編集画面に行ったときに、フォームの中が空の状態だと、いちいち入力する手間があって大変ですもんね!
コントローラーでIDをもとにもくもく会のデータ1件取得し、ビューに渡す
詳細画面で実装したように、IDをもとにもくもく会のデータを1件取得します。
/**
* 編集画面
*/
public function edit(Request $request, $id)
{
// カテゴリー一覧を取得
$categories = $this->category->allCategoriesData();
// IDをもとに編集画面に表示するもくもく会のデータを1件取得
$event = $this->event->findEventByEventId($id);
return view('event.edit', compact('categories', 'event'));
}
一応、findEventByEventIdのロジックはこんな感じでしたね。
/**
* idをもとにeventsテーブルから特定のレコードに絞り込む
*
* @param int $id イベントID
* @return Event
*/
public function findEventByEventId($id)
{
return $this->find($id);
}
compact関数を使って、変数をビューに渡します。
old(‘name属性’, $event->name属性)と書く
完成形は、DBの値をフォームで初期表示させることです。
これに関しては、以下の記事で詳しく書いているので合わせてチェックして欲しいのですが、
登録画面では、old(‘name属性’)としていたところを、old(‘name属性’, $event->name属性)とすれば、
バリデーションに引っかかった時は、old(‘name属性’)の値が、初期表示の場合は、$event->name属性の値がフォームに表示されます。
タイトルのフォームを以下のように修正してください。
<input type="text" class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}" name="title" id="title" value="{{ old('title', $event->title) }}">
これで、編集画面に遷移した時にタイトルがすでに初期表示されます。
カテゴリーはちょっと厄介なので、この後で解説します。
@extends('layouts.app')
@section('content')
<div class="container">
<form action="{{ route('event.create') }}" method="POST">
@csrf
{{-- タイトルフォーム --}}
<div class="form-group">
<label for="title">{{ 'タイトル' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}" name="title" id="title" value="{{ old('title', $event->title) }}">
@if ($errors->has('title'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('title') }}
</span>
@endif
</div>
{{-- カテゴリープルダウン --}}
<div class="form-group w-50">
<label for="category-id">{{ 'カテゴリー' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<select class="form-control{{ $errors->has('category_id') ? ' is-invalid' : '' }}" id="category-id" name="category_id">
@foreach ($categories as $category)
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endforeach
</select>
@if ($errors->has('category_id'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('category_id') }}
</span>
@endif
</div>
{{-- 開催日をカレンダーで選択 --}}
<div class="form-group w-25">
<label for="date">{{ '開催日' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="date" class="form-control{{ $errors->has('date') ? ' is-invalid' : '' }}" name="date" id="date" value="{{ old('date', $event->date) }}">
@if ($errors->has('date'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('date') }}
</span>
@endif
</div>
{{-- もくもく会開催時間 --}}
<div class="form-group w-50">
<div class="row">
{{-- 開始時間 --}}
<div class="col">
<label for="start_time">{{ '開始時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('start_time') ? ' is-invalid' : '' }}" name="start_time" id="start_time" value="{{ old('start_time', $event->start_time) }}">
@if ($errors->has('start_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('start_time') }}
</span>
@endif
</div>
{{-- 終了時間 --}}
<div class="col">
<label for="end_time">{{ '終了時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('end_time') ? ' is-invalid' : '' }}" name="end_time" id="end_time" value="{{ old('end_time', $event->end_time) }}">
@if ($errors->has('end_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('end_time') }}
</span>
@endif
</div>
</div>
</div>
{{-- 参加費フォーム --}}
<div class="form-group w-25">
<label for="entry-fee">{{ '参加費' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('entry_fee') ? ' is-invalid' : '' }}" name="entry_fee" id="entry-fee" value="{{ old('entry_fee', $event->entry_fee) }}">
@if ($errors->has('entry_fee'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('entry_fee') }}
</span>
@endif
</div>
{{-- もくもく会の詳細 --}}
<div class="form-group">
<label for="content">{{ '詳細' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<textarea class="form-control{{ $errors->has('content') ? ' is-invalid' : '' }}" name="content" id="content" rows="10" placeholder="もくもく会の詳細を記載してください。">{{ old('content', $event->content) }}</textarea>
@if ($errors->has('content'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('content') }}
</span>
@endif
</div>
<button type="submit" class="btn btn-success w-100">
{{ 'もくもく会を更新する' }}
</button>
</form>
</div>
@endsection
カテゴリー以外が初期表示でDBの値になっていると思います。
編集画面でカテゴリー(プルダウン)を表示させる場合は…?
編集画面のプルダウンでDBの値を初期表示させるのは、以下の記事で解説していますが、
初期表示はDBの値、バリデーションに引っかかったら、oldの値を表示と方針は同じです。
<select class="form-control{{ $errors->has('category_id') ? ' is-invalid' : '' }}" id="category-id" name="category_id">
@foreach ($categories as $category)
@if (!is_null(old('category_id')))
{{-- バリデーション時の挙動 --}}
@if (old('category_id') == $category->category_id)
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
@else
{{-- 初期表示 --}}
@if ($event->category_id == $category->category_id))
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
@endif
@endforeach
</select>
コードの解説をすると、
@if (!is_null(old('category_id'))
@else
@endif
old(‘category_id’)がnullではない時、つまり、バリデーションに引っかかった時は、if〜elseが読まれ、old(‘category_id’)がnullの時に、つまり直前に値を操作した場合や初期表示の時は、else〜endifが実行されます。
// oldの値とプルダウンのカテゴリーIDが一致するか判定
// 一致していたら、そのカテゴリーIDをselect状態にする。
@if (old('category_id') == $category->category_id)
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
{{-- 初期表示 --}}
// もくもく会のカテゴリーIDとプルダウンのカテゴリーIDが一致するか判定
// 一致するカテゴリーIDをselect状態にする
@if ($event->category_id == $category->category_id))
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
やってることはこんな感じでした。
これで編集画面は終わりです。
最後に編集画面の全体像になります。
@extends('layouts.app')
@section('content')
<div class="container">
<form action="{{ route('event.create') }}" method="POST">
@csrf
{{-- タイトルフォーム --}}
<div class="form-group">
<label for="title">{{ 'タイトル' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}" name="title" id="title" value="{{ old('title', $event->title) }}">
@if ($errors->has('title'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('title') }}
</span>
@endif
</div>
{{-- カテゴリープルダウン --}}
<div class="form-group w-50">
<label for="category-id">{{ 'カテゴリー' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<select class="form-control{{ $errors->has('category_id') ? ' is-invalid' : '' }}" id="category-id" name="category_id">
@foreach ($categories as $category)
@if (!is_null(old('category_id')))
{{-- バリデーション時の挙動 --}}
@if (old('category_id') == $category->category_id)
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
@else
{{-- 初期表示 --}}
@if ($event->category_id == $category->category_id))
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
@endif
@endforeach
</select>
@if ($errors->has('category_id'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('category_id') }}
</span>
@endif
</div>
{{-- 開催日をカレンダーで選択 --}}
<div class="form-group w-25">
<label for="date">{{ '開催日' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="date" class="form-control{{ $errors->has('date') ? ' is-invalid' : '' }}" name="date" id="date" value="{{ old('date', $event->date) }}">
@if ($errors->has('date'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('date') }}
</span>
@endif
</div>
{{-- もくもく会開催時間 --}}
<div class="form-group w-50">
<div class="row">
{{-- 開始時間 --}}
<div class="col">
<label for="start_time">{{ '開始時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('start_time') ? ' is-invalid' : '' }}" name="start_time" id="start_time" value="{{ old('start_time', $event->start_time) }}">
@if ($errors->has('start_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('start_time') }}
</span>
@endif
</div>
{{-- 終了時間 --}}
<div class="col">
<label for="end_time">{{ '終了時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('end_time') ? ' is-invalid' : '' }}" name="end_time" id="end_time" value="{{ old('end_time', $event->end_time) }}">
@if ($errors->has('end_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('end_time') }}
</span>
@endif
</div>
</div>
</div>
{{-- 参加費フォーム --}}
<div class="form-group w-25">
<label for="entry-fee">{{ '参加費' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('entry_fee') ? ' is-invalid' : '' }}" name="entry_fee" id="entry-fee" value="{{ old('entry_fee', $event->entry_fee) }}">
@if ($errors->has('entry_fee'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('entry_fee') }}
</span>
@endif
</div>
{{-- もくもく会の詳細 --}}
<div class="form-group">
<label for="content">{{ '詳細' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<textarea class="form-control{{ $errors->has('content') ? ' is-invalid' : '' }}" name="content" id="content" rows="10" placeholder="もくもく会の詳細を記載してください。">{{ old('content', $event->content) }}</textarea>
@if ($errors->has('content'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('content') }}
</span>
@endif
</div>
<button type="submit" class="btn btn-success w-100">
{{ 'もくもく会を更新する' }}
</button>
</form>
</div>
@endsection
次回は、更新処理について解説していきます。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント