動的に作成されたボタンに付随する値を取得する方法



0   名前: Souha : 2006/04/25 12:11
こんにちわ、はじめまして。
早速ですが、ご相談させてください。

現在、PHPとJavaScriptを併用したSiteの作成を行っています。
PHPでDBからデータを取得し、リストを動的に作成し、
それを表示するつもりです。
表示の際に、選択ボタンを表示し、選択ボタンを押下することで、
次のページに遷移させるようなコーディングを行いたいと思っております。

ButtonオブジェクトのValueはボタンの表示名が入る為、
隣にHiddenBoxを生成し、そこに値をセットしておき、
POSTを行う事になると思いますが。

最悪、PHP側でJSのコードに対し、ボタン1つごとのFunctionを動的に
作成し、埋め込むという方法はあるのですが・・・さすがにみっともない。

JavaScriptでどのように書くとスマートに実現できるのでしょうか。
いい方法があればご教授いただけないでしょうか。

HTMLソース
<table>
<TR>
<TD>TEST1</TD>
<TD>
<input type="submit" name="btnSelect1" value="選択">
<input type="hidden" name="txtHidden1" value="001">
</TD>
</TR>
<TR>
<TD>TEST2</TD>
<TD>
<input type="submit" name="btnSelect2" value="選択">
<input type="hidden" name="txtHidden2" value="002">
</TD>
</TR>
 (以下繰り返し)
</Table>

1   名前: Pid : 2006/04/25 12:11
仰る内容が今一つピンとこないのですが,たとえば「スマートでない」方法だと,どんな JavaScript がどこで使用されるのですか。

2   名前: Souha : 2006/04/25 12:11
少し本題とは離れますが、まず現在の表示方法について説明します。
簡単に言うと、
PHP内で表示用のテンプレート(Bodyを除く部分が書かれたもの)を読込む
→Body内のキーワードを表示するBody部を保持するファイルに置き換える
→さらにBody内のキーワードをJSを保持するファイルに置き換える
→結果をブラウザに表示。
ということを、やっています。

本題です。
PHP内ではDBからデータを取得し、ForLoopでリストを作成します。
この際に、ボタンとHiddenBoxに命名する必要が発生します。
このタイミングで、別に1ボタンに対する1イベントを
動的に作成し、変数に放り込んでおきます。

※こんな感じ
for($i = 1; $i <= $cnt; $i++)
{
//ループによる行作成
$table = $table."<TD><input type='button' name='btnSample".$i."' value='TEST' onClick='return setData".$i."()'>"
$table = $table."<Input Type='hidden' name='txtHidData".$i."' Value='".$rsdata[$i]."'></TD>"

//ボタンに対するJSの作成
$strJS = $strJS."function setData".$i."{" strGetData = '';"
$strJS = $strJS."strGetData = window.form1.txtHidData".$i.".value;"
$strJS = $strJS."window.form1.txtsubmitdata.value = strGetData;"
$strJS = $strJS."Return True;}"
}

ちょっと見づらいですが。
要するに、PHPで動的にリストを作るループ文の中で、
対応するイベントを同一の命名規則で、JSと、イベントを叩く部分を
文字列で作成してしまいます。

その上でJSのファイル内にキーワードを仕込んでおき、
文字列変換で置き換えてしまう。
HTMLに出力した際にはキーワードとイベントが一致する為、
Hiddenボックスに入っている値を共通のHiddenボックスに
コピーしておけば、次にCallした先からは同じ所を見ればいいので、
問題はないわけです。

ただ、JSのイベントがボタンの数だけできてしまう事になるので、
他にいい方法はないものかと思いまして、ご相談させていただいています。

3   名前: Souha : 2006/04/25 12:11
>HTMLに出力した際にはキーワードとイベントが一致する為、

ボタンのイベントとJSの関数が一致する為、です。
失礼しました。

4   名前: Pid : 2006/04/25 12:11
詳細な説明をありがとうございます。ただ,今回のご質問内容ならば,クライアント側に渡すソース(の抜粋)を載せるだけの方がアドバイスを得られやすいと思います(サーバ側 PHP を動作確認できる環境は限られますし,そもそも本件はクライアント側の情報だけで済む話ですので)。

さて,コードから推測する限り form 要素があるのですね?ならば,文書読み込み完了と同時に,form 要素内の全ての input[type="button"] 要素に onclick 属性を付ければ良いだけかと思います。

onload = function () {
  var nodes = document.forms['form1'].elements;
  var I = nodes.length;
  var i = 0;

  do if ('button' == nodes[i].type)
    nodes[i].onclick = function () {
      var el = this.form.elements;
      el['txtsubmitdata'].value = el['txtHidData' + this.name.match (/\d+$/)].value;
    }
  while (++i < I);
}

以上を head 要素内にでも置けば十分です(本来は,こういうレガシーな書き方ではなく addEventListener/attachEvent を使うべきですが,割愛)。もし,name="btnSelect-" の直後に name="txtHidData-" が確実に来るのであれば,もっと簡単に書けるでしょう。


なお,いくつか気になった点ですが

> onClick='return setData".$i."()'
ここで return する必要がありますか(なお,onClick ではなく onclick)。

> function setData".$i."{" strGetData = '';
JavaScript では,var 宣言しない変数は原則としてグローバル変数になります。

> window.form1.txtHidData
このような書式は公式には存在しません(歴史的な事情により WinIE はこれでも認識してしまう)。

> Return True;
return true; でなければなりません。

5   名前: Souha : 2006/04/25 12:11
>Pidさん

お返事遅れて申し訳ありません。
PC環境がない所にいた為、閲覧できませんでした。

ご回答及び、サンプルソースと指摘点ありがとうございます。
また、指摘点ありがとうございます。
WindowsXP SP1で開発を行っている為、IEでのみ認識するものを
気づかずにスルーしてました。

>もし,name="btnSelect-" の直後に name="txtHidData-" が
>確実に来るのであれば,もっと簡単に書けるでしょう。

これに関しては、PHP内のコーディングで解決できますので、
もう少し勉強して、シンプルに書きたいと思います。

一覧へ戻る