ホームページ制作 オフィスオバタ

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>

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>

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

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

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

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

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

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

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

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


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

モバイルバージョンを終了