Javascript 追加、編集、削除の機能を持ったToDoリスト


#こんな感じ
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ピュアJSで追加、編集、削除の機能を持ったToDoリスト <a href="https://t.co/saHDWKuFo2">pic.twitter.com/saHDWKuFo2</a></p>&mdash; 高卒プログラマーげんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1416711813241073665?ref_src=twsrc%5Etfw">July 18, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#HTML/CSS/JavascriptだけのToDoリスト
全てのコードを一気に載せます。

##HTML

```html:index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>ToDo</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <div class="todoBox">
      <div class="todoBox_header">
        <h1>TODO</h1>
      </div>
      <div class="todoBox_main">
        <h1>一覧</h1>
        <div class="todoBox_list">
         <ul id="todo-list">
           <li class="todo-list-item">
            <span>卵と牛乳を買いに行く</span>
            <button class="todoDelete hide">削除</button>
          </li>
           <li class="todo-list-item">
            <span>白髪染めをする</span>
            <button class="todoDelete hide">削除</button>
          </li>
           <li class="todo-list-item">
            <span>USJのチケットを予約する</span>
            <button class="todoDelete hide">削除</button>
          </li>
         </ul>
        </div>
      </div>
      <div class="showMessage">
        <div id="doneTask" class="success hide">
          <p>正常にタスクを追加しました</p>
        </div>
        <div id="getError" class="error hide">
          <p>エラーが発生</p>
        </div>
        <div id="doneEdit" class="showEdit hide">
          <p>タスクを編集しました</p>
        </div>
        <div id="doneDelete" class="showDelete hide">
          <p>タスクを削除しました</p>
        </div>
      </div>
      <div class="todoBox_form">
        <div class="inputForm">
            <input type="text" name="text-input" id="text-input" placeholder="タスクを入力してください">
        </div>
        <button id="add" onclick="newElement()">登録</button>
        <button id="edit" class="hide" onclick="editElement()">編集</button>
      </div>
    </div>
  </div>
  <script src="app.js"></script>
</body>
</html>
```

##CSS

```css:style.css
.container {
  width: 100%;
  height: auto;
}

.todoBox {
  margin: 40px auto;
  width: 800px;
  min-height: 550px;
  border: solid;
  border-color: #707070;
}

.todoBox_header {
  background-color: #7C7C7C;
  height: 60px;
  padding-left: 20px;
}

.todoBox_header h1 {
  font-size: 30px;
  font-weight: 300;
  line-height: 60px;
  margin: 0;
  color: #ffffff;
}

.todoBox_main {
  min-height:400px;
  padding: 10px 25px;
}

.todoBox_main h1 {
  font-size: 30px;
  font-weight: 300;
}

.todoBox_list ul {
  list-style: none;
  padding: 0;
}

.todoBox_list li {
  display: flex;
  font-size: 20px;
  margin-bottom: 15px;
}

.todoDelete {
  width: 80px;
  height: 100%;
  color: #ffffff;
  background-color: #7A1710;
  border: none;
  font-size: 20px;
  margin-left: 20px;
}

.active-item {
  color:  #39813D;
}

.showMessage {
  font-size: 20px;
  padding: 0 25px;
}

#doneTask p {
  color:  #39813D;
}

#getError p {
  color: #7A1710;
}

#doneEdit p {
  color:  #39813D;
}

#doneDelete p {
  color:  #39813D;
}

.todoBox_form {
  padding: 0 25px;
  margin-bottom: 20px;
  height: 40px;
  display: flex;
  justify-content: space-between;
}

.inputForm {
  width: 84%;
}

.todoBox_form input {
  padding: 0 0 0 20px;
  font-size: 20px;
  height: 100%;
  width: 100%;
}

.todoBox_form button {
  width: 80px;
  height: 100%;
  color: #ffffff;
  background-color: #39813D;
  border: none;
  font-size: 20px;
}

.hide {
  display: none;
}
```

##Javascript

```javascript:app.js
'use strict';

const textInput = document.getElementById('text-input');
const todoList = document.getElementById('todo-list');
const editBtn = document.getElementById("edit");
const addBtn = document.getElementById("add");


//編集を解除
document.addEventListener('click', (e) => {
  if (e.target.className == 'active-item' || e.target.tagName == 'INPUT') {
  } else {
      editBtn.classList.add('hide');
      addBtn.classList.remove('hide');
  }
});


// リスト追加
function newElement() {
  const text = textInput.value.trim();
  const errorMessage = document.getElementById("getError");
  const deleteMessage = document.getElementById("doneDelete");
  if (text === '') {
    errorMessage.classList.remove('hide');
    hideMessage(errorMessage);
          return;
      }

  const li = document.createElement('li');
  const span = document.createElement('span');
  const button = document.createElement('button');
  const addMessage = document.getElementById("doneTask");

  li.classList.add('todo-list-item');
  span.textContent = text;
  button.textContent = '削除';
  button.classList.add('todoDelete');
  button.classList.add('hide');
  // 削除イベントを追加
  button.addEventListener('click', e => {
          todoList.removeChild(e.target.closest('li'));
          textInput.value = '';
          deleteMessage.classList.remove('hide');
          hideMessage(deleteMessage);
      });

  li.appendChild(span);
  li.appendChild(button);
  todoList.appendChild(li);
  textInput.value = '';
  addMessage.classList.remove('hide');
  hideMessage(addMessage);
}


// 編集ボタン
function editElement() {
  try{
  const text = textInput.value.trim();
  const activeItem = document.getElementsByClassName('active-item');
  const editMessage = document.getElementById("doneEdit");
  const errorMessage = document.getElementById("getError");
  activeItem[0].textContent = text;
  editMessage.classList.remove('hide');
  hideMessage(editMessage);
  } catch (e) {
    errorMessage.classList.remove('hide');
    hideMessage(errorMessage);
    console.error("エラー：", e.message);
  }
}


// 削除ボタン
const todoDelete = document.getElementsByClassName("todoDelete");
const deleteMessage = document.getElementById("doneDelete");
for (let i = 0; i < todoDelete.length; i++) {
  todoDelete[i].onclick = function() {
    todoList.removeChild(this.parentElement);
    textInput.value = '';
    deleteMessage.classList.remove('hide');
    hideMessage(deleteMessage);
  }
}

// リストをクリックした時
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
  const allList = document.getElementsByClassName('todo-list-item');
  for (let i = 0; i < allList.length; i++) {
    const listItem = allList[i];
    if (listItem) {
      listItem.firstElementChild.classList.remove('active-item');
      listItem.lastElementChild.classList.add('hide');
    }
  }
  if (ev.target.tagName === 'SPAN') {
    ev.target.classList.toggle('active-item');
  }
  // 削除ボタン表示
  ev.target.nextElementSibling.classList.remove('hide');
  editBtn.classList.remove('hide');
  addBtn.classList.add('hide');
  textInput.value = event.target.innerHTML;
}, false);

// メッセージを消す
function hideMessage(Element) {
  setTimeout(() => {
      Element.classList.add('hide');
    }, 2500);
}
```

これで何のフレームワークやライブラリも使用しない、**「純正Javascript」だけで追加、編集、削除の機能を持ったToDoリストを作成できました:muscle:**

いやー純正Javascriptだけで書くと、ソースが思った以上に長くなりますね・・:sweat:
結構無理やり実装した感があるので、あくまで参考程度でよろしくお願いします。