質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
ラジオボタン

ラジオボタンはフォームに使われる要素のひとつであり、ユーザに限られた選択肢からひとつの答えを選んでもらうというものです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

994閲覧

【TODOリスト】TodoリストのID番号の振り分け機能について

yukiman

総合スコア7

ラジオボタン

ラジオボタンはフォームに使われる要素のひとつであり、ユーザに限られた選択肢からひとつの答えを選んでもらうというものです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/06/16 05:38

TodoリストのID番号の振り分け機能

JavascriptでTodoリストを作成している初学者です。
ラジオボタンで表示を切り替えても、ID番号を振り直されないようにしたい。
また、表示切り替え中のとき、タスクを追加した際に、作業中の中に追加していきたい

発生している問題

ラジオボタンを押し、"作業中"、"完了"のボタンを押し、表示を切り替える際、ID番号が振り直され連番に戻ってしまいます。
完成させたい機能は、"すべて"で振り当てられているID番号を維持したまま、表示切り替えを行いたいです。

また、"作業中"、"完了"を選択しているときに、新しいタスクを追加すると1度すべて表示されてしまいます。
もう1度ラジオボタンを押さないと表示が正常にならないです

該当のソースコード

html

1<!DOCTYPE html> 2<html lang="jp"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>js</title> 7</head> 8 9<body> 10 11 12 <h1>ToDoリスト</h1> 13 <p> 14 <input type="radio" name="list" value="all" id="radioAll" onchange="change()">すべて 15 <input type="radio" name="list" value="work" id="radioWork" onchange="change()">作業中 16 <input type="radio" name="list" value="done" id="radioDone" onchange="change()">完了 17 </p> 18 19 <table> 20 <thead> 21 <th>ID</th> 22 <th>コメント</th> 23 <th>状態</th> 24 <th></th> 25 </thead> 26 <tbody id="todo-body"> 27 </tbody> 28 </table> 29 30 31 <h2>新規タスクの追加</h2> 32 <input id="text" type="text"> 33 <button id='btn'>追加</button> 34 35 <script src="js/main.js"></script> 36 37 38</body> 39 40</html> 41

JavaScript

1'usestrict' 2 3{ 4 const tableBody = document.getElementById('todo-body') 5 const text = document.getElementById('text'); 6 const todos = []; 7 8 9 document.querySelector('button').addEventListener('click', () => { 10 const workBtn = document.createElement('button'); 11 const tableIds = todos.length; 12 workBtn.textContent = '作業中' 13 const todo = {}; 14 todo.taskId = tableIds; 15 todo.tableComment = text.value; 16 todo.tableStatus = workBtn; 17 change(); 18 19 20 21 workBtn.addEventListener('click', () => { 22 if (workBtn.textContent === '作業中') { 23 workBtn.textContent = '完了' 24 } else { 25 workBtn.textContent = '作業中' 26 }; 27 return workBtn; 28 }) 29 30 31 createRemoveButton = (tableRecord) => { 32 const number = tableRecord.rowIndex - 1; 33 const removeBtn = document.createElement('button'); 34 removeBtn.textContent = '削除' 35 36 removeBtn.addEventListener('click', () => { 37 todos.splice(number, 1); 38 showTodos(); 39 }) 40 41 return removeBtn; 42 }; 43 44 if (todo) { 45 todos.push(todo); 46 text.value = ''; 47 showTodos(todos); 48 } 49 }); 50 51 52 53 const showTodos = (argTodos) => { 54 tableBody.textContent = ''; 55 argTodos.forEach((todo, number) => { 56 const tableRecord = document.createElement('tr'); 57 tableBody.appendChild(tableRecord); 58 const tableId = document.createElement('td'); 59 const comment = document.createElement('td'); 60 const status = document.createElement('td'); 61 const action = document.createElement('td'); 62 63 tableId.textContent = number; 64 comment.textContent = todo.tableComment; 65 const work = todo.tableStatus 66 tableRecord.appendChild(tableId); 67 tableRecord.appendChild(comment); 68 tableRecord.appendChild(status); 69 status.appendChild(work); 70 tableRecord.appendChild(action); 71 action.appendChild(createRemoveButton(tableRecord)); 72 73 }); 74 }; 75 76 77 function change() { 78 const radioAll = document.getElementById('radioAll'); 79 const radioWork = document.getElementById('radioWork'); 80 const radioDone = document.getElementById('radioDone'); 81 82 if (radioAll.checked) { 83 return showTodos(todos); 84 } else if (radioWork.checked) { 85 const todoWork = todos.filter((todo) => { 86 return todo.tableStatus.textContent === '作業中' 87 }) 88 return showTodos(todoWork); 89 } else if (radioDone.checked) { 90 const todoDone = todos.filter((todo) => { 91 return todo.tableStatus.textContent === '完了' 92 }) 93 return showTodos(todoDone); 94 } 95 } 96 97 98} 99 100

