[JavaScript][L3] ボタン押下によりコンテンツ(div>ul>li)を別コンテンツ(div>ul>li)に移動(生成)する

# 実施条件
[[[JavaScript][L2] ボタン押下によりコンテンツ(div>ul>li)を削除する](https://qiita.com/Jochun/items/c79fa73fb224d52897c0)を理解していること

# 環境
MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0（23A344）
Homebrew 4.3.8
gh 2.52.0

# ソースコード外観

## HTML
~~~html:index.html
<!DOCTYPE html>
<html>
  <head>
    <title>TODO(JS)</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div class="input-area">
      <input id="add-text" placeholder="TODOを入力" />
      <button id="add-button">追加</button>
    </div>
    <div class="incomplete-area">
      <p class="title">未完了のTODO</p>
      <ul id="incomplete-list">
        <!--  // 完成系の例としてliタグ以下を作成している
        <li>
          <div class="list-row">
            <p class="todo-item">TODOです</p>
            <button>完了</button>
            <button>削除</button>
          </div>
        </li> -->
      </ul>
    </div>
    <div class="complete-area">
      <p class="title">完了したTODO</p>
      <ul id="complete-list">
        <!--  // 完成系の例としてliタグ以下を作成している
        <li>
          <div class="list-row">
            <p class="todo-item">TODOでした</p>
            <button>戻す</button>
          </div>
        </li> -->
      </ul>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>
~~~

## JavaScript
~~~js:index.js
import "./styles.css";

const onClickAdd = () => {
  // テキストボックスの値を取得し、初期化する
  const inputText = document.getElementById("add-text").value;
  document.getElementById("add-text").value = "";

  // li生成
  const li = document.createElement("li");

  // div生成
  const div = document.createElement("div");
  div.className = "list-row";

  // p生成
  const p = document.createElement("p");
  p.className = "todo-item";
  p.innerText = inputText;

  // button(完了)タグ生成
  const completeButton = document.createElement("button");
  completeButton.innerText = "完了";
  completeButton.addEventListener("click", () => {
    // 押された完了ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
    const moveTarget = completeButton.closest("li");
    completeButton.nextElementSibling.remove();
    completeButton.remove();
    // 戻すボタンを生成してdivタグ配下に設定
    const backButton = document.createElement("button");
    backButton.innerText = "戻す";
    moveTarget.firstElementChild.appendChild(backButton);
    // 完了リストに移動
    document.getElementById("complete-list").appendChild(moveTarget);
  });

  // button(削除)タグ生成
  const deleteButton = document.createElement("button");
  deleteButton.innerText = "削除";
  deleteButton.addEventListener("click", () => {
    // 押された削除ボタンの親にあるliタグを未完了リストから削除
    const deleteTarget = deleteButton.closest("li");
    document.getElementById("incomplete-list").removeChild(deleteTarget);
  });

  // liタグの子要素に各要素を設定
  div.appendChild(p);
  div.appendChild(completeButton);
  div.appendChild(deleteButton);
  li.appendChild(div);

  // id="incomplete-list"の`ul`タグに子要素を設定した`li`タグを追加
  document.getElementById("incomplete-list").appendChild(li);
};

document.getElementById("add-button").addEventListener("click", onClickAdd);
~~~


# 手順
## 概観
1. 完了buttonとして定義した`completeButton`に、仮の`click`イベントとして`alert("完了")`で設定する
    ~~~js:index.js
    completeButton.innerText = "完了";
    // 仮の`click`イベントとして`alert("完了")`で設定している = clickされた時の関数はここに記載していく
    completeButton.addEventListener("click", () => {
        alert("完了");
    });
    ~~~

1. 仮の`click`イベントである`alert("削除")`を正しい関数に直す
    ~~~diff_javascript:index.js
    completeButton.innerText = "完了";
    - // 仮の`click`イベントとして`alert("完了")`で設定している = clickされた時の関数はここに記載していく
    - completeButton.addEventListener("click", () => {
    -     alert("完了");
    + completeButton.addEventListener("click", () => {
    +     // 押された削除ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
    +     const moveTarget = completeButton.closest("li");
    +     completeButton.nextElementSibling.remove();
    +     completeButton.remove();
    +     // 戻すボタンを生成してdivタグ配下に設定
    +     const backButton = document.createElement("button");
    +     backButton.innerText = "戻す";
    +     moveTarget.firstElementChild.appendChild(backButton);
    +     // 完了リストに移動
    +     document.getElementById("complete-list").appendChild(moveTarget);
    });
    ~~~
## 詳細
1. 最終的に移動したいコンテンツ(`li`タグ)を後続の処理のために取得
    ~~~js:index.js
    const moveTarget = completeButton.closest("li");
    ~~~
1. 押された完了ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
    ~~~js:index.js
    // 押された完了ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
    const moveTarget = completeButton.closest("li");
    completeButton.nextElementSibling.remove();
    completeButton.remove();
    ~~~

1. 戻すボタンを生成してdivタグ配下に設定
    ~~~js:index.js
    // 戻すボタンを生成してdivタグ配下に設定
    const backButton = document.createElement("button");
    backButton.innerText = "戻す";
    moveTarget.firstElementChild.appendChild(backButton);
    ~~~

1. 完了リストに移動
    ~~~js:index.js
    // 完了リストに移動
    document.getElementById("complete-list").appendChild(moveTarget);
    ~~~

# 参考リンク
- [Element: nextElementSibling プロパティ](https://developer.mozilla.org/ja/docs/Web/API/Element/nextElementSibling)
- [Element: firstElementChild プロパティ](https://developer.mozilla.org/ja/docs/Web/API/Element/firstElementChild)