前提・実現したいこと
初めて質問させていただきます。
質問の仕方など至らないところがあるかと思いますので、そういったことも含めご意見いただければと思います。
TODOリストを作成しています。
タスクの状態を作業中・完了の2つに変更できるボタンをつけていて、
すべて・作業中・完了の3種類ラジオボタンを押下することで、それぞれタスクの状態による表示の切り替え機能を実装したいです。その際に元のID(インデックス)を保持したまま表示されるようにしたいです。
発生している問題・エラーメッセージ
TODOリストは配列で管理しています。
ラジオボタンが押されるたびに、フィルターを通して特定の要素だけを取り出し
表示させたいのですが、今のフィルターだと新しい配列を2つ作ってしまっているため
表示した時のID(インデックス)が元のIDと変わってしまいます。
ex.
実現したいこと。
[ラジオボタンすべて]
0 abc 作業中
1 def 完了
2 ghi 作業中
[ラジオボタン作業中]
0 abc 作業中
2 ght 作業中
[ラジオボタン完了]
1 def
現在
[ラジオボタンすべて]
0 abc 作業中
1 def 完了
2 ghi 作業中
[ラジオボタン作業中]
0 abc 作業中
1 ght 作業中
[ラジオボタン完了]
0 def
IDを変えることなく、ラジオボタンに合った表示ができるようなフィルターを作りたいです。
該当のソースコード
HTML
1<!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset='utf-8'> 5 <meta name='viewport' content='width=device-width'> 6 <title></title> 7 </head> 8 <body> 9 <h1>ToDoリスト</h1> 10 <form> 11 <input type='radio' name='status' checked>すべて 12 <input type='radio' name='status'>作業中 13 <input type='radio' name='status'>完了 14 </form> 15 <div> 16 <table> 17 <thead> 18 <tr> 19 <th>ID</th> 20 <th>コメント</th> 21 <th>状態</th> 22 </tr> 23 </thead> 24 <tbody id='newTask'> 25 </tbody> 26 </table> 27 </div> 28 29 <div> 30 <h3>タスクを追加する</h3> 31 <input id='task' type='text' value=''> 32 <input id='addBtn' type='button' value='追加'> 33 </div> 34 35 <script> 36 const tasks = []; 37 const addBtn = document.getElementById('addBtn'); 38 const tBody = document.getElementById('newTask'); 39 const radioBtn = document.getElementsByName('status'); 40 //追加機能 41 addBtn.addEventListener('click', () => { 42 const todo = {}; 43 const taskValue = document.getElementById('task').value; 44 if (taskValue === '') { 45 alert('文字を入力してください!') 46 }else { 47 todo['task'] = taskValue; 48 todo['status'] = '作業中'; 49 tasks.push(todo); 50 document.getElementById('task').value = ''; 51 show(tasks); 52 filterTasks(); 53 } 54 },false); 55//####################################################################### 56//###################[該当箇所]フィルターを作りたい ############################ 57 const filterTasks = () => { 58 if (radioBtn[0].checked) { 59 return show(tasks); 60 }else if (radioBtn[1].checked) { 61 const doingTasks = tasks.filter(element => { return element.status === '作業中'}); 62 return show(doingTasks); 63 }else{ 64 const doneTasks = tasks.filter(element => { return element.status === '完了' }); 65 return show(doneTasks); 66 } 67 };//このフィルターだと表示した時にIDが元のIDと変わってしまう。 68//####################################################################### 69//####################################################################### 70 //すべてのラジオボタンにイベントを追加 71 radioBtn.forEach((e, number) => { 72 radioBtn[number].addEventListener('click', filterTasks, false); 73 }); 74 const show = array => { 75 //子要素の全削除 76 tBody.textContent = ''; 77 array.forEach((tasksvalue, number) => { 78 const childTr = tBody.insertRow(); 79 const indexCell = childTr.insertCell(); 80 const taskCell = childTr.insertCell(); 81 const statusCell = childTr.insertCell(); 82 const statusBtn = document.createElement('input'); 83 const closeBtn = document.createElement('input'); 84 //タスクの番号を追加 85 indexCell.textContent = number; 86 //タスクのコメントを追加 87 taskCell.textContent = array[number].task; 88 //タスクの状態を追加 89 statusBtn.type = 'button'; 90 statusBtn.value = array[number].status; 91 statusCell.appendChild(statusBtn); 92 //状態変更機能 93 const switchStatus = e => { 94 statusBtn.value = e; 95 array[number].status = e; 96 }; 97 statusBtn.addEventListener('click', () => { 98 if (statusBtn.value === '作業中') { 99 switchStatus('完了'); 100 filterTasks(); 101 } else{ 102 switchStatus('作業中'); 103 filterTasks(); 104 } 105 },false); 106 //削除ボタンの追加 107 closeBtn.type = 'button'; 108 closeBtn.value = '削除'; 109 childTr.appendChild(closeBtn); 110 //削除機能 111 closeBtn.addEventListener('click', () => { 112 array.splice(number, 1); 113 show(tasks); 114 filterTasks(); 115 }, false) 116 }); 117 }; 118 </script> 119 </body> 120 </html> 121
試したこと
元はフィルターではなく該当箇所に以下のような関数を作り表示非表示を切り替えていました。
ただフィルターを作ればコードが省略できるかと考え実装しようとしています。
また、過去に似たような質問があったので回答を見せてもらいました。
そこで提示されているアンサーである、格納しているオブジェクト自体に番号を渡すという方法も解決策のひとつだと思うんですが、、それ以外の方法はないもんでしょうか。
HTML
1//ラジオボタン押下時の表示切り替え 2 function changeDisplay(){ 3 const tBodyChildren = document.getElementById('newTask').childNodes; 4 const doneTask = document.getElementsByClassName('doneTask'); 5 const doingTask = document.getElementsByClassName('doingTask'); 6 7 if(radioBtn[0].checked){ 8 tBodyChildren.forEach((e, index) => { 9 tBodyChildren[index].style.display = ''; 10 }) 11 }else if(radioBtn[1].checked){ 12 for(let i = 0; i < doneTask.length; i++){ 13 doneTask[i].style.display = 'none'; 14 }; 15 for(let i = 0; i < doingTask.length; i++){ 16 doingTask[i].style.display = ''; 17 }; 18 }else{ 19 for(let i = 0; i < doneTask.length; i++){ 20 doneTask[i].style.display = ''; 21 }; 22 for(let i = 0; i < doingTask.length; i++){ 23 doingTask[i].style.display = 'none'; 24 }; 25 }; 26 };
補足情報(FW/ツールのバージョンなど)
書いた方が良い情報があれば追加します。
よろしくお願いします。
回答2件
あなたの回答
tips
プレビュー