JavaScriptで簡易的TODOアプリの作成 学習振り返り

# TODOアプリの作成の準備

- 下記の構造でファイルを作成

```
  TODO
    ├── index.html
    ├── index.js
    └── style.css  
```

# HTMLで構造を作成する(マークアップ)

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TODOアプリ</title>
    <link rel="stylesheet" href="./style.css">
</head>

<body>
    <div>
        <input placeholder="TODOを入力">
        <button>追加</button>
    </div>

    <div>
        <p>予定のTODO</p>
        <ul>
            <li>
                <div>
                    <p>勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
        </ul>
    </div>

    <div>
        <p>完了したTODO</p>
        <ul>
            <li>
                <div>
                    <p>飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
        </ul>
    </div>

    <script src="./index.js"></script>
</body>

</html>
```

# CSSでスタイリング

- まずは `index.html`　に `class` を付与

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TODOアプリ</title>
    <link rel="stylesheet" href="./style.css">
</head>

<body>
    <div class="input-area">
        <input placeholder="TODOを入力">
        <button>追加</button>
    </div>

    <div class="incomplete-area">
        <p class="title">予定のTODO</p>
        <ul>
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
        </ul>
    </div>

    <div class="complete-area">
        <p class="title">完了したTODO</p>
        <ul>
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
        </ul>
    </div>
    
    <script src="./index.js"></script>
</body>

</html>
```

- `styles.css` を編集

```css:styles.css
body {
  font-family: sans-serif;
  color: #666;
}

input {
  border-radius: 8px;
  border: none;
  padding: 6px 16px;
}

button {
  border-radius: 8px;
  border: none;
  padding: 4px 16px;
  margin: 0px 2px;
}

button:hover {
  background-color: #79a8a9;
  color: #fff;
  cursor: pointer;
}

.input-area {
  background-color: #c6e5d9;
  width: 400px;
  height: 30px;
  padding: 8px;
  margin: 8px;
  border-radius: 8px;
}

.incomplete-area {
  border: 2px solid #aacfd0;
  width: 400px;
  min-height: 200px;
  padding: 8px;
  margin: 8px;
  border-radius: 8px;
}

.complete-area {
  border: 2px solid #aacfd0;
  width: 400px;
  min-height: 200px;
  padding: 8px;
  margin: 8px;
  border-radius: 8px;
  background-color: #c9dede;
}

.title {
  text-align: center;
  margin-top: 0;
  font-weight: bold;
}

.list-row {
  display: flex;
  align-items: center;
}

.todo-item {
  margin: 6px;
}
```

# タスクの追加機能を実装していく

`index.html`を編集

- `追加`ボタンに `id`を付与 (id="add-button")

```html:index.html
<!-- 省略 -->

<body>
    <div class="input-area">
        <input placeholder="TODOを入力">
        <button id="add-button">追加</button>
    </div>

    <!-- 省略 -->

</body>

 <!-- 省略 -->
```


`index.js`を編集

- `id="add-button"`のある `追加`ボタンをクリックしたらアラートがでるようにする。(onClickAdd関数が動作するかどうかの確認)

```js:index.js
'use strict';

const onClickAdd = () => {
    alert();
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

`追加`ボタンをクリックしてアラートがでるか試してみる。

- TODOを入力して __`追加`__ ボタンをクリックするとアラートに追加したTODOが表示されるか試してみる(onClickAdd関数の実行時)。


- `class="input-area"`の `input`に`id="add-text"`を付与する。

`index.html`を編集

```html:index.html
<!-- 省略 -->

<body>
    <div class="input-area">
        <input id="add-text" placeholder="TODOを入力">
        <button id="add-button">追加</button>
    </div>

    <!-- 省略 -->

</body>

 <!-- 省略 -->
```

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    // 入力したTODOを const inputText に格納
    const inputText = document.getElementById('add-text').value;
    alert(inputText);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```
何か入力して `追加`ボタン押下時にアラートテキストが出力されるか確認。

- 追加後は テキストボックスにテキストが残らないようにするため、`value`を空にする(初期化)。

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    // 追加した後にテキストボックスを空白にして初期化する
    document.getElementById('add-text').value = '';
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

- `index.js`に `li`タグを生成する。

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    // liタグの生成
    const li = document.createElement("li");
    console.log(li); // TODO追加後に生成されているかどうか確認
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

TODO追加後はコンソールを確認

```:console
<li></li>
```

- 続いて `div` タグの生成

`index.js`に追加

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    // divタグの生成
    const div = document.createElement("div");
    console.log(div);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

同じくコンソールを確認

```:console
<div></div>
```
- `div`タグに `class="list-row"` を付ける

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row"; // divにclass="list-row"を付ける
    console.log(div);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

```:console
<div class="list-row"></div>
```

- `p`タグを生成
- `p`タグには `todo-item`クラスを付ける
- `p`タグには追加されたTODOが入るようにする(定数 `inputText`に追加するTODOが入る)

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

    // pタグの生成
    const p = document.createElement("p");
    // pタグにclass="todo-item"を付ける
    p.className = "todo-item";
    // pタグに追加されたTODOを入れる
    p.innerText = inputText;
    console.log(p);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

