はじめに
これまで勉強してきたことを活かして、追加、編集、削除機能を持つToDoアプリを作ってみたので、その時のことをメモに残します。
▼(2024/09/07追記)▼
コメントにて完成品に不具合があるとのご指摘をいただきましたので、完成品と記事に掲載しているコードの修正を行いました。
完成品
実装したいこと
- テキストボックスにToDoを入力し追加ボタンを押すと、ToDoがリストに追加される
- テキストボックスが空欄のまま追加ボタンを押すと、アラートが出る
- リストに追加された各ToDoには、編集ボタンと削除ボタンを付与する
- 編集ボタンを押すと、ToDoのテキスト部分がToDo名の値を保持したテキストボックスに変化する
- ToDoの編集が完了したら、テキストボックスが消えて新たなToDo名のテキストに変化する
- ToDo編集時も、テキストボックスが空欄であればアラートを出す
- 削除ボタンを押すと、ToDoが削除される
製作過程
HTML
index.html
<form action="#" id="todoForm">
<input type="text" name="todo" id="todo">
<input type="submit" value="追加する">
</form>
<ul id="todoList"></ul>
JavaScript
全コード
app.js
const form = document.querySelector("#todoForm");
const list = document.querySelector("#todoList");
// ToDo追加の関数
const addTodo = (val) => {
// テキストボックスが空欄の場合はアラートを出す
if (!val) {
alert("ToDoを入力してください!!");
} else { // テキストボックスが空欄でなければToDoを追加
// liタグを作成
const todo = document.createElement("li");
// spanタグを作成し、テキストボックスの値を入れる
const label = document.createElement("span");
label.innerText = val;
// 編集ボタンを作成
const editBtn = document.createElement("button");
editBtn.classList.add("editBtn");
editBtn.innerText = "編集する";
// 削除ボタンを作成
const deleteBtn = document.createElement("button");
deleteBtn.classList.add("deleteBtn");
deleteBtn.innerText = "削除する";
// liタグにspanタグ、編集ボタン、削除ボタンを追加
todo.append(label, editBtn, deleteBtn);
// ulタグにliタグを追加
list.append(todo);
}
};
// ToDo編集の関数
const editTodo = (target) => {
if (target.innerText === "編集する") {
// 編集ボタンのテキストを変更
target.innerText = "登録する";
// spanタグを取得
const label = target.previousElementSibling;
// テキストボックスを作成し、value属性をspanタグのToDoに設定
const editInput = document.createElement("input");
editInput.setAttribute("type", "text");
editInput.setAttribute("value", label.innerText);
// spanタグをテキストボックスに差し替える
label.replaceWith(editInput);
} else {
// テキストボックスを取得
const editInput = target.previousElementSibling;
// テキストボックスが空欄の場合はアラートを出す
if (!editInput.value) {
alert("ToDoを入力してください!!")
} else { // テキストボックスが空欄でなければToDoを修正する
// spanタグを作成し、spanタグのテキストにテキストボックスのvalue属性を代入
const label = document.createElement("span");
label.innerText = editInput.value;
// テキストボックスをspanタグに差し替える
editInput.replaceWith(label);
// 編集ボタンのテキストを変更
target.innerText = "編集する";
}
}
};
// ToDo削除の関数
const deleteTodo = (target) => {
// 削除ボタンの親liタグを削除
target.closest("li").remove();
};
document.addEventListener("click", function (e) {
// イベントが発生した要素を取得
const element = e.target;
if (!(element instanceof HTMLElement)) return;
// 編集ボタンをクリックすると、ToDoを編集する関数を実行
if (element.matches(".editBtn")) {
editTodo(element);
}
// 削除ボタンをクリックすると、ToDoを削除する関数を実行
else if (element.matches(".deleteBtn")) {
deleteTodo(element);
}
});
form.addEventListener("submit", function (e) {
e.preventDefault();
// テキストボックスの値を取得
const todoVal = document.querySelector("#todo").value;
// ToDoの追加
addTodo(todoVal);
// テキストボックスを初期化
document.querySelector("#todo").value = "";
});
解説1: ToDo追加
app.js
// ToDo追加の関数
const addTodo = (val) => {
// テキストボックスが空欄の場合はアラートを出す
if (!val) {
alert("ToDoを入力してください!!");
} else { // テキストボックスが空欄でなければToDoを追加
// liタグを作成
const todo = document.createElement("li");
// spanタグを作成し、テキストボックスの値を入れる
const label = document.createElement("span");
label.innerText = val;
// 編集ボタンを作成
const editBtn = document.createElement("button");
editBtn.classList.add("editBtn");
editBtn.innerText = "編集する";
// 削除ボタンを作成
const deleteBtn = document.createElement("button");
deleteBtn.classList.add("deleteBtn");
deleteBtn.innerText = "削除する";
// liタグにspanタグ、編集ボタン、削除ボタンを追加
todo.append(label, editBtn, deleteBtn);
// ulタグにliタグを追加
list.append(todo);
}
};
- テキストボックスが空欄
- アラートを出す
- テキストボックスが空欄でない
- テキストボックスに入力された値を取得し、以下のような構造のHTMLタグが
ul
タグの中に追加されるindex.html<li> <span>テキストボックスに入力された値</span> <button class="editBtn">編集する</button> <button class="deleteBtn">削除する</button> </li>
- テキストボックスに入力された値を取得し、以下のような構造のHTMLタグが
解説2: ToDo削除
app.js
// ToDo削除の関数
const deleteTodo = (target) => {
// 削除ボタンの親liタグを削除
target.closest("li").remove();
};
- 削除ボタンがクリックされたら、親タグである
li
タグごと削除される
解説3: ToDo編集機能
app.js
// ToDo編集の関数
const editTodo = (target) => {
if (target.innerText === "編集する") {
// 編集ボタンのテキストを変更
target.innerText = "登録する";
// spanタグを取得
const label = target.previousElementSibling;
// テキストボックスを作成し、value属性をspanタグのToDoに設定
const editInput = document.createElement("input");
editInput.setAttribute("type", "text");
editInput.setAttribute("value", label.innerText);
// spanタグをテキストボックスに差し替える
label.replaceWith(editInput);
} else {
// テキストボックスを取得
const editInput = target.previousElementSibling;
// テキストボックスが空欄の場合はアラートを出す
if (!editInput.value) {
alert("ToDoを入力してください!!")
} else { // テキストボックスが空欄でなければToDoを修正する
// spanタグを作成し、spanタグのテキストにテキストボックスのvalue属性を代入
const label = document.createElement("span");
label.innerText = editInput.value;
// テキストボックスをspanタグに差し替える
editInput.replaceWith(label);
// 編集ボタンのテキストを変更
target.innerText = "編集する";
}
}
};
- ToDoの編集を行う場合のプログラム
- 編集ボタンのテキストを「編集する」から「登録する」に変更する
- テキストボックスを作成し、value属性値を
span
タグのテキスト(ToDo)に設定する -
span
タグをテキストボックスに差し替える
- ToDoの編集が完了した場合のプログラム
- テキストボックスが空欄でない
-
span
タグを作成し、テキストをテキストボックスのvalue属性値に設定する - テキストボックスを
span
タグに差し替える - 編集ボタンのテキストを「登録する」から「編集する」に変更する
-
- テキストボックスが空欄
- アラートを出す
- テキストボックスが空欄でない