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

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

詳細はこちら
JavaScript

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

Q&A

解決済

2回答

880閲覧

フォームの表示非表示の切り替え

asako1010

総合スコア50

JavaScript

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

0グッド

1クリップ

投稿2019/12/14 17:22

編集2019/12/17 11:58

##質問の内容 課題内容
javaScriptでtodoListを作っています。
ラジオボタンには、すべて/作業中/完了の3つチェックボタンがあり、それぞれチェックするとそれに合った配列が表示される様な仕組みを作っています。チェックは1つしか選択できません。

現在、以下のコードでは「ラジオボタンの作業中を押したときに完了が消え、ラジオボタンの完了を押したときに作業中が消えるという仕組み」を作ろうとしています。

##試したこと
以下のコードの「button-done」「button-working」が間違っているというのは分かるのですが、どう書き換えればいいかが分かりりません。

//フォーム document.getElementById('button-done').style.display = ""; document.getElementById('button-working').style.display = "none"; } else if (radio[1].checked) { //フォーム document.getElementById('button-done').style.display = "none"; document.getElementById('button-working').style.display = ""; }

以下、現在のコードです。

<!DOCTYPE html> <html lang="ja"> ​ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>ToDoリスト</title> <link rel="stylesheet" href="css/style.css"> ​ </head> ​ <body> <h1>ToDoリスト</h1> ​ <div class="radiobutton"> <label for="button-1" ><input type="radio" id="button-1" name="radio1" value="1" checked="checked" />すべて</label> <label for="button-2"><input type="radio" id="button-done" name="radio1" value="2" onclick="entryChange1();" />完了中</label> <label for="button-3"><input type="radio" id="button-working" name="radio1" value="3" onclick="entryChange1();" />作業中</label> ​ <table> <thead> <tr> <th>ID</th> <th>コメント</th> <th>状態</th> </tr> </thead> <tbody id="idTbody"> </tbody> </table> ​ <h2>新規タスクの増加</h2> ​ <p id=id_p> <input type="text" id="id_text" value=""> <button id="btn" type="btn" class="button" value=""> 追加</button> </p> </div> ​ <script src="js/main.js"></script> </body> </html>
'use strict' let taskid = 0; //イベントリスナ―を登録 const add_btn = document.getElementById('btn'); add_btn.addEventListener('click', () => { const id_td = document.createElement("td"); id_td.textContent = taskid; const comment = document.getElementById("id_text").value; const commentEl = document.createElement("td"); commentEl.textContent = (comment); const createWorkingBtn = function () { //作業中ボタンを生成する処理 const workingBtn = document.createElement("button"); workingBtn.textContent = "作業中"; workingBtn.addEventListener('click', () => { console.log('表示を変更'); if (workingBtn.textContent === "作業中") { workingBtn.textContent = "完了"; } else { workingBtn.textContent = "作業中"; } }) //生成した作業中ボタンを返す処理 return workingBtn; } const workingBtn = createWorkingBtn(); const createDelBtn = function () { //削除ボタンを生成する処理 const delBtn = document.createElement("button"); delBtn.textContent = "削除"; delBtn.addEventListener('click', () => { idTbody.removeChild(trEl); }) //生成した削除ボタンを返す処理 return delBtn; } const delBtn = createDelBtn() const trEl = document.createElement("tr"); trEl.appendChild(id_td); trEl.appendChild(commentEl); trEl.appendChild(workingBtn); trEl.appendChild(delBtn); const todoEl = document.getElementById("idTbody"); todoEl.appendChild(trEl); taskid++; }, false); /*ラジオボタン作業中、完了を押下時の処理*/ function entryChange1() {   const radio = document.getElementsByName('radio1') if (radio[0].checked) { //フォーム document.getElementById('button-done').style.display = ""; document.getElementById('button-working').style.display = "none"; } else if (radio[1].checked) { //フォーム document.getElementById('button-done').style.display = "none"; document.getElementById('button-working').style.display = ""; } } //オンロードさせ、リロード時に選択を保持 window.onload = entryChange1;