```:console
<p class="todo-item">hoge</p>
```

- `<div class="list-row">` の子要素に `<p class="todo-item"></p>`を配置する。

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    // divタグの子要素にpタグを配置
    div.appendChild(p);
    console.log(div);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

```:console
<div class="list-row">
    <p class="todo-item">hoge</p>
</div>
```

- `li`タグの子要素に`<div class="list-row>`を配置する

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    div.appendChild(p);

    // liタグの子要素にdivを配置
    li.appendChild(div);
    console.log(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

```:console
<li>
  <div class="list-row">
    <p class="todo-item">hoge</p>
  </div>
</li>
```

- `incomplete-area`内の `ul`タグに `id="incomplete-list"`を付与する

`index.html`を編集

```html:index.html
<!-- 省略 -->

    <div class="incomplete-area">
        <p class="title">予定のTODO</p>
        <ul id="incomplete-list"> <!-- id="incomplete-list"の付与 -->
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
        </ul>
    </div>

    <!-- 以下省略 -->
```

- `<ul id="incomlete-list">`の子要素に`li`タグを配置する(未完了リストに追加)。

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    div.appendChild(p);

    li.appendChild(div);

    // idがincomlete-listの子要素にliタグを入れる(未完了リストに追加)
    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

これで、ブラウザに追加したTODOが表示される。

# TODOの完了ボタンと削除ボタンの生成

- 完了ボタンの生成

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    // button(完了)ボタンの生成
    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    console.log(completeButton);

    div.appendChild(p);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

```:console
<button>完了</button>
```

- 削除ボタンの生成

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";

    // button(削除)ボタンの生成
    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    console.log(deleteButton);

    div.appendChild(p);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

```:console
<button>削除</button>
```

- `div`タグ(incomplete-list内) の子要素に`完了`ボタンと`削除`ボタンを配置する。

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";

    // 順番通りに。。。
    div.appendChild(p);
    div.appendChild(completeButton); // 完了ボタンをdivの子要素に配置
    div.appendChild(deleteButton); // 削除ボタンをdivの子要素に配置

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

これで何かTodo追加時に`完了`ボタンと`削除`ボタンがブラウザで表示される。

# TODOの削除機能を作成

- `削除`ボタンと`完了`ボタンに`addEventListener`の適用

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    // addEventListenerの適用
    completeButton.addEventListener('click', () => {
        alert("完了"); // 完了ボタン押下時の処理
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        alert("削除"); // 削除ボタンを押下時の処理
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

`完了`ボタン及び`削除`ボタンをクリックするとアラートがでる(テスト)。

- TODOを削除する際は、`li`タグから削除されるようにする `closest`を使用すると良い。
(削除ボタンの親にある`li`タグから拾う)

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        alert("完了");
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        // 削除ボタンの親にあるliから要素を拾う
        // deleteTargetには削除する要素が入っている
        const deleteTarget = deleteButton.closest("li"); 
        console.log(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

下記が削除したい要素になる

```:console
<li>
  <div class="list-row">
    <p class="todo-item">hoge</p>
    <button>完了</button>
  </div>
</li>
```

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

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

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

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        alert("完了");
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        // deleteTargetは<ul id="incomplete-list">の子要素になるため removeChildメソッドにdeleteTargetを指定して上げればよい
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

これでTODOは削除可能になる。

# TODOの完了機能を作成

- `完了`ボタン押下時のプロセス
1. `完了`ボタン押下すると`complete-area`の方へ移動するようになるので、その要素を選択するようにする。
2. `削除`ボタンが削除される
( `nextElementSibling`メソッドを使い`完了`ボタン要素の次に続く兄弟要素ノードを選択できる。つまり、ボタンの直後に存在するHTML要素を取得して、それを`remove`メソッドで`削除`ボタンを削除できる)
3. `完了`ボタンが削除される
(単純に`completeButton`を`remove`メソッドを使って削除すればよい)


### `完了`ボタンを押下時に`削除`ボタンが消えるようにする

`index.js`を編集

```js:index.js
    // 省略

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        // completeエリアに移動する要素を選択
        const moveTarget = completeButton.closest("li");
        // 完了ボタンの兄弟要素の削除ボタンを選択し、削除する
        completeButton.nextElementSibling.remove();
        // 完了ボタンを削除
        completeButton.remove();
    });

    // 以下省略
```

これで`完了`ボタンを押下すると`削除`ボタンと`完了`ボタンは削除される。

# `完了`ボタン押下後に`戻す`ボタンが追加されるようにする

- `moveTarget`の要素の初めの子要素(`div`)の子要素に`戻す`ボタンを追加するようにするには `firstElementChild`メソッドと`appendChild`メソッドを繋げるようにする。

`index.js`を編集

```js:index.js
    // 省略

        const completeButton = document.createElement("button");
        completeButton.innerText = "完了";
        completeButton.addEventListener('click', () => {
          const moveTarget = completeButton.closest("li");
          completeButton.nextElementSibling.remove();
          completeButton.remove();
          // ボタン要素の作成
          const backButton = document.createElement("button");
          // ボタン要素にテキスト '戻す'を設定
          backButton.innerText = "戻す";
          // moveTarget(li要素)の子要素(div)のさらに子要素に'戻す'ボタンを追加
          moveTarget.firstElementChild.appendChild(backButton);
    });

  // 以下省略
```

これで`完了`ボタンを押下すると `戻す`ボタンが追加される

# 完了したTODOエリア(complete-area)に移動する

1. `html`の`complete-area`の `ul`タグに`id="complete-list"`を付与する。
2. `moveTarget`を`<ul id="complete-list">`の子要素に配置する。

```html:index.html
      <!-- 省略 -->

    <div class="complete-area">
        <p class="title">完了したTODO</p>
        <ul id="complete-list"> <!-- id="complete-list"を付与 -->
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
        </ul>
    </div>

    <!-- 以下省略 -->
```

- `moveTarget`を`id="complete-list"`の子要素に移動

`index.js`を編集

```js:index.js
    // 省略

        const completeButton = document.createElement("button");
        completeButton.innerText = "完了";
        completeButton.addEventListener('click', () => {
          const moveTarget = completeButton.closest("li");
          completeButton.nextElementSibling.remove();
          completeButton.remove();
          const backButton = document.createElement("button");
          backButton.innerText = "戻す";
          moveTarget.firstElementChild.appendChild(backButton);
          // complete-listの子要素に moveTargetを移動
          document.getElementById("complete-list").appendChild(moveTarget);
    });

    // 以下省略
```

これで `完了`ボタンを押下すると完了したTODOのリストに移動する

# 完了したTODOを予定のTODOへ戻す機能の実装

1. `createIncompleteTodo`関数を作成して渡された引数を基に未完了のTODOを作成する機能を実装します。

2. 下記の`index.js`の 下記のコードの部分を `createImcompleteTodo`関数の中に移動します。
3. `onClickAdd`関数の中の 定数 `inputText` を `createIncompleteTodo`に送るようにしなくてはならないので、`onClickAdd`関数の中に `createIncompleteTodo`関数を実行させる記述が必要になります。

```js:index.js
// 下記の部分のコードをcreateImcompleteTodo関数を作成して、その中に移動する
    const li = document.createElement("li");

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

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

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";
        moveTarget.firstElementChild.appendChild(backButton);
        document.getElementById("complete-list").appendChild(moveTarget);
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
```

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';
    // inputTextをcreateIncompleteTodo関数に送る
    createIncompleteTodo(inputText);
}

// 渡された引数を基に未完了のTODOを作成する関数
const createIncompleteTodo = (todo) => {
    // ここから移動してきたコード
    const li = document.createElement("li");

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

    const p = document.createElement("p");
    p.className = "todo-item";
    // inputTextはtodoの引数に入ってくるので todo に変更する
    p.innerText = todo;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";
        moveTarget.firstElementChild.appendChild(backButton);
        document.getElementById("complete-list").appendChild(moveTarget);
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
    // ここまで
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

1. `戻す`ボタンをクリックした時の`addEventListener`を追加します。
2. 

`index.js`を編集

```js:index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';
    createIncompleteTodo(inputText);
}

const createIncompleteTodo = (todo) => {
    const li = document.createElement("li");

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

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = todo;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";

        // 戻すボタンのイベントリスナーを追加
        backButton.addEventListener("click", () => {
            alert();
        });

        moveTarget.firstElementChild.appendChild(backButton);
        document.getElementById("complete-list").appendChild(moveTarget);
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
```

- `戻す`ボタンのイベントリスナーの中の処理内容
1. `previousElementSibling`メソッドを使って `buckButton` の一個手前に要素(pタグになる)を参照して`innerText`メソッドでテキストだけを取得する。
2. `createIncompleteTodo`関数の引数にそのテキストを入れるようにして実行させる
(予定のTODOのリストに追加される)
3. まだ`戻す`ボタンを押下しても完了したTODOに残ってるのでそれを削除するようにする

`index.js`を編集

```js:index.js
   // 省略

         backButton.addEventListener("click", () => {
         　　　　　　// backbutton.previousElementSiblingはbuckButtonの一個手前に要素(pタグになる)を参照してinnerTextでテキストだけを取得する
            const todoText = backButton.previousElementSibling.innerText;
            // createIncompleteTodoの引数にtodoTextを入れて実行
            createIncompleteTodo(todoText);
            // 完了したTODOに戻したTODOが残ってしまうので削除する
            backButton.closest("li").remove();
        });

  // 以下省略
```

以上で 戻す機能の実装は終了です。

後は以下のように `index.html`の `li`要素ノードを消しておけばOKです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TODOアプリ</title>
    <link rel="stylesheet" href="./style.css">
</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">
        </ul>
    </div>

    <div class="complete-area">
        <p class="title">完了したTODO</p>
        <ul id="complete-list">
        </ul>
    </div>

    <script src="./index.js"></script>
</body>

</html>
```

JavaScriptだけでこのようなアプリを作成するとなるとこんなに複雑になるのですね。
仕組みはよく理解できました。