Jqueryで同じ名前のフォームを区別する
先日Jqueryを使って、フォームの値などを操作していたのですが、気になる現象が発生しました。
送信ボタンが複数ある、ちょっと複雑なフォームだったのですが、動かしてみると、予期せず複数フォームに同じ値がセットされていました。
これは具合が悪いとおもい、しらべ対処いたしました。
今回も忘備録として記録いたします。
やりたいこと
複数フォームがあり、入力フォームに値をいれて、ボタンを押したら出力部分に値を反映するというものです。
※サンプルでは、出力部分は普通のフォームですが、実際には非表示フォームです。
現象:実際にやってみたらこうなりました。
入力部分01で入力した値が、出力01、出力02両方に反映されてしまいました。
サンプルで試していただくと、入力01、入力02で入力した値が、両方の出力に同時反映されてしまいます。
入力と出力を分離しているのでそれぞれのフォームに反映できないと困ります。
早速原因を調べてみました。
なぜ複数フォームに同時に反映されてしまうのか?
今回の仕掛けはこのようになっています。
- 入力フォームのボタンを押したら入力フォームの値を取り出す。
- 取り出した値を出力フォームにセットする
これらのことをJqueryで行っていますが、あることに気づきました。
出力フォーム01と02の名前が同じ
なるほど、同じ名前だから、出力時に同時に反映されるのだと。
対処方法
対処方法としては以下の3つが考えられます。
- フォームの「name」をそれぞれ違う名前にする
- フォームに異なる名称の「クラス」を設定する
- Jqueryで頑張って区別する
1と2はフォームに異なる名前を付けるので、物理的に区別することができます。
実際にフォームが少ない場合はこちらのほうが現実的です。
でも、フォームが100個あるなど多数の場合は、1、2の方法はあまり現実的ではありません。
なぜならば、メンテナンスがものすごく大変だからです。
つまり、nameやクラスが異なっていものが100以上あると、Jquery側にも100種類以上の記述が必要になるためです。
例えば、さらに100個追加となった場合に、Jquery側も直さなければいけません。
これは面倒だと思い、3の方法で何とかすることにしました。
直した方法はこちら
直す前のJquery部分がこちらです。
1 2 3 4 5 6 7 8 9 10 |
<script> $(document).ready(function() { $('input[name="input_set"]').click(function() { var value = $(this).parent("div").children('input[name=input]').val(); $('input[name="output"]').val(value); }); }); </script> |
name=”output” に値をセットしています。
これだと当然、同じ名前すべてにセットされます。
そこで次のように変えました。
ボタンを押された親のformをだどり、その子供のoutputフォームにセットする
そのソースがこちらです。
1 2 3 4 5 6 7 8 9 10 11 |
<script> $(document).ready(function() { $('input[name="input_set"]').click(function() { var value = $(this).parent("div").children('input[name=input]').val(); $(this).parent("div").parent("form").children("div").children('input[name="output"]').val(value); }); }); </script> |
parent()で親をだどり、formの子供のname=”output”のみに値をセットするようになりました。
その結果、正しくセットされるようになりました。
疑問:parent()を2回つかっているのはなぜ?
修正版では、parentを2回使っていますが、これはなぜなのか?
答えは単純です。
formの下に「div」があり「div」が「input」を囲っているからです。
つまり、コーディングレベルでdivがなければ parent1回でよいということです。
Jqueryのparentはフォームだけでなく、divなどのタグもたどるのです。
ちなみに、サンプルの全ソースがこちらです。
formの下にdivタグがあり、その下にinputタグがある孫構成になっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
<!doctype html> <html> <head> <meta charset="shift_jis"> <title>同じパラメータにセット</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(document).ready(function() { $('input[name="input_set"]').click(function() { var value = $(this).parent("div").children('input[name=input]').val(); $(this).parent("div").parent("form").children("div").children('input[name="output"]').val(value); }); }); </script> <style type="text/css"> section { width: 600px; margin-right: auto; margin-left: auto; margin-bottom: 20px; padding: 20px; border: 1px solid #CCC; } h1 { margin: 0px; padding: 0px; } input { padding: 10px; } </style> </head> <body> <section> <form action="" method="post"> <div class="input"> <h1>入力部分01</h1> <p> 値を入力して読み込みボタンを押してください。<br> 出力01に入力値が表示されます。 </p> <input name="input" type="text"> <input name="input_set" type="button" value="値をセット"> </div> <div class="form"> <h2>出力部分 01</h2> <input name="output" type="text"> </div> </form> </section> <section> <form action="" method="post"> <div class="input"> <h1>入力部分02</h1> <p> 値を入力して読み込みボタンを押してください。<br> 出力01に入力値が表示されます。 </p> <input name="input" type="text"> <input name="input_set" type="button" value="値をセット"> </div> <div class="form"> <h2>出力部分 02</h2> <input name="output" type="text"> </div> </form> </section> </body> </html> |
Jqueryはとても便利ですが、便利ゆえ落とし穴もあったりします。
でも工夫すればより効率的に組むことができるということを、今回学びました。