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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

2951閲覧

バリデーションが上手くいかない。

aaaaaaaa

総合スコア501

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2017/02/17 10:43

編集2017/02/24 04:11

ブレイクスルーjavascript(SHOEISYA)の22pから32pに記述してある、フォームに書き込まれた内容を即時に検証(文字数や適切な単語が利用されているかなど)でき、
何か問題があれば注意が表示される機能を実際に作るという内容に疑問があったので質問します。
実際に作ってみたものの、動作しません。javascriptソースを確認してみるといくつか誤植があったので修正してみたのですが、それでも動きませんでした。
フォームに文字を入力し、それに何かしらの間違い(文字数が8文字以内かつ、4文字以上、必須項目)を犯せば注意が表示される仕組みなのですが、
その注意が表示されないのです。

javascript

1function AppModel(attrs) { 2 this.val =""; 3 //使用するvalidation patternを設定するオブジェクトを追加する。 4 this.attrs = { 5 required: "",//値が空かどうかを調べるrequiredメソッド。 6 maxlength: 8, 7 minlength: 4 8 }; 9 10 this.listeners = { 11 valid: [],//valid…正当な、有効な 12 invalid: []//invalid…病人 13 }; 14} 15//AppModelのプロトタイプたち。つまりインスタンスに継承させたいものだ。 16 17//this.valの値が正しいのかどうかを調べるvalidateメソッド。 18AppModel.prototype.validate = function() { 19 var val; 20 //バリデーションでエラーが出たものを保存しておくための空の配列 21 this.errors = []; 22 23 for(var key in this.attrs) { 24 val = this.attrs[key]; 25 if(!this[key](val)) this.errors.push(key); 26 } 27 this.trigger(!this.errors.length ? "valid" : "invalid"); 28}; 29 30//第一引数に配列の添え字、第二引数に第一引数を処理する関数を指定した。 31AppModel.prototype.on = function(event, func) { 32 //AppModelがもつ連想配列listeners内の、eventという添え字を持つモノ(恐らく配列だろうが、いまのところeventを添え字に持つ配列は、見当たらない。)の末尾にfuncという関数を挿入している。 33 this.listeners[event].push(func); 34}; 35 36AppModel.prototype.trigger = function(event) { 37 $.each(this.listeners[event], function() { 38 //コンストラクター内でのthisは、インスタンスを表すので、this()は、AppModel()なのか? 39 //▼このthis()の意味は良くわからない。(1/27) 40 this(); 41 }); 42}; 43//恐らくセッター。受け取ったvalが、AppModelのthis.valと一致すれば処理を行わない。一致しなければ、this.valに引数を代入する。 44AppModel.prototype.set = function(val) { 45 if(this.val === val) return; 46 this.val = val; 47 this.validate(); 48}; 49 50//値が空かどうかを判定するrequiredメソッド。 51AppModel.prototype.required = function() { 52 return this.val !== ""; 53}; 54//値の文字数が引数のnum以上かどうかを判定するmaxlengthメソッド。 55AppModel.prototype.maxlength = function(num) { 56 return num >= this.val.length; 57}; 58//値の文字数が引数num以下かどうかを判定するminlengthメソッド。 59AppModel.prototype.minlength = function(num) { 60 return num <= this.val.length; 61}; 62 63 64function AppView(el) { 65 66 this.initialize(el); 67 //インスタンス化したとき、handleEventsメソッドを実行するようにしている。 68 this.handleEvents(); 69} 70 71AppView.prototype.initialize = function(el) { 72 this.$el = $(el); 73 74 //this.$elの隣のliをthis.$listに代入する。 75 this.$list = this.$el.next().children(); 76 77 var obj = this.$el.data(); 78 79 if(this.$el.prop("required")) { 80 obj["required"] = ""; 81 } 82 83 this.model = new AppModel(obj); 84}; 85 86AppView.prototype.handleEvents = function() { 87 var self = this; 88 //handleEventsメソッドでは、keyupイベントのイベントハンドラにonKeyupを登録する。 89 this.$el.on("keyup", function(e) { 90 self.onKeyup(e); 91 }); 92 93 this.model.on("valid", function() { 94 self.onValid(); 95 }); 96 97 this.model.on("invalid", function() { 98 self.onInvalid(); 99 }); 100}; 101//keyupイベントが発生した時に実行されるonKeyupメソッドを実装する。 102AppView.prototype.onKeyup = function(e) { 103 var $taget = $(e.currentTarget); 104 //this.modelのsetメソッドを使用して、inputの値をmodelにセットする。$target.valのvalは、requiredやmaxlengthか? 105 this.model.set($target.val()); 106}; 107 108//this.$elのclass="error"を消し、this.$listを非表示にする。 109AppView.prototype.onValid = function() { 110 this.$el.removeClass("error"); 111 this.$list.hide(); 112}; 113 114//そしてthis.$elにclass="error"を付与し、this.$listの中で該当エラーのみ表示する。 115AppView.prototype.onInvalid = function() { 116 var self =this; 117 this.$el.addClass("error"); 118 this.$list.hide(); 119 120 $.each(this.model.errors, function(index, val) { 121 self.$list.filter("[data-error=\"" + val + "\"]").show(); 122 }); 123}; 124//inputを引数で指定した関数で、個別に処理する。 125$("input").each(function() { 126 new AppView(this); 127});

html

1<div class="container"> 2 <div class="row"> 3 <div class="col"> 4 <label for="">権限を作成</label> 5 </div> 6 <div class="col"> 7 <input type="text" placeholder="4文字以上、8文字以内で入力して下さい" data-minlength="4" data-maxlength="8" required><!-- requiredは、フォームへの入力や洗濯を必須とする。 --> 8 <ul> 9 <li data-error="required">必須項目です。</li> 10 <li data-error="minlength">4文字以上で入力して下さい。</li> 11 <li data-error="maxlength">8文字以内で入力して下さい。</li> 12 </ul> 13 </div> 14 </div><!-- row --> 15 <div class="row"> 16 <div class="col"> 17 <label for="">権限を作成</label> 18 </div> 19 <div class="col"> 20 <input type="text" placeholder="4文字以上、8文字以内で入力して下さい" data-minlength="4" data-maxlength="8" required> 21 <ul> 22 <li data-error="required">必須項目です。</li> 23 <li data-error="minlength">4文字以上で入力して下さい。</li> 24 <li data-error="maxlength">8文字以内で入力して下さい。</li> 25 </ul> 26 </div> 27 </div><!-- row --> 28</div><!-- container -->

問題のソースコード
http://jsdo.it/rrrrrrrr/e5jz

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

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

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

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

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

ikedas

2017/02/18 02:38

外部のサイトに置いたソースコードはそのうち消えるかもしれません。後で質問を読む人には意味不明になってしまうので、ソースコードも質問の中に書いて下さい。コードを整形する方法はヘルプ https://teratail.com/help を見て下さい。
aaaaaaaa

2017/02/24 04:11

ご返答有難うございました。ソースコードを追記しました。
guest

回答2

0

ベストアンサー

修正箇所

元の書籍のコードと解説がわかりませんが下記の場所を修正してください。
modelへのハンドラ設定の方法(A)と(B)

  • AppView.prototype.handleEvents

javascript

1AppView.prototype.handleEvents = function() { 2 var self = this; 3 4 this.$el.on("keyup", function(e) { 5 self.onKeyup(e); 6 }); 7 8 // (A) model.listeners.valid にハンドラを登録する 9 this.model.listeners.valid.push(function() { 10 self.onValid(); 11 }); 12 13 // (B) model.listeners.invalid にハンドラを登録する 14 this.model.listeners.invalid.push(function() { 15 self.onInvalid(); 16 }); 17};
  • AppView.prototype.onKeyup

質問内のコードでは、以下のvar $tagetvar $targetのタイプミスだと思います。

javascript

1AppView.prototype.onKeyup = function(e) { 2 var $taget = $(e.currentTarget); 3 // イベントを発生させたターゲットの値なので入力されている現在の値がval()です 4 this.model.set($target.val()); 5};

説明

下記の部分のAppModel.prototype.triggerについて補足説明します。

javascript

1AppModel.prototype.validate = function() { 2 var val; 3 //バリデーションでエラーが出たものを保存しておくための空の配列 4 this.errors = []; 5 6 for(var key in this.attrs) { 7 val = this.attrs[key]; 8 if(!this[key](val)) this.errors.push(key); 9 } 10 11 // エラーの有無により、"valid"か、"invalid"の文字列を引数にしてtriggerを呼び出す 12 this.trigger(!this.errors.length ? "valid" : "invalid"); 13}; 14 15AppModel.prototype.trigger = function(event) { 16 $.each(this.listeners[event], function() { 17 this(); 18 }); 19};

listenersはobject型なので[event]は、プロパティへのアクセスとなります。
eventの値が"valid"だとすると、this.listeners.validと等価です。
this.listeners.validは配列なので、$.eachで一つづつ処理されます。
この配列の要素は、handleEventsで登録した(A)や(B)のハンドラで、そのまま呼び出せるので、this()となります。

このAppModel.prototype.triggerの処理から、修正箇所としてハンドラの設定方法を修正しています。

  • jqueryの取り込みは下記の方法で行い、実行できることを確認しました。

HTML

1... 2<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> 3...

投稿2017/02/24 14:21

StupidDog

総合スコア263

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

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

aaaaaaaa

2017/03/01 10:36

ご回答有難うございます。詳細な回答で大変参考になりました。 jqueryを取り込んで、誤記である$tagetを$targetにしたところjsdoで無事動作したことを確認しました。ベストアンサーを押したいところですが、一つ質問させてください。 全く同じソースをローカルホスト(windows7sp1 xampp1.0.0.0 IE11とchrome56.0.2924.87)で試すと全く動作しないのです。ローカルホストのapp.jsには、回答を基に修正したjsdoitと同等のソースと、同じく回答を基に、AppView.prototype.handleEventsメソッドも修正したソースがあるのですが、どちらも動作せず、表示させたい文言が現れません。 別の回答にてIE11の開発者ツールでエラーが出ない原因としてjavascriptに関する設定が原因であるとの旨がありました。おそらくPCの内部的な事情で上手くいかないのだと思うのです。 唯一の手がかりは、クロームの開発者ツールでコンソール画面をみてみると GET http://localhost/image/error.png 404 (Not Found) (anonymous) @ jquery-1.11.1.min.js:2 j @ jquery-1.11.1.min.js:2 fireWith @ jquery-1.11.1.min.js:2 ready @ jquery-1.11.1.min.js:2 J @ jquery-1.11.1.min.js:2 と表示されていました。code.jquery.com/jquery-1.11.1.min.jsは、存在しているのですが何が原因でこうなってしまうのでしょうか。
StupidDog

2017/03/01 16:40 編集

app.jsを<head>内で読み込んでいますが、このタイミングではinput要素がまだ生成されていないので要素とコードが関連付きません。 jsdo.itでjavascript枠に入力したコードは内部で<body>の最後に呼ばれるようになっているので上手く動作します。 対応するには、input要素が生成された後にイベントを関連付けします。 (1) app.js側で対応するならばreadyイベントで実行されるようにします。 ----------javascript : app.js // あまり短縮しないで書いた場合 $(document).ready(function() { $("input").each(function() { new AppView(this); }); }); ---------- (2) html側で対応するならば<head>内からapp.jsの読み込み部分を<body>の末尾へ移動します。 ---------- html : index.html ... <script type="text/javascript" src="./app.js"></script> </body> </html> ---------- コメント欄だとコードが装飾できないようなので少し見辛いです・・・
aaaaaaaa

2017/03/02 10:37

ご回答有難うございます。仰るとおりにbody最下部においてファイル読み込みをしたところ、ローカルホスト側でも無事うまくいきました。 >>app.jsを<head>内で読み込んでいますが、このタイミングではinput要素がまだ生成されていないので要素とコードが関連付きません。 「どこで知った?」と言われると答えに窮してしまい申し訳ありませんが、今までの認識だと、<head>内で記述した<script src="./a.js">は、<body>配下より先に読み込まれるので問題なく動作するものだと思っておったのです。が、どうも何かと勘違いしているようですが、何と勘違いしているのでしょうか。 >>jsdo.itでjavascript枠に入力したコードは内部で<body>の最後に呼ばれるようになっているので上手く動作します。 なるほど、そのような仕様になっているのですね。とても勉強になります。 >>(1)app.hs側で...のソースは、$(function() {...});と同じもので、画像を除いたすべてのDOMが読み込まれてから…というものでしょうか。ソースを提示して下さるまで忘れてました。情けない限りです。
StupidDog

2017/03/02 16:06

最近のteratailの質問で以下のようなものがあります。 ・scriptタグはなんで通常bodyに書くのか https://teratail.com/questions/67208 回答がいっぱいで色々理由があるのかなぁと。 SEOとかは除いて、コードについて考えると、 1. 使う前に関数・変数が定義・宣言されている事 2. 扱う対象(DOM)が扱う時に存在している事 を意識すればよいと思います。 昔、<head>内の<script>が多かったのは、jQueryのようにDOMを検索して編集するのではなく、<xxx onClick="abc();">のようにイベントのハンドラなどを属性へ直接記述していたからかも、、、でも真相はわかりません。 この場合は、abc()がxxxタグより前で定義されている必要があります。
guest

0

$ が定義されていないから。エラー文が出ていると思いますよ。

デベロッパーツールで確認してみてください。⇒ http://eng-entrance.com/javascript-display-error

投稿2017/02/24 07:53

kei344

総合スコア69364

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

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

aaaaaaaa

2017/02/24 10:33

ご回答有難うございます。 このような作業を行うときは、できるだけF12で表示される開発者ツールを表示するようにしているのですが、特にエラーはでていませんでした。以下の画面は、動作しないバリデーデーションプログラムを開発者ツールで見てみたものです。もちろんF5を押したあとの画面になっています。 http://fast-uploader.com/file/7043487567797/ >>$ つまりJquery本体のファイルが必要だということですよね。以下のように、グーグル、本家、ダウンロードしたjqueryファイルから呼び出して使ってみたのですが、結局動作しませんでした。 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> <script type="text/javascript" src"./jquery-1.11.1.js"></script>
kei344

2017/02/24 11:55

http://jsdo.it/rrrrrrrr/e5jz をWin7 IE11 で開き、jsdo.itの再生ボタンを押すことで開発者ツールにてエラーを確認しました。 IEでローカルのJavaScriptを実行しようとすると、セキュリティの設定次第だと思いますが実行されないことがあったように記憶しています。なので、スクリプトの実行テスト(勉強)は Firefox がお勧めです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問