前回はTODOモデルを使用して、画面に一覧表示をしました。
今回は表示された一覧のチェックを押されたら、TODOのタスクが終わったということにします。
こちらの箇所を押すと…
こうなるようにします…
そして、チェック状態を保持するようにします。
TODOコントローラーにチェック(check)メソッドを追加する
まず、コントローラーにチェックをされたら保存する処理を作成します。
todosテーブルにcheckカラムを作成しているので、そこにチェック状態を保存します。
app/Http/Controllers/TodoController.php
を開いてください。
下記のように処理を追加します。
class TodoController extends Controller
{
// ----- 他のメソッドは省略 -----
// ---- ここから追加する -----
public function check(Request $request) {
$todo = Todo::find($request->select_todo_id);
if ($todo->check) {
$todo->check = false;
} else {
$todo->check = true;
}
$todo->save();
return redirect()->route('todo.init');
}
// ---- ここまで追加する -----
}
解説
checkメソッドを追加しました。
まず、リクエストで渡されたidからfindを使ってTodoモデルのデータを取得します。(idをビューに仕込んで渡すようにします)
findを使うと、渡した値で主キーを検索して、データを1行取得できます。
取得した後にチェック状態を確認します。
trueの場合はcheckにfalseを入れて、falseの場合はtrueを入れました。
つまり、チェックがついてたら外して、ついてなかったら付けるみたいな感じです。
最後にモデルのsaveメソッドを呼び出して保存しました。
このようにモデルの各プロパティを更新して、saveメソッドを呼ぶことで更新できます。
処理が終わった後は、初期画面にリダイレクトして画面表示しています。
TODOビューを修正する(checkTodo関数の追加など)
ビューを修正していきます。
チェックボタンをクリックしたときに、javascriptのonclickを使用して、作成したcheckメソッドに処理を飛ばします。
onclickは既にチェックボタンのタグに下記のように書いています。
チェックボタンがクリックされたときにcheckTodo関数が呼び出されるようにしています。
そして、TodoモデルのidをcheckTodo関数に渡しています。
今回のビューの修正は、このcheckTodo関数を追加してformタグの箇所を少し変更します。
<button type="button" onclick="checkTodo({{ $todo->id }})" class="cursor-pointer ml-3 mr-3 px-1 py-1 shadow-md rounded-md font-semibold text-white text-base {{ $todo->check ? 'bg-green-500 hover:bg-green-700 ring-green-200' : 'bg-gray-500 hover:bg-gray-700 ring-gray-200' }} ring-2">
<!--- 省略 --->
</button>
それでは、修正していきます。
bladeファイルのresources/views/todolist.blade.php
を開いてください。
まずは、headタグの中にscriptタグを書いて、下記のようにcheckTodo関数を追加します。
<body>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<title>todo</title>
<!-- -ここから追加する ---->
<script>
function checkTodo(todoId) {
document.querySelector("#select_todo_id").value = todoId;
document.querySelector("#todo_form").action = "{{ route('todo.check') }}";
document.querySelector("#todo_form").submit();
}
</script>
<!-- -ここまで追加する ---->
</head>
<!-- -省略 ---->
</body>
フォームにidを付与します。
また、inputタグのhidden項目をフォームから送信する内容として作成します。(Todoのidを格納する)
フォームタグの下記の箇所を探してください…
<form method="post">
@csrf
<!-- -省略 ---->
下記のように修正します。
<form method="post" id="todo_form">
@csrf
<input type="hidden" name="select_todo_id" id="select_todo_id" value="" />
<!-- -省略 ---->
解説
チェックボタンを押した時に動かす関数と、フォームを修正しました。
一覧のチェックボタンを押すと、javascriptのcheckTodo関数が動きます。
やっている内容は下記になります。
- hidden項目にidを設定する
一覧でループしている中で、それぞれのTodoレコードのIDをcheckTodo関数に渡しています。
下記のコードで、チェックボタンがクリックされたときにTodoのidが送信されるようにフォームのhidden項目を設定しています。
querySelectorはHTMLの要素を取得するために使用しています。
document.querySelector("#select_todo_id").value = todoId;
- フォームにアクション先を指定して送信する
フォームのアクションにLaravelのrouteヘルパーで取得した送信先を設定しています。
その後にsubmitを呼び出して、送信して完了です。
document.querySelector("#todo_form").action = "{{ route('todo.check') }}";
document.querySelector("#todo_form").submit();
これで、チェックしたTodoのidがTodoControllerのcheckメソッドに送信される処理になります。
コントローラでは送信されたidからモデルを取得して更新するようにしましたね。
次は、routeヘルパーに書いてあるcheckメソッド(‘todo.check’)へのルーティングがないので作成しましょう。
ルーティングを修正して、チェック機能のルートを作成する
routes/web.php
を開いてください。
Route::get('/', [TodoController::class, 'index'])->name('todo.init');
Route::post('/add', [TodoController::class, 'add'])->name('todo.add');
// --- ここから追加する ---
Route::post('/check', [TodoController::class, 'check'])->name('todo.check')
// --- ここまで追加する ---
TODOを追加する時と同じように、チェック用のURLをPOST形式で追加しました。
これで、TodoControllerのcheckメソッドで処理されますね。
動作確認
開いて、チェックを入れます…
このようにチェックできることが確認できました!
データベースを確認すると、チェックされてcheckカラムの内容が「1」(true)になりました。
もう一度チェックボタンを押すと、チェック状態が消えてカラムが「0」(false)になることが確認できます。
終わりに
今回はチェック機能を作成していきました。
ビューからIDを渡しているところが少し複雑だったかと思います。
Todoレコードの更新は、レコードを取得する時と同じようにEloquentで簡単にできましたね。
次回はTodoの削除機能を作成します。
コメント