🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

ラジオボタン

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

JavaScript

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1004閲覧

ラジオボタンを使いタスクの表示切替をしたい。

F_Yohei

総合スコア14

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

ラジオボタン

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

JavaScript

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/12/05 11:47

###前提・実現したいこと
イメージ説明
それぞれ「すべて」 「作業中」 「完了」 とラベルがついたラジオボタンを準備し、作業中のラジオボタンを押下すると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()を使った場合、新しい配列が作成されることにより添字の番号も変わってしまうことも問題です。

ご教授いただければ幸いです。
よろしくお願いします????‍♂️

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

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

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

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

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

guest

回答1

0

ベストアンサー

完全な回答とは言えない、指針程度の内容ですが、ご容赦ください。

todos配列がデータベース的な存在だと思いますが、
ここへ格納するオブジェクトに、idプロパティが無い
というのが痛いです。
TODOを一意に識別するための情報なので、
ぜひともidプロパティが欲しいです。

そのためには、新規TODO追加時にIDを決める必要があります。
addTaskButtonclickイベントハンドラの中です。
そこで、一意なIDを採番しましょう。

例えば…

javascript

1// 最初の方で… 2const todos = []; 3let last_id = 0; // ID用の連番 4... 5 6// `click`イベントハンドラ内で… 7const todoInput = { task: textBox.value, state: '作業中' }; 8last_id++; 9todoInput.id = last_id; 10...

一方、画面に表示するTODOリスト用のtr要素を作るときにも
ID情報を持たせておくと何かと便利です。

javascript

1// addTask()の中で… 2const tr = document.createElement('tr'); 3tr.setAttribute('data-id', todo.id); // ←ここ 4todoList.appendChild(tr);

そうすると、あとは、
filter()で抽出されたTODO一覧に応じて、
tr要素の可視・不可視を切り替えれば良いですね。

javascript

1// 抽出処理のところで… 2let selectedIds = filter.map((todo)=>todo.id); 3document.querySelectorAll('#todoList tr[data-id]').forEach((tr)=>{ 4 tr.style.display = selectedIds.includes(parseInt(tr.getAttribute('data-id'))) ? 'table-row' : 'none'; 5});

※なお、この方針を採用する場合、削除ボタンや作業中ボタンのクリック時の処理なども修正が必要です。

投稿2020/12/05 15:42

gpsoft

総合スコア1323

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

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

F_Yohei

2020/12/05 23:33

回答いただきありがとうございます???? 早速教えていただいたことを試してみます(^^)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問