さて、前回予告したとおり、削除ボタンを設置します。
html-css-javascript.hatenadiary.com
前回も言ったとおり、チェックボックスを作って削除ボタンを押したらチェックした候補者を削除する、というものにします。
DOM操作
まずは要素を作る必要がありますね。
const checkTd = document.createElement("td");//<td></td>を作成
HTMLのチェックボックスは<input type="checkbox">という書き方なので、inputという要素とtypeを記入すれば完成ということになりますので、以下のように書きます。
const checkBox = document.createElement("input");//チェックボックスを作成 checkBox.type = "checkbox"; checkBox.value = candidate.id; checkTd.appendChild(checkBox);
上でtd(checkTd)を作りましたがそれと並行してチェックボックス(checkBox)を作り、checkTd.appendChild(checkBox);で、checkTdの子要素にcheckBoxを追加します。
また、どのチェックボックスにチェックを入れたかというのは候補者に割り当てたIDで判断します。
で、そのcheckTdをテーブルに追加します。
listItem.appendChild(checkTd);
正確にはlistItemの要素は<tr>なので、そこに追加する形になります。
あとは削除ボタンを付ければOKです。
<button id="deleteBtn">削除</button>
チェックボックスの情報を送信
削除ボタンを押したときに、チェックボックスにチェックがついているものの情報を送信します。
チェックボックスの値にIDを突っ込みます。
checkBox.value = candidate.id;
で、チェックが入ってるものをすべて選択するということですから、以下のようになります。
document.querySelectorAll("チェックが入っているチェックボックス")
チェックが入っているチェックボックスは以下のコマンドで探します。
"input[type='checkbox']:checked"
checkboxタイプのinputを探し、さらにcheckedでチェックがついているものをピックアップする、という意味です。
さて、ここまでをボタンと紐づけします。
deleteBtn.addEventListener("click", () => { const checkedBoxes = document.querySelectorAll( "input[type='checkbox']:checked" ); console.log(checkedBoxes); });
console.logでチェックボックスの値も見られるようにしておきました。
念のために言っておくと、これはIDとかではなくあくまで要素です。
renderのところでcheckBox.value = candidate.id;と書きました。
で、id=101だったとすると、以下のようになります。
<input type="checkbox" value="101">
これがチェックがついている状態だと以下のようになります。
<input type="checkbox" value="101" checked>
で、このようにcheckedがついているものをinput[type='checkbox']:checkedで判別して取り出すことになります。
次にcheckedが入っているもののみのIDを取り出します。
checkedBoxes.forEach((box) => { console.log(box.value); });
チェックがついてるもののみの配列であるところのcheckedBoxesの中身をすべて見て、IDを取り出していく処理です。
これを新しく配列を作って、そこに加えていくことになります。
const ids = []; checkedBoxes.forEach((box) => { ids.push(Number(box.value)); });
box.vauleは"101"などの文字列なので、Numberを使って数字に変換しておく必要があります。
サーバーへリクエスト
こうやって得たids、つまり削除したい項目のIDの配列をfetchによってサーバー側に送り、保存から削除するようリクエストします。
fetch("http://localhost:3000/api/delete", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ids }), }) .then((response) => response.json()) .then((data) => { console.log(data.message); loadCandidates(); }) .catch((err) => { console.error(err); });
受け取り口の名前はdeleteにしておきました。
サーバー側で受け取り
フロントから送り出したのでサーバーで受け取ります。
まず受け取り口はdeleteにしたので、こんな感じになりますね。
app.post("/api/delete", (req, res) => {
次にbodyにある配列を渡します。
const idsToDelete = req.body.ids; console.log("削除リクエストの受信:", idsToDelete);
次に送られてきた配列が保存されているデータにあるかどうかを調べ、選別します。
candidates = candidates.filter((candidate) => !idsToDelete.includes(candidate.id));
filterは残すものを選択するメソッドです。
たとえば以下のような場合。
candidates = [ { id: 101 }, { id: 102 }, { id: 103 } ]; idsToDelete = [101, 103];
残るのは101、103になります。
削除したい要素、つまり送られてきた要素は削除したいものなので、これらが残ってしまったら困ります。
なので右辺には!を付けて残るものを逆にします。
その右辺はというと
!idsToDelete.includes(candidate.id));
ですが、これはidsToDeleteのうちcandidate.idが含まれているかどうかを判別する、という意味です。
上述と合わせると、candidate.idを含まないものを残したいので!を付けることになります。
で、そうした処理をした新しい配列をサーバーに書き込みます。
fs.writeFileSync( "candidates.json", JSON.stringify(candidates, null, 2), "utf8"
ここまでをまとめて書きます。
app.post("/api/delete", (req, res) => { const idsToDelete = req.body.ids; console.log("削除リクエストの受信:", idsToDelete); candidates = candidates.filter((candidate) => !idsToDelete.includes(candidate.id)); fs.writeFileSync( "candidates.json", JSON.stringify(candidates, null, 2), "utf8" ); res.json({ message: "削除完了" }); });
実行してみる
はい、動きませんでした。
いつも通りですね。
次回直します。