試したこと

document.querySelector('button').addEventListener('click', () => { const workBtn = document.createElement('button'); const tableIds = todos.length; workBtn.textContent = '作業中' const todo = {}; todo.taskId = tableIds; todo.tableComment = text.value; todo.tableStatus = workBtn; change();

表示切り替え中にタスク追加したときにすべて表示されてしまうことについては、ここにchange()を書くのかなと思い試したのですが、エラーも出ませんが、結果も変わりませんでした。

IDについては、lengthで表示すればいいのかなと考え色々試したのですが、うまくいかずforEachの中で書いて連番でとりあえず表示している状況です、、、

よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ラジオボタンで表示を切り替えても、ID番号を振り直されないようにしたい。

idのテキストに対して、表示すべき内容が間違っています。
現在表示しようとしているのは、リストのIndexを表示してしまっているため、todosで管理しているtaskたちのID番号が振り直されているわけではありません。
正しくtodoのIDを表示するようにしてあげれば、解決できるかと思います。

javascript

1 const showTodos = (argTodos) => { 2 tableBody.textContent = ''; 3 argTodos.forEach((todo, number) => { 4 5 // ... 6 7 tableId.textContent = number; // ここが間違っています 8 }); 9 };

表示切り替え中のとき、タスクを追加した際に、作業中の中に追加していきたい

change()を呼ぶ箇所が間違っているので、変更してみてください。

javascript

1 document.querySelector('button').addEventListener('click', () => { 2 const workBtn = document.createElement('button'); 3 const tableIds = todos.length; 4 workBtn.textContent = '作業中' 5 const todo = {}; 6 todo.taskId = tableIds; 7 todo.tableComment = text.value; 8 todo.tableStatus = workBtn; 9 change(); // ここではない

投稿2021/06/16 08:47

yoshihiko555

総合スコア84

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukiman

2021/06/17 03:06

change() 場所をことで実装できました!ありがとうございます。 ID番号なのですが ``` argTodos.forEach((todo, length) => { tableId.textContent = length; ``` で書いてみたのですが、すべてのID番号が同じになり、数が増えていく流れになってしまいました。 どのようにかけば一つ一つにlengthをもたせて書くことができるのでしょうか。 また、削除ボタンを押すとすべてのタスクが消え argTodos.forEach((todo, length) => {}について Uncaught ReferenceError: forEach is not definedというエラーメッセージが出て来てしまうのですが、どういった理由からなのでしょうか。 もし回答いただけると嬉しいです。
yoshihiko555

2021/06/17 04:34

> すべてのID番号が同じになり、数が増えていく流れになってしまいました。 lengthを表示しているのであれば、0, 1, 2とIDが表示されるような気もしますが。。。 > どのようにかけば一つ一つにlengthをもたせて書くことができるのでしょうか。 lengthを持たせる必要はないかと思います。lengthの意味を今一度確認してみてください。 また、forEatchの仕組みも理解しておく必要があるかと思います。 argTodos.forEach((todo, length) => { // ... } ここで行っていることは、引数で渡されたargTodosを一つずつforで回しています。 forEatch((todo, length)のtodoには、argTodosで渡されたタスクの入り、lengthには、argTodosのIndexが入ってきます。 下記は、forEatchの例です。 const list = [ { id: 1, status: '作業中'}, { id: 2, status: '作業中'}, { id: 3, status: '作業中'}, ] このようなリストがあるとして、これをforEatchで回すと、 list.forEatch((todo, length) => { console.log(todo) // -> 1回目:{ id: 1, status: '作業中' } 2回目 : { id: 2, status: '作業中' } ... console.log(length) // -> 1回目 : 0 2回目 : 1 ... } このようになります。 正しいIDを表示するためには、繰り返しの処理で回ってきたtodoのIdを表示することで解決できるのではないでしょうか。 > 削除ボタンを押すとすべてのタスクが消え これは、argTodosがundefinedになっているからだと思います。 undefinedには、forEachメソッドなんてものは、存在しないので。 削除ボタンを押した際の処理でしっかりshowTodosにtodosを渡しているか確認してみてください。
yukiman

2021/06/17 05:31

ID,削除ボタン押したときの動きは実現できました!ありがとうございます! しかし、ラジオボタンで表示を切り替えたときにどうしても、IDが連番に振り直されてしまいます。 なぜなのでしょうか、、
yoshihiko555

2021/06/17 05:56

正しくコードを直しているのであれば、そこも解決してそうな気もしますが… 現状のソースコードを提示していただけますか
yukiman

2021/06/18 04:13 編集

'usestrict' { const tableBody = document.getElementById('todo-body') const text = document.getElementById('text'); const todos = []; document.querySelector('button').addEventListener('click',() => { const workBtn = document.createElement('button'); const tableIds = todos.length; workBtn.textContent = '作業中' const todo = { tableIds, tableComment:text.value, tableStatus:workBtn, }; workBtn.addEventListener('click', () => { if (workBtn.textContent === '作業中') { workBtn.textContent = '完了' } else { workBtn.textContent = '作業中' }; return workBtn; }) createRemoveButton = (tableRecord) => { const number = tableRecord.rowIndex - 1; const removeBtn = document.createElement('button'); removeBtn.textContent = '削除' removeBtn.addEventListener('click', () => { todos.splice(number, 1); showTodos(todos); }) return removeBtn; }; if (todo) { todos.push(todo); text.value = ''; showTodos(todos); change(); } }); const showTodos = (argTodos) => { tableBody.textContent = ''; argTodos.forEach((todo) => { const tableRecord = document.createElement('tr'); tableBody.appendChild(tableRecord); const tableId = document.createElement('td'); const comment = document.createElement('td'); const status = document.createElement('td'); const action = document.createElement('td'); tableId.textContent = todo.tableIds; comment.textContent = todo.tableComment; const work = todo.tableStatus tableRecord.appendChild(tableId); tableRecord.appendChild(comment); tableRecord.appendChild(status); status.appendChild(work); tableRecord.appendChild(action); action.appendChild(createRemoveButton(todo.tableIds)); }); }; function change() { const radioAll = document.getElementById('radioAll'); const radioWork = document.getElementById('radioWork'); const radioDone = document.getElementById('radioDone'); if (radioAll.checked) { return showTodos(todos); } else if (radioWork.checked) { const todoWork = todos.filter((todo) => { return todo.tableStatus.textContent === '作業中' }) return showTodos(todoWork); } else if (radioDone.checked) { const todoDone = todos.filter((todo) => { return todo.tableStatus.textContent === '完了' }) return showTodos(todoDone); } } } 修正いたしました!申し訳ありません。 分かりやすくありがとうございます しかし、削除したときでも番号を維持してしまい 今度は連番にならなくなってしまいます。 createRemoveButton内にどのように書けば解決できるのでしょうか、
yoshihiko555

2021/06/18 04:04

先述した通り、tableId.textContentに代入すべきものが間違っております。 todoのIdを代入すべきです。 また、lengthという変数名を使用しておりますが、その実体はargTodosのindexが入っています。 lengthというのは、あくまでリストの要素数を表しているので、変数名的にlengthを使用するのはあまりよろしくないでしょう。 const showTodos = (argTodos) => { tableBody.textContent = ''; argTodos.forEach((todo, length) => { // ... tableId.textContent = length; // ここはlengthではありません。 }); };
yukiman

2021/06/18 04:14

すみません! 先程とうこうした内容編集しましたので確認していただいてもよろしいでしょうか。
yukiman

2021/06/18 04:22

見づらくて申し訳ありません。
yoshihiko555

2021/06/18 04:29

> しかし、削除したときでも番号を維持してしまい 今度は連番にならなくなってしまいます。 基本的にIDというのは一意のものであるべきなので、削除時に採番しなおすというのはいかがなものかと思いますが。。。 例えば、タスクが1、2、3とあって、2のタスクを削除したときに、IDが1のタスクは1に、3のタスクは2になってしまった場合、後でタスク2の情報を取得したいとなったときに、元のIDが2のタスクを取得するべきなのか、現在のIDは2だけど、元のIDは3のタスクを取得するべきなのかってのがわからなくなってしまいます。 ※まぁそこはそのプログラムの仕様によるといったところにはなりますが。 前置きはおいといて、実装の仕方ですが 削除ボタンが押された時に、現時点でのtodosに対して、再度自動採番をしてあげる必要があるかと思います。 todosに対して、forEachなりで回してその際に、IDにIndexを割り当てればよいかと思います。
yukiman

2021/06/20 04:10

実装できました???? 丁寧な解説ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問