JavaScriptだけでtodoアプリを作る（JS基礎復習）

家にいることが多くなったこのご時世。
比較的自由な時間が増えたので、全然触っていなかったJavaScriptを思い出すため、基礎の復習に最適だと聞くTodoアプリを作ってみました。


#todoアプリに実装する機能
todoアプリに実装する機能は、以下の通りです。

- テキストボックスに入力した文字を取得する
- addボタンを押した時
 - テキストボックスに入力した内容がToDoリストに表示される
 - 一項目を削除するボタン、全ての項目を削除するボタンを表示する
- ToDoリストに追加される項目の隣に✅（完了ボタン）を表示
- ✅（完了ボタン）を押した時
  - Doneリストにその項目を表示する  
  - 項目の隣に削除ボタン、✅を押した日時を表示する 

こちらが完成図になります。
<img width="1439" alt="スクリーンショット 2020-05-14 12.03.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529982/42dde490-c85e-7bff-e990-0853ec45e829.png">
こんな条件で、todoアプリを作ってみます。

##Step1.まずは見た目から
まずはHTMLとCSSで、見た目の部分だけ作ります。
HTMLは、

```html:todoappforjs


<body>
    <header>
        <h1>ToDoアプリ</h1>
    </header>
    <div class="addli">
        <input id="add-area" type="text" placeholder="To Do">
        <span class="add-btn">add</span>
    </div>
    <div id="todo-app">
        <ul class="lists" id="todo">
            <p>ToDo</p>
        </ul>
        <ul class="lists" id="done">
            <p>Done</p>
        </ul>
    </div>
</body>

```

以上がHTMLです。CSSは割愛します。

<img width="800" alt="スクリーンショット 2020-05-06 19.00.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529982/2a1771bc-1c7e-cd89-1f08-4cc186c1e0a8.png">
見た目はこんな感じ。


##Step2.textboxに入力した内容がToDoに表示されるまで
ここからJavaScriptを記述します。

```javascript
//class 'add-btn' を取得
var e = document.getElementsByClassName('add-btn');

e[0].addEventListener('click', function() {
    var listText = document.getElementById('add-area');
    var text = document.createTextNode('listText.value');
    var li = document.createElement('li');
    var list = document.getElementById('todo');
  //作成したliタグにtextboxに入力した値textを追加
    li.appendChild(text);
    list.appendChild(li);
});

```
addボタンをクリックした時に、`input`タグに入力されている値の`value`を取得し、新たに`li`タグをToDoリスト内に作り、そこに先ほどの`input`タグに入力した値を追加するという内容です。

##step3.削除ボタン、完了ボタンの実装まで
続いて、作成した`li`タグに削除ボタン、完了ボタンを追加します。ちなみに、ゴミ箱のアイコンとチェックマークのアイコンは、<a href="https://fontawesome.com/">Font Awesome</a>を使っています。同様にJavaScriptから、

```javascript

e[0].addEventListener('click', function(){
var li = document.createElement('li');
//削除ボタン
var trash = document.createElement('span');
trash.classList.add('trash');
trash.innerHTML = '削除　<i class="fas fa-trash-alt"></i>';
li.appendChild(trash);

//完了ボタン
var check = document.createElement('span');
check.classList.add('check');
check.innerHTML = '完了　<i class="far fa-check-square"></i>';
li.appendChild(check);
var list = document.getElementById('todo');
list.appendChild(li)

}) 

```

ここまでのJavaScriptはaddボタンを押した時のイベントを記述しているので、中身を一つの関数にまとめます。

```javascript
function addElement() {
    var text = document.createTextNode('listText.value');
    var li = document.createElement('li');
    var list = document.getElementById('todo');
  //作成したliタグにtextboxに入力した値textを追加
    li.appendChild(text);
    list.appendChild(li);
 //削除ボタン
    var trash = document.createElement('span');
    trash.classList.add('trash');
    trash.innerHTML = '削除　<i class="fas fa-trash-alt"></i>';
    li.appendChild(trash);

 //完了ボタン
    var check = document.createElement('span');
    check.classList.add('check');
    check.innerHTML = '完了　<i class="far fa-check-square"></i>';
    li.appendChild(check);

};

```

削除ボタン、完了ボタンにそれぞれクラスを割り当てたのは、判別化を図るためです。
`innerHTML`プロパティはそのままHTMLを書くことができるので便利ですね。

##step4.要素を削除する
続いて、削除ボタンを押した時に要素を削除するイベントを記述します。押した要素を判別するのに`for`文を使います。

```javascript
function trashBox() {
   var trash = document.getElementsByClassName('trash');
   for(var i = 0; i < trash.length; i++) {
       trash[i].addEventListener('click', function() {
              this.parentNode.remove();
       });
   }
}
```

削除ボタンを押すことで、その押したリストのみが削除される、といった内容の関数です。



##step5.Doneリストに要素を移動する
続いて、完了ボタンを押した時、Doneリスト内に移動する、というイベントを記述します。
こちらも、削除ボタンと同様に`for`文でまわします。

```javascript
function checkBox() {
    var check = document.getElementsByClassName('check');
    var done = document.getElementById('done');
    for(var i = 0; i < check.length; i++) {
        check[i].addEventListener('click', function() {
            done.appendChild(this.parentNode);
        });
    }
}
```

##JSのコードまとめ

最後に、まとめとしてこれまでのコードの記述の一覧を載せます。

```javascript
var e = document.getElementsByClassName('add-btn');

e[0].addEventListener('click', function() {
    addElement();
    trashBox();
    checkBox();
});

function addElement() {
    var listText = document.getElementById('add-area');
    var text = document.createTextNode(listText.value);
    var li = document.createElement('li');
    li.appendChild(text);


    // li要素にボタンを追加
    var trash = document.createElement('span');
    trash.classList.add('trashPosition');
    trash.classList.add('trash');
    trash.innerHTML = '削除　<i class="fas fa-trash-alt"></i>'
    li.appendChild(trash);

    var check = document.createElement('span');
    check.classList.add('checkPosition');
    check.classList.add('check');
    check.innerHTML = '完了　<i class="far fa-check-square"></i>'
    li.appendChild(check);


    var lists = document.getElementById('todo')
    lists.appendChild(li);
};

// todoリスト内の削除ボタン
function trashBox() {
    var trash = document.getElementsByClassName('trash');
    // クリックしたliタグの配列数を取得
    for (var i = 0; i < trash.length; i++) {
        trash[i].addEventListener('click', function() {
            // thisはtrash[i]にあたる
            var li = this.parentNode;
            li.remove();
            // console.log(i);
        });
    };
};

function checkBox() {
    var check = document.getElementsByClassName('check');
    var done = document.getElementById('done');
    for (var i = 0; i < check.length; i++) {
        check[i].addEventListener('click', function() {
            var li = this.parentNode;
            done.appendChild(li);
            this.remove();
        });
    };
};
```

#終わりに
以上がJavaScriptのみで作るTodoアプリでした。基礎的な部分のみを理解して作ったものなので、どこか間違ってる箇所や、より効率的にかけるところがあれば、ご指摘いただけるとありがたいです。