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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

4回答

2899閲覧

jquery:増殖したフォーム内のonchangeが効かない

squirrel

総合スコア18

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2017/06/01 03:20

下記のjqueryスニペットに機能追加して、増殖フォームを作成しています。
http://code.runnable.com/VZtbYFWhaIY5zFL-/add-remove-form-elements-dynamically-%5Bjquery-javascript%5D

追加機能は、
始めから表示されているフォームブロックを増やし、radio buttonの代わりにtext, checkbox, select要素を追加して、selectのonchangeをトリガーに、その値によって当該フォーム内のtextareaを表示/非表示にする

というものですが、なぜか増殖したフォームだけselectで値を変えてもなにも反応してくれません。
conlose.logでデバッグしたところ、$('select').change() で出力してるものが何も出力されていないので、clone時に問題がありそうですが、あまり詳しくないため勘所もなく手詰まりになっています。

そもそもこのスニペットを使用しての実現は難しいのかどうかなども含めてアドバイス頂けたら幸いです。
よろしくお願いします。

javascript

1$(function () { 2 3 var frm_cnt = 1; 4 5 // [Default表示]プルダウンの値に合わせて選択肢テキストエリアの表示非表示をする 6 for(var i=0; i<=frm_cnt; i++) { 7 var val = $("[id=dish_type\\["+ i +"\\]]").val(); 8 9 if(val == 3 || val == 4 || val == 5) { 10 $('#memos' + i).css('display', 'block'); 11 } 12 else { 13 $('#memos' + i).css('display', 'none'); 14 } 15 } 16 17 // [+]ボタンクリックされた際のアクション 18 $(document).on('click', '.add', function(){ 19 var original = $('#form_block\\[' + frm_cnt + '\\]'); 20 var originCnt = frm_cnt; 21 var originVal = $("input[name='attend\\[" + frm_cnt + "\\]']:checked").val(); 22 23 frm_cnt++; 24 25 $original 26 .clone() 27 .hide() 28 .insertAfter($original) 29 .attr('id', 'form_block[' + frm_cnt + ']') // クローンのid属性を変更。 30 .find("input[type='checkbox'][checked]").prop('checked', true) 31 32 // textareaのdivブロック用追記 33 .attr('id', 'memos' + frm_cnt) 34 35 .end() // 一度適用する 36 .find(':input').each(function(idx, obj) { 37 $(obj).attr({ 38 id: $(obj).attr('id').replace(/\[[0-9]+\]+$/, '[' + frm_cnt + ']'), 39 name: $(obj).attr('name').replace(/\[[0-9]+\]+$/, '[' + frm_cnt + ']') 40 }); 41 42 var $type = obj.type || obj.tagName.toLowerCase(); // form element typeの取得 43 44 //テキストとテキストエリアの中身をクリアにする 45 if ($type == 'text') { 46 $(obj).val(''); 47 } 48 else if($type == 'textarea'){ 49 $(obj).val(''); 50 } 51 }); 52 53 // clone取得 54 var clone = $('#form_block\\[' + frm_cnt + '\\]'); 55 clone.children('span.close').show(); 56 57 clone.slideDown('slow'); 58 59 // originalチェックボックス復元 60 $original.find("input[name='attend\\[" + originCnt + "\\]'][value='" + originVal + "']").prop('checked', true); 61 }); 62 63 $(document).on('click', '.close', function(){ 64 var removeObj = $(this).parent(); 65 removeObj.fadeOut('fast', function() { 66 removeObj.remove(); 67 // 番号振り直し 68 frm_cnt = 0; 69 $(".form-block[id^='form_block']").each(function(index, formObj) { 70 if ($(formObj).attr('id') != 'form_block[0]') { 71 frm_cnt++; 72 $(formObj) 73 .attr('id', 'form_block[' + frm_cnt + ']') // id属性を変更。 74 .find(':input').each(function(idx, obj) { 75 $(obj).attr({ 76 id: $(obj).attr('id').replace(/\[[0-9]+\]+$/, '[' + frm_cnt + ']'), 77 name: $(obj).attr('name').replace(/\[[0-9]+\]+$/, '[' + frm_cnt + ']') 78 }); 79 }); 80 } 81 }); 82 }); 83 }); 84 85 // selectorのvalueによってフォーム内容を変える 86 $('select').change(function() { 87 //idや値を変数に格納 88 var id = $(this).attr('id'); 89 var val = $(this).val(); 90 var num = id.match(/\[([0-9]+)\]+$/)[1]; 91 92 console.log(id + '=' + val); 93 console.log(num); 94 95 //選択したvalue値をp要素に出力 96 if(val == 3 || val == 4 || val == 5) { 97 $('#memos' + num).css('display', 'block'); 98 } 99 else { 100 $('#memos' + num).css('display', 'none'); 101 } 102 }); 103});

HTML

1<form action="/confirm" id="InputForm" method="post" accept-charset="utf-8"> 2 3 <!--0--> 4 <div class="form-block" id="form_block[0]"> 5 <span class="close" title="Close" style="display: none;">-</span> 6 <p class="form-content"> 7 <span><input name="attend_flag[0]" id="attend_flag[0]" value="1" checked="" type="checkbox">参加</span> 8 <span>お名前:<input name="atendee[0]" id="atendee[0]" value="お名前" type="text"></span> 9 <span>ディッシュタイプ: 10 <select name="dish_type[0]" id="dish_type[0]"> 11 <option value="">選択してください</option> 12 <option value="1" selected="">和食</option> 13 <option value="2">フレンチ</option> 14 <option value="3">イタリアン</option> 15 <option value="4">中華</option> 16 <option value="5">その他</option> 17 </select> 18 </span> 19 <span id="memos0" style="display: none;">オプショナルディッシュなど:<br> 20 <textarea name="memo[0]" id="memo[0]" cols="80" rows="3"></textarea> 21 </span> 22 </p> 23 </div> 24 25 <!--1--> 26 <div class="form-block" id="form_block[1]"> 27 <span class="close" title="Close" style="display: block;">-</span> 28 <p class="form-content"> 29 <span><input name="attend_flag[1]" id="attend_flag[1]" value="1" checked="" type="checkbox">参加</span> 30 <span>お名前:<input name="atendee[1]" id="atendee[1]" value="性別" type="text"></span> 31 <span>ディッシュタイプ: 32 <select name="dish_type[1]" id="dish_type[1]"> 33 <option value="">選択してください</option> 34 <option value="1" selected="">和食</option> 35 <option value="2">フレンチ</option> 36 <option value="3">イタリアン</option> 37 <option value="4">中華</option> 38 <option value="5">その他</option> 39 </select> 40 </span> 41 <span id="memos4" style="display: block;">オプショナルディッシュなど:<br> 42 <textarea name="memo[1]" id="memo[1]" cols="80" rows="3"></textarea> 43 </span> 44 </p> 45 </div> 46 <div class="form-block" id="form_add"> 47 <span class="add" title="Add">+</span> 48 </div> 49 <div class="button_confirm"><a href="#" id="Confirm">入力内容の確認</a></div> 50</form>

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

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

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

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

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

guest

回答4

0

ベストアンサー

追加されたコードにはonchangeイベントは適用されていません。

DOMに対するJavascriptの操作はonChangeなどのイベントセットの記述を実行した瞬間にhtml上に存在するDOMに対して適応されます。

なので、javascript実行前にあるフォームに関してはonchangeイベントが設定されていますが、追加されたものに対してはonchangeイベントが設定されていないので、思い通りに動かないという事が起きます。

つまり、cloneして要素をInsertした後にもう一度onchangeイベントをセットしてあげると正しく動きます!

$original .clone() .hide() ... //テキストとテキストエリアの中身をクリアにする if ($type == 'text') { $(obj).val(''); }else if($type == 'textarea'){ $(obj).val(''); } }); // cloneした後にイベントを再設定すると動く $('select').change(function() { // イベントを追加 })

しかし、それより一般的?なのは、皆様がおっしゃっているとおり、イベントをdocument自体に付与するパターンだと思います。

js

1$(document).on('change', 'select', function(){ 2 // documentにeventが設定されているので問題なく動く 3});

また、iphoneだと上の用にdocumentやbodyに付与するとイベントが動かないことがあったきがするので、body配下に一つdiv#rootみたいなものをいれて以下のようにするといいかもしれません。

js

1$('#root').on('change', 'select', function(){ 2 // #rootに入れる 3});

何にせよ大事なことは、.change.on('change', function(){})などは~したら~してねという動作をDOMに対して設定する、セットするという理解を持つことだと思います!
それを持っていると、後から追加された要素にはイベントがセットされていないので、現在のバグが出来ていると理解できるかと思います!

長々すいません!

投稿2017/06/01 10:00

編集2017/06/01 10:03
MasakazuFukami

総合スコア1869

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

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

squirrel

2017/06/05 01:41

ありがとうございます。$(document).on('change', 'select', function(){ に変えたら解決できました。表示・非表示要素のずれは、memosの採番し直し処理がうまくいってなかったから起きていたようです。 具体的には、.end()の下に以下のコードを足しました。 .find("span[id=memos" + originCnt + "]").attr('id', 'memos' + frm_cnt) .end() いろいろとありがとうございました。
guest

0

ほかのと同様にdocumentで捕捉してはどうでしょう。

JavaScript

1////$('select').change(function() { 2$(document).on('change', 'select', function() {

投稿2017/06/01 03:28

x_x

総合スコア13749

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

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

squirrel

2017/06/05 01:40

ありがとうございます。$(document).on('change', 'select', function(){ に変えたら解決できました。表示・非表示要素のずれは、memosの採番し直し処理がうまくいってなかったから起きていたようです。 具体的には、.end()の下に以下のコードを足しました。 .find("span[id=memos" + originCnt + "]").attr('id', 'memos' + frm_cnt) .end() いろいろとありがとうございました。
guest

0

$('select').change(function() {

$(document).on('change', 'select', function(){

のように変えてみてください。

【jQuery】.on clickイベントが効かない時の対処方法
2. 動的に生成された要素にイベントをかける場合
jQuery1.9の現象なのか?後から.appendや.html()などで追加した要素に効かない場合があります。
動的に変化する要素へのイベントは、変化しない親の要素に仕込むと動きます。

投稿2017/06/01 03:32

raichi

総合スコア278

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

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

squirrel

2017/06/05 01:39

ありがとうございます。$(document).on('change', 'select', function(){ に変えたら解決できました。表示・非表示要素のずれは、memosの採番し直し処理がうまくいってなかったから起きていたようです。 いろいろとありがとうございました。
guest

0

.clone()を呼び出すときに.clone(true)として、イベントも付けてやる必要があると思いますが。
dataも引き継いじゃうので、どうなんでしょう?

あと、こういうのをスニペットって言うんですかね?良く分からないけど。
Wikipediaでは、

スニペット(英語: snippet)とは、「断片」という意味である。情報処理の分野ではよく使う短いプログラムコードを統合開発環境から呼び出す機能の事である。 また、呼び出される短いコードの事をスニペットと呼ぶ場合もある。

って書いてあるので、ちょっと意味が違いそう?最近はそういう風に使うんですか?

投稿2017/06/01 03:29

shi_ue

総合スコア4437

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

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

squirrel

2017/06/01 03:59

ありがとうございます。出来ればテキスト類はクリアにしたいですが、データはオリジナルを引き継いでもかまいません。やってみましたが、onchangeは反応してくれたものの、テキストエリアではなくチェックボックスが表示・非表示となってしまいました。 言語表現については、英語圏の友人がスニペット共有サイトだと教えてくれ、サイト自体もcode snippetsと書いてあるのでスニペットと書きました。
shi_ue

2017/06/01 05:50

コードを精査したわけではなく、質問内容で回答してしまったので、見当違いでしたかね。 他の方が言われているように、documentでイベントを補足する方がよさそうです。 スニペットの件もすみません。差し出がましかったですね。 日本語と英語の意味が少々乖離している良い例かもしれません。
squirrel

2017/06/05 01:41

ありがとうございます。$(document).on('change', 'select', function(){ に変えたら解決できました。表示・非表示要素のずれは、memosの採番し直し処理がうまくいってなかったから起きていたようです。 具体的には、.end()の下に以下のコードを足しました。 .find("span[id=memos" + originCnt + "]").attr('id', 'memos' + frm_cnt) .end() いろいろとありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問