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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

1147閲覧

input(テキスト欄)が空欄の時、submitボタンを押すと、2度目以降エラーメッセージが重複して表示されてしまう。

k373

総合スコア17

JavaScript

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2018/09/27 12:27

編集2018/09/27 12:28

前提・実現したいこと

フォームの作成をしております。(TODOリストの作成を想定)
テキストボックスが空欄の時、submitボタンを押すと、その下に「タスクを入力してください」とエラーメッセージを表示します。
再度空欄のままsubmitボタンを押すと、エラーメッセージが同じように表示されるようにしたいです。(重複なし)
空欄を埋め、再度submitボタンを押すと、エラーメッセージが消え、テキストボックスの内容がリスト表示として追加されるようにしたいです。

発生している問題・エラーメッセージ

一度テキストボックスを空欄にしたまま、submitボタンを押すと、エラーメッセージが表示されます。
その後、再度空欄でsubmitボタンを押すと、2個目の同じエラーメッセージが表示されてしまします。(3回目以降も追加されていき、重複し続けます。)
また、その後に空欄を埋め、submitボタンを押すとテキストボックスの内容がリスト表示として追加されますが、エラーメッセージは消えません。

該当のソースコード

html

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="utf-8"> 6 <title>TODOリスト</title> 7 <link rel="stylesheet" href="css/style.css" type="text/css"> 8 <script src="js/todo.js" charset="utf-8"></script> 9</head> 10 11<body> 12 13 <div class="container"> 14 15 <form action="" method="" id="form"> 16 17 <div id="task-wrap"> 18 <label for="task">内容</label> 19 <input type="text" id="task" value=""><br> 20 </div> 21 22 <input type="button" id="add" value="追加"><br> 23 24 </form> 25 26 <ul id="result"></ul> 27 28 </div> 29 30</body> 31 32</html>

javascript

1(window.onload = function() { 2 'use strict'; 3 4 const add = document.getElementById("add"); 5 const task = document.getElementById("task"); 6 const taskWrap = document.getElementById("task-wrap"); 7 const result = document.getElementById("result"); 8 9 add.addEventListener("click", function(){ 10 if(task.value === ""){ 11 const error = document.createElement('div'); 12 error.className = "error"; 13 error.innerHTML = "タスクを入力してください"; 14 taskWrap.appendChild(error); 15 }else{ 16 const newTask = document.createElement("li"); 17 newTask.className = "newtask"; 18 newTask.textContent = task.value; 19 result.appendChild(newTask); 20 } 21 task.value = ""; 22 }, false); 23 24})();

試したこと

javascript

1(window.onload = function() { 2 'use strict'; 3 4 const add = document.getElementById("add"); 5 const task = document.getElementById("task"); 6 const taskWrap = document.getElementById("task-wrap"); 7 const result = document.getElementById("result"); 8 9 add.addEventListener("click", function(){ 10 if(task.value === ""){ 11 taskWrap.removeChild(error); 12 const error = document.createElement('div'); 13 error.className = "error"; 14 error.innerHTML = "タスクを入力してください"; 15 taskWrap.appendChild(error); 16 }else{ 17 taskWrap.removeChild(error); 18 const newTask = document.createElement("li"); 19 newTask.className = "newtask"; 20 newTask.textContent = task.value; 21 result.appendChild(newTask); 22 } 23 task.value = ""; 24 }, false); 25 26})();

以上を試した結果、Uncaught ReferenceError: error is not defined at HTMLInputElement.<anonymous>という エラーが以下の最後の行に返ってきました。

javascript

