こんにちは!本日もJavaScriptでToDoアプリを作っていきます!
前回のお話はこちらから
前回までの経過
登録ボタンを押すと、入力した内容、完了削除ボタンがリストに表示され、削除機能もつけました。
今回は完了ボタンを押したらDoneリストに移動するように実装していきます。
完了プログラムを実装
完了プログラムも削除プログラム同様、まずはプログラムを定義します。
const doneTodo = (donebtn) => {
const doneTodo = donebtn.closest('li'); //完了ボタンから1番近いliタグを取得
doneList.appendChild(doneTodo); //Doneリストの子要素に取得したliタグを挿入
};
1・2行目は変数名や引数の名前が異なるだけで、仕組みは削除プログラムと同様です。
そして3行目は、.appendChildで2行目で取得したliタグをdoneList(Doneリスト)に挿入しています。
定義が終わったら、呼び出す記述をしましょう。
//完了機能追加
donebtn.addEventListener('click', () => {
doneTodo(donebtn);
});
削除機能を追加したとき同様に、登録するボタンの.addEventListenerの中に記述しました。
完了ボタンを押したらDoneリストに移動するようになりました!
今は移動するだけなので、Doneリスト内の完了ボタンは消すように記述を加えます。
const doneTodo = (donebtn) => {
const doneTodo = donebtn.closest('li'); //変更なし
doneList.appendChild(doneTodo); //変更なし
donebtn.remove(); //<- 追加!!
};
4行目にdonebtn(完了ボタン)を.removeで削除する記述を追加しました。
Doneリストの中は削除ボタンのみになりました!
しかし、今の状態でDoneリストの削除を押すとエラーが出てしまいます。
指摘されている54行目の記述は、
todoList.removeChild(choseTodo);
todoList(画面左側ToDoリスト)の子要素であるchoseTodo(削除ボタンから1番近いliタグ)を削除してくださいという記述です。
ここでエラーが出るのは、todoListが無いからです。これをDoneリストを取得する記述に変えてあげると動きそうですね。削除が押されたアイテムがToDoリスト内かDoneリスト内かを条件分岐させて、処理を書きましょう。
//冒頭に追記
const doneList = document.getElementById("js-done-list"); //完了リストのul取得
const doneTodo = (donebtn) => {
const doneTodo = donebtn.closest('li');
//以下1行追記
doneTodo.setAttribute('class', 'done-item'); //条件分岐のための準備
//追記ここまで
doneList.appendChild(doneTodo);
donebtn.remove();
};
まずは条件分岐のための条件づくりを書き加えます。
冒頭にDoneリストのid取得プログラムを変数に入れておく記述を加えます。そしてdoneTodo関数内に、Doneリストに移動したliタグだけに、done-itemクラスを付与する記述を追記します。
それでは条件分岐を書いていきましょう。
const deleteTodo = (delbtn) => {
const delconfirm = this.confirm('本当に削除しますか?');
if (delconfirm === true) {
const choseTodo = delbtn.closest('li');
//削除が押されたアイテムがToDoリスト内かDoneリスト内かで処理を変える条件分岐
if (choseTodo.classList.contains('done-item')) { //liタグにdone-itemクラスがあれば
doneList.removeChild(choseTodo); //doneListの中の該当liタグを削除(右側Doneリスト内で削除を行う)
} else { //条件に一致しない場合は
todoList.removeChild(choseTodo); //todoListの中の該当liタグを削除(左側ToDoリスト内で削除を行う)
}
//追記ここまで
}
};
先程の準備のときにDoneリストに移動したliタグにクラスがあるかないかで条件を分岐させて、処理を分けています。
エラーなく正常に動作するようになりました!
ここまでで今回の仕様はすべてクリアしました。ここからは少しだけ工夫をしていきます。
フォームが空のときは登録しない
現在は入力せずに登録するとからのリストが生成されてしまいます。
入力がないときは登録しない(=入力があったときだけ処理が走る)ように条件分岐を書いていきましょう。
todoRegister.addEventListener('click', () => {
if (todoValue.value !== '') { // 入力フォームの値が空でないとき以下を実行
// ul>li>p構造を作る、divタグ挿入のプログラム
// 削除完了ボタンの追加プログラム
// 削除機能追加プログラム
// 完了機能追加プログラム
}
});
登録を押したときのイベント処理の中をif文の中に入れました。(ここでは長いのでif文内は省略)
何も入力していないときは登録イベントが実行されなくなりました!
次は登録するを押したら、フォームを空にするプログラムを実装しましょう。
登録を押したらフォームを空にする
現在は登録を押しても、入力した値が残ったままになっています。
これを登録を押したら、初期の状態に戻るように記述を加えます。
todoRegister.addEventListener('click', () => {
if (todoValue.value !== '') {
const todo = document.createTextNode(todoValue.value);
//以下1行追記
todoValue.value = ''; // フォームを初期状態(空)にする
//追記ここまで
const litag = document.createElement('li');
const ptag = document.createElement('p');
//ボタンを入れるdiv要素追加
//完了ボタン追加
//削除ボタン追加
//削除機能追加
//完了機能追加
}
});
5行目の記述を登録ボタンイベントの中に書き加えます。
登録するを押すと、入力していた値がなくなり初期状態に戻りました!
これにてToDoリスト完成です!
最後に
ToDoリスト完成しました!今の状態では再読込をするとすべてリセットされてしまいますが…。
JavaScriptでタグを増やしたりクラスをつけようとすると冗長になるんだなーと体感しました。
次回からはいよいよReactを本格的に触っていきます!
最後までお読み頂きありがとうございました。
コメント