##編集後のコード

<!DOCTYPE html> <html lang="ja"> ​ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>ToDoリスト</title> <link rel="stylesheet" href="css/style.css"> ​ </head> ​ <body> <h1>ToDoリスト</h1> ​ <div class="radiobutton"> <input type="radio" id="filter-all" name="radio1" value="1" checked="checked" /> <label for="filter-all">すべて</label> <input type="radio" id="filter-done" name="radio1" value="2" /> <label for="filter-done">完了中</label> <input type="radio" id="filter-working" name="radio1" value="3" /> <label for="filter-working">作業中</label> ​ <table> <thead id> <tr> <th>ID</th> <th>コメント</th> <th>状態</th> </tr> </thead> <tbody id="idTbody"> </tbody> </table> ​ <h2>新規タスクの増加</h2> ​ <p id=todo-form> <input type="text" id="todo-comment" value=""> <button id="btn" type="btn" class="button" value=""> 追加</button> </p> </div> ​ <script src="js/main.js"></script> </body> </html> ```  ```ここに言語を入力 'use strict' let taskid = 0; function entryChange() { radio = document.getElementsByName('radio1') //ラジオボタンの0(すべて)がチェックされたとき if (radio[0].checked) { document.getElementsByClassName('done').style.display = ""; document.getElementsByClassName('doing').style.display = ""; //ラジオボタンの1(完了)がチェックされたとき } else if (radio[1].checked) { //フォーム doing.forEach(done => { console.log(done); document.getElementsByClassName('done').styledisplay = ""; document.getElementsByClassName('doing').style.display = "none"; }) //ラジオボタンの2(作業中)がチェックされたとき } else if (radio[2].checked) { //フォーム doing.forEach(work => { console.log(work); document.getElementsByClassName('done').style.display = "none"; document.getElementsByClassName('doing').style.display = ""; }) } } //オンロードさせ、リロード時に選択を保持 window.onload = entryChange; //イベントリスナ―を登録 const add_btn = document.getElementById('btn'); add_btn.addEventListener('click', () => { const id_td = document.createElement("td"); id_td.textContent = taskid; const comment = document.getElementById("todo-comment").value; const commentEl = document.createElement("td"); commentEl.textContent = (comment); const createWorkingBtn = function () { //作業中ボタンを生成する処理 const workingBtn = document.createElement("button"); workingBtn.classList.add("doing"); workingBtn.textContent = "作業中"; workingBtn.addEventListener('click', () => { console.log('表示を変更'); if (workingBtn.textContent === "作業中") { workingBtn.classList.add("doing"); workingBtn.textContent = "完了"; // ボタン押下で生成されたdomの中の親要素へclassNameをつける処理 const doneParent = workingBtn.parentNode; doneParent.className = 'workDone'; } else { workingBtn.classList.add("done"); workingBtn.textContent = "作業中"; // ボタン押下で生成されたdomの中の親要素へclassNameをつける処理 const workParent = this.parentNode; workParent.className = 'work'; } }) //生成した作業中ボタンを返す処理 return workingBtn; } const workingBtn = createWorkingBtn(); const createDelBtn = function () { //削除ボタンを生成する処理 const delBtn = document.createElement("button"); delBtn.textContent = "削除"; delBtn.addEventListener('click', () => { idTbody.removeChild(trEl); }) //生成した削除ボタンを返す処理 return delBtn; } const delBtn = createDelBtn() const trEl = document.createElement("tr"); trEl.appendChild(id_td); trEl.appendChild(commentEl); trEl.appendChild(workingBtn); trEl.appendChild(delBtn); const todoEl = document.getElementById("idTbody"); todoEl.appendChild(trEl); taskid++; }, false);

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

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

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

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

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

guest

回答2

0

ベストアンサー

過去のご質問からも 徐々にTODOリストを形にしていることが伺えますが、正直、「仕様が纏まってないのではないか?」と思います。というのは、ご質問の本質であるイベントリスナを考える以前の問題として、正しいマークアップができていないからです。

  1. label 要素の for 属性を指定する時は 対応する input 要素の id と同じでなければならない(MDN label)。
  2. 各要素の id属性には 意味付けされた言葉が用いられておらず、可読性に欠けます(MDN セマンティクス)。

例えば、

  • button-1 / button-1 -> filter-all
  • button-2 / button-done -> filter-done
  • button-3 / button-working -> filter-working
  • idTbody -> todo-items
  • id_p -> todo-form
  • id_text -> todo-comment
  • btn -> todo-append

属性値だけでなく、Javascript の変数名や関数名にも命名規則を定めるように心がけないと、回答者は匙を投げることになりかねません。

ご質問のタイトル

フォームの表示非表示の切り替え

「フォーム」という言葉だけでは不明瞭に感じます。

現状、初期のご質問と比べても3つの「フォーム」があるはずです。

  1. 登録用
  2. 項目変更用(状態変更/削除)
  3. フィルタ用(再表示)

各フォームに、表示に対応した変化を期待する機能があると思いますが、機能に応じたイベントリスナを書く前に、考えることが 表示の方法と対応したデータ になります。

table を利用したデータの取り扱いにも、2つが考えられます。

  1. table 要素の属性だけで行う。
  2. 別途、javascript の Arrayで管理し、table 要素に差し込む。

「データの扱い方」を定めないと、作用するイベントリスナは構築できません。


回答は、「まずは正しいマークアップをしてください」ということになりますが、javascript 内で多用する document.getElementById() の代わりに CSSのセレクタで取得する方法があります。

  1. MDN querySelector()
  2. MDN querySelectorAll()

javascript 内で多用するからこそ、次のように短く書く例は役立つかもしれません。

javascript

1const qs = selector => document.querySelector(selector); 2const qsa = selector => document.querySelectorAll(selector); 3 4// document.querySelectorAll("input[name=radio1]") を短くできる 5let filterButtons = qsa("input[name=radio1]");

直接的な回答には至りませんが、参考になればと思います。

投稿2019/12/15 11:53

編集2019/12/15 12:16
AkitoshiManabe

総合スコア5434

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

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

asako1010

2019/12/15 12:53

ありがとうございます。 可読性については全く意識していませんでした。 気をつけます。 マークアップから勉強し直します。
guest

0

'use strict'を使うなら宣言していない変数を使わない。

JavaScript

1// radio = document.getElementsByName('radio1') 2// ↓ 3 const radio = document.getElementsByName('radio1') 4```**動くサンプル:**[https://jsfiddle.net/n65jbs92/](https://jsfiddle.net/n65jbs92/) 5 6【【初心者向け】コンソールによるJavascriptのエラー表示方法】 7[https://eng-entrance.com/javascript-display-error](https://eng-entrance.com/javascript-display-error)

投稿2019/12/14 18:19

kei344

総合スコア69596

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

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

asako1010

2019/12/14 18:35

ありがとうございます。 ご指摘いただいたか所は修正しました。
kei344

2019/12/14 18:43

radioに何個のラジオボタンが入っているかを調べてみましょう。
asako1010

2019/12/15 04:51

「すべて」「作業中」「完了」の3つ入っております。
kei344

2019/12/15 09:34

では関数entryChange1ではその3つの状態を確認して、表示非表示を切り替えるべきでは?
asako1010

2019/12/15 09:44

コメントありがとうございます。 「確認」というのはどういう意味でしょうか? 飲み込み悪く、すみません。
kei344

2019/12/15 10:06

if (radio[0].checked) {} else if (radio[1].checked) {} と、2要素しか見ていない。ラジオボタンは3つ。
asako1010

2019/12/15 12:53

「すべて」についても見るということですね。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問