1add.addEventListener("click", function(){ 2 if(task.value === ""){ 3 taskWrap.removeChild(error);

以上、どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

click時のイベントの冒頭でclassNameをerror指定で削除すればいいだけだと思います。
「試したこと」だと定義前の変数を使っているから出るエラーです。
イベント内でconstで定義しているのでそこから外では使えませんし、
もちろん定義前にも使えません。何も入っていません。

ここは考え方1つだと思うのですが、
「add」ボタンをクリックしたときにバリデーションが走るのですから、
そもそもどのerrorも残っていてはいけません。
なので、やるべきは「ここの入力コントロールの子要素のエラー表示を削除」ではなく、「全てのエラー表示を削除」です。
errorというクラスを指定するルールなのであれば、そのクラス名を指定して全て削除すれば良いです。

投稿2018/09/27 12:39

m.ts10806

総合スコア80850

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

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

k373

2018/09/27 13:00

ご回答ありがとうございます。 いただきましたご回答の理論は非常に説得力のあるものです。 以下のように、クリック時にクラス名errorのものを取得し、非表示にするというコードを実行したのですが、Cannot set property 'display' of undefined at HTMLInputElement.とのエラーが返ってきてしまします。 add.addEventListener("click", function(){ document.getElementsByClassName("error").style.display ="none"; if(task.value === ""){ すみませんが、ご教示いただけますでしょうか。 よろしくお願いいたします。
m.ts10806

2018/09/27 13:03

最初は存在しないエレメントからいきなりstyleを参照しようとしたらそうなりますよ。 それと「非表示」ではなく「削除」でないと意味がありません。
k373

2018/09/27 13:32 編集

ご回答ありがとうございます。 なるほど。styleの件、理解いたしました。 add.addEventListener("click", function(){ const hide = document.getElementsByClassName("error"); document.body.removeChild(hide); このように対処してみました。以下のエラーが返ってきました。 parameter 1 is not of type 'Node' Nodeについて調べましたが、"document.getElementByIdで取得した要素のオブジェクトは、HTMLElementという種類のノードだということです。"と書かれており、どこがNodeではないのか理解できませんでした。 度々すみませんが、よろしくお願いいたします。
k373

2018/09/27 13:39

以下のコードだと、一度だけボタンをクリックすると正常に動きましたが、2度目から以下のエラーが出てしましました。 The node to be removed is not a child of this node. add.addEventListener("click", function(){ const hide = document.getElementsByClassName("error"); for (var i = 0; i < hide.length; i++) { document.body.removeChild(hide[i]); }
m.ts10806

2018/09/27 13:41

getElement”s" なので個数分の配列になります。 https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByClassName >elementsは、見つかった要素のライブな【訳注: 現状の情報とリンクした】HTMLCollection です。要素は、それらがその文書ツリーに現れる順番に得られます。 つまり、HTMLCollection が返ってきます。 forで回して1つ1つremoveしてください。 あと、エレメント自体を特定できているのでいちいちremoveChildeで辿る必要もありません。 例:※hideという変数名も適切ではありませんね ※未検証。実装イメージのみ参考にしてください const error_elements = document.getElementsByClassName("error"); for(i = 0;i<error_elements.length;i++){ error_elements[i].remove(); }
m.ts10806

2018/09/27 13:42

エラーメッセージが出たならエラーメッセージで調べてください。 ちょっと丸投げが過ぎませんかね。
m.ts10806

2018/09/27 13:43

デバッグもしてください。console.log()は分かりますか?
k373

2018/09/27 13:55

ご回答ありがとうございます。 HTMLCollectionの内容は、検索で知り、理解できました。 getElemetByIdとは返ってくるものが違うということですね。 ご回答いただきましたコードで問題なく解決できました。 エラーメッセージにつきましても、まだまだ勉強不足のため、調べはするのですが理解できず、申し訳ありませんでした。次回より、より深く英文等も理解いくまで読み込むようにします。 デバッグに関しては、できておらず申し訳ありませんでした。console.log();はわかりますが、デバッグの使い方を勉強し、今後のプログラミング学習に努めます。 色々とご丁寧にご指摘、アドバイスありがとうございました。 精進します。
m.ts10806

2018/09/27 13:58

若干乱雑にコメントしてしまったこと、失礼しました。 プログラミングは問題解決のためにあるのが根底だと思います。 「デバッグ」は自身に起きている問題を解決するための糸口となります。 必ず覚えてください。Hello Worldの次に覚えるべきことと言っても過言ではありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問