###前提・実現したいこと
それぞれ「すべて」 「作業中」 「完了」 とラベルがついたラジオボタンを準備し、作業中のラジオボタンを押下するとstateが作業中のTaskのみ、完了のラジオボタンを押下するとstateが完了のTaskのみ表示するようにしたい。
その際、IDの番号は最初に表示されたものを引継ぎそのまま表示されるようにしたい。
###該当のソースコード
HTML
1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>TodoList</title> 8</head> 9 10<body> 11 <h1>ToDoリスト</h1> 12 <form> 13 <input type="radio" name="state" id="allTodo"> 14 <label for="radio1">すべて</label> 15 <input type="radio" name="state" id="workingTodo"> 16 <label for="radio2">作業中</label> 17 <input type="radio" name="state" id="doneTodo"> 18 <label for="radio3">完了</label> 19 </form> 20 21 <div> 22 <table> 23 <thead> 24 <tr> 25 <th>ID</th> 26 <th>コメント</th> 27 <th>状態</th> 28 </tr> 29 </thead> 30 <tbody id="todoList"> 31 32 </tbody> 33 </table> 34 35 </div> 36 37 <h2>新規タスクの追加</h2> 38 <form> 39 <input type="text" id="todoInput" value=""> 40 <button type="submit" value="追加" id="addTaskButton">追加</button> 41 </form> 42 <script src="main.js"></script> 43</body> 44 45</html>
JavaScript
1const radio1 = document.getElementById('radio1') 2const radio2 = document.getElementById('radio2') 3const radio3 = document.getElementById('radio3') 4const todoList = document.getElementById('todoList'); 5const addTaskButton = document.getElementById('addTaskButton'); 6const textBox = document.getElementById('todoInput'); 7 8const todos = []; 9 10//stateが作業中にTodoのみ抽出する関数 11radio2.addEventListener('click', () => { 12 const filter = todos.filter((todo) => { 13 return todo.state === '作業中'; 14 }); 15 console.log(filter); 16}); 17 18 19addTaskButton.addEventListener('click', (e) => { 20 e.preventDefault(); 21 const todoInput = { task: textBox.value, state: '作業中' }; 22 textBox.value = ''; 23 if (todoInput.task.match(/\S/g)) { 24 //空白以外の文字に一致したら配列に追加 25 todos.push(todoInput); 26 textBox.focus(); 27 } 28 addTask(); 29 console.log(todos); 30}); 31 32//配列に格納されたToDoをHTMLに表示させる為の関数 33const addTask = () => { 34 while (todoList.firstChild) { 35 todoList.removeChild(todoList.firstChild); 36 } 37 38 todos.forEach((todo, id) => { 39 const tr = document.createElement('tr'); 40 todoList.appendChild(tr); 41 42 const idTd = document.createElement('td'); 43 const comment = document.createElement('td'); 44 const stateTd = document.createElement('td'); 45 const deleteTd = document.createElement('td'); 46 47 tr.appendChild(idTd); 48 tr.appendChild(comment); 49 tr.appendChild(stateTd); 50 tr.appendChild(deleteTd); 51 52 idTd.textContent = id; 53 comment.textContent = todo.task; 54 55 stateTd.appendChild(createStateButton(id)); 56 deleteTd.appendChild(createDeleteButton(id)); 57 }); 58}; 59 60//状態を管理する為のボタンを作成する関数 61const createStateButton = (id) => { 62 const workingBtn = document.createElement('button'); 63 workingBtn.textContent = todos[id].state; 64 workingBtn.addEventListener('click', () => { 65 if (todos[id].state === '作業中') { 66 todos[id].state = '完了'; 67 } else { 68 todos[id].state = '作業中'; 69 } 70 addTask(); 71 }); 72 return workingBtn; 73}; 74 75//ToDoを削除するボタンを作る為の関数 76const createDeleteButton = (id) => { 77 const deleteBtn = document.createElement('button'); 78 deleteBtn.textContent = '削除'; 79 deleteBtn.addEventListener('click', () => { 80 if (id > -1) { 81 todos.splice(id, 1); 82 } 83 addTask(); 84 }); 85 return deleteBtn; 86};
###問題点
filter()を使い、stateが作業中のtaskのみを抽出することはできたのですが、
その後、抽出したものをどう処理すればいいか見当がつかず進めません。
forEach()を使い表示しようと考えてみたのですが、コードが冗長になってしまい何かいい方法がないかと思い質問させていただきました。
また、IDの連番はTODOを表示させる関数の中でforEachした時の添字を代入しています。
filter()を使った場合、新しい配列が作成されることにより添字の番号も変わってしまうことも問題です。
ご教授いただければ幸いです。
よろしくお願いします????♂️
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/05 23:33