Jqueryで同じ名前のフォームを区別する

先日Jqueryを使って、フォームの値などを操作していたのですが、気になる現象が発生しました。

送信ボタンが複数ある、ちょっと複雑なフォームだったのですが、動かしてみると、予期せず複数フォームに同じ値がセットされていました。

これは具合が悪いとおもい、しらべ対処いたしました。

今回も備忘録として記録いたします。

やりたいこと

複数フォームがあり、入力フォームに値をいれて、ボタンを押したら出力部分に値を反映するというものです。
※サンプルでは、出力部分は普通のフォームですが、実際には非表示フォームです。

現象:実際にやってみたらこうなりました。

入力部分01で入力した値が、出力01、出力02両方に反映されてしまいました。

サンプルはこちらです。

サンプルで試していただくと、入力01、入力02で入力した値が、両方の出力に同時反映されてしまいます。
入力と出力を分離しているのでそれぞれのフォームに反映できないと困ります。

早速原因を調べてみました。

なぜ複数フォームに同時に反映されてしまうのか?

今回の仕掛けはこのようになっています。

  • 入力フォームのボタンを押したら入力フォームの値を取り出す。
  • 取り出した値を出力フォームにセットする

これらのことをJqueryで行っていますが、あることに気づきました。

出力フォーム01と02の名前が同じ

なるほど、同じ名前だから、出力時に同時に反映されるのだと。

対処方法

対処方法としては以下の3つが考えられます。

  1. フォームの「name」をそれぞれ違う名前にする
  2. フォームに異なる名称の「クラス」を設定する
  3. Jqueryで頑張って区別する

1と2はフォームに異なる名前を付けるので、物理的に区別することができます。
実際にフォームが少ない場合はこちらのほうが現実的です。

でも、フォームが100個あるなど多数の場合は、1、2の方法はあまり現実的ではありません。

なぜならば、メンテナンスがものすごく大変だからです。
つまり、nameやクラスが異なっていものが100以上あると、Jquery側にも100種類以上の記述が必要になるためです。

例えば、さらに100個追加となった場合に、Jquery側も直さなければいけません。
これは面倒だと思い、3の方法で何とかすることにしました。

直した方法はこちら

直す前のJquery部分がこちらです。

<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>Code language:HTML, XML(xml)

name="output" に値をセットしています。

これだと当然、同じ名前すべてにセットされます。
そこで次のように変えました。

ボタンを押された親のformをだどり、その子供のoutputフォームにセットする

そのソースがこちらです。

<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>Code language:HTML, XML(xml)

parent()で親をだどり、formの子供のname="output"のみに値をセットするようになりました。

その結果、正しくセットされるようになりました。

直したバージョンがこちらです。

疑問:parent()を2回つかっているのはなぜ?

修正版では、parentを2回使っていますが、これはなぜなのか?
答えは単純です。

formの下に「div」があり「div」が「input」を囲っているからです。

つまり、コーディングレベルでdivがなければ parent1回でよいということです。
Jqueryのparentはフォームだけでなく、divなどのタグもたどるのです。

ちなみに、サンプルの全ソースがこちらです。
formの下にdivタグがあり、その下にinputタグがある孫構成になっています。

<!doctype html><html><head><metacharset="shift_jis"><title>同じパラメータにセット</title><scriptsrc="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><styletype="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><formaction=""method="post"><divclass="input"><h1></h1><p><br></p><inputname="input"type="text"><inputname="input_set"type="button"value="値をセット"></div><divclass="form"><h2></h2><inputname="output"type="text"></div></form></section><section><formaction=""method="post"><divclass="input"><h1></h1><p><br></p><inputname="input"type="text"><inputname="input_set"type="button"value="値をセット"></div><divclass="form"><h2></h2><inputname="output"type="text"></div></form></section></body></html>Code language:HTML, XML(xml)

Jqueryはとても便利ですが、便利ゆえ落とし穴もあったりします。
でも工夫すればより効率的に組むことができるということを、今回学びました。

今回のレポートは以上です。
読んでいただいてありがとうございました。


ホームページに関するお悩み事やご相談事がございましたら私どもまでご連絡ください。 鋭意ご対応申し上げます。
ホームページのご提案もさせていただいております