2005 年 2 月 19 日 (土) 自宅

ちょっとここ数日 HTML のフォームをいじっているのですが、 そもそもは 1 つのフォームに複数のボタンを配置する方法に関していろいろと悩んでいました。 普通に考えるのであれば、<input type="submit"> を複数の name で配置して、 それを受け取れば良いのですが…。

そうすると、ちょっと HTML の構成に制限が生じてしまいます。

<form action="URI" method="post">
<input type="submit" name="button0" value="ボタン0">
<input type="submit" name="button1" value="ボタン1">
</form>

こうすれば、 button0 と button1 のどちらかに value が入るかどうかを調べるのは簡単です。 ただし、<input type="submit"> では value をボタンに表示される文字列として利用してしまうので、 name でフォームの内容を判別することになります。

これは解釈するプログラムを書く上であまりスマートではありません。 特に、ボタンを状況に応じて動的に生成する場合、 不定個数のボタンをどう扱うかという問題がやや面倒です (不可能ではありませんが)。

また、value は文字列のみなので、画像ファイルを張ったりすることもできません (単純に画像ファイルのみでボタンを構成するには <input type="image"> が使えますが)。

で、そんな時のためにか、より汎用的なエレメントとして提供されているのが <button> エレメント…だと思っていました。 たとえば上記の例だと、次のように記述できます。

<form action="URI" method="post">
<button type="submit" name="a" value="0">ボタン0</button>
<button type="submit" name="a" value="1">ボタン1</button>
</form>

これによって、ボタンに表示される文字を開始タグから終了タグの間に書くことで、 value="" を本来の目的で使用することが可能となり、 受け側のプログラムは a というパラメータさえチェックするだけでシンプルに書けますし、 複数ボタンの動的生成処理も、悩む場所がほとんどありません…。

…と思っていたのですが、どうもこれが IE のみで振る舞いが違う感じ。 検証のために、こんな感じのフォームを作ります。

<form action="http://fromto.cc/cgi-bin/test.pl" method="get">
<button type="submit" name="aaa" value="bbb">ccc</button>
</form>

実物のボタンはこれ。

action として指定された test.pl はこんなプログラム。

#!/usr/bin/perl
use CGI;
my $cgi = new CGI;
print $cgi->header;
my $val = $cgi->param('aaa');
$val =~ s/&/&amp;/g;
$val =~ s/</&lt;/g;
$val =~ s/>/&gt;/g;
print <<EOT;
<html>
<head>
<title>form test</title>
</head>
<body>
<p>aaa = <span style="font-size: 200%; color:red">$val</span></p>
</body>
EOT

で、これを試すと、 その時試した MSIE for Windows 以外のすべてのブラウザで「aaa=bbb」と表示されるにもかかわらず、 MSIE for Windows では「aaa=ccc」と表示されてしまうのです (w3m は <button> を解釈しないらしく、 ボタン自体が表示されませんでした)。

要するに、<input type="submit" name="aaa" value="ccc"> と書いたのと全く一緒。 何だよ、それじゃ MSIE においては <button> の利点って画像ファイルが文字と一緒に 1 つのボタンに張れるだけ? 意味ないじゃん。

で、さらに恐ろしいことが判明。MSIE for Macintosh では、 「aaa=」のみしか表示されないのです。GET メソッドの行き先の URI は、 何と単に「http://fromto.cc/cgi-bin/test.pl?」となってしまうのです (IE 以外では「http://fromto.cc/cgi-bin/test.pl?aaa=bbb」となる)。

一応結果をまとめてみます。

aaa=bbb
FireFox 1.0, Mozilla 1.75, Safari 125.12, Epiphany 1.4.7, Lynx 2.8.6dev8(注), Opera 7.20
aaa=ccc
MSIE 6.0 for Windows, MSIE 5.5 for Windows
aaa=
MSIE 5.23 for Macintosh
ボタンが表示されない
w3m 0.5.1

(注) Lynx では「(bbb) ccc」のようにボタンが表示されるが、 動作自体は aaa=bbb と正しく表示される。

ということで、MSIE for Macintosh と MSIE for Windows が、 とても問題のある動作ということがわかるのですが…実質的な判断として、 MSIE で動作に問題があれば使えないよなぁ…。

ちなみに、W3C の HTML 4.01 のフォームの仕様書によれば、次のようになっていますが…。 やはり MSIE の仕様が問題のような気が…。

<!ELEMENT BUTTON - -
     (%flow;)* -(A|%formctrl;|FORM|FIELDSET)
     -- push button -->
<!ATTLIST BUTTON
  %attrs;                              -- %coreattrs, %i18n, %events --
  name        CDATA          #IMPLIED
  value       CDATA          #IMPLIED  -- sent to server when submitted --
  type        (button|submit|reset) submit -- for use as form button --
  disabled    (disabled)     #IMPLIED  -- unavailable in this context --
  tabindex    NUMBER         #IMPLIED  -- position in tabbing order --
  accesskey   %Character;    #IMPLIED  -- accessibility key character --
  onfocus     %Script;       #IMPLIED  -- the element got the focus --
  onblur      %Script;       #IMPLIED  -- the element lost the focus --
  >

ということで、仕方がないので submit ボタンを使うしかなさそう。

<form action="URI" method="post">
<button type="submit" name="a" value="0">ボタン0</button>
<button type="submit" name="a" value="1">ボタン1</button>
</form>

上のようなフォームを作りたい場合は、submit ボタンと hidden を組み合わせて、 次のようにやればいいのかな。 これならフォーム中の submit ボタンのリストも取得可能だし。

<form action="URI" method="post">
<input type="submit" name="button0" value="ボタン0">
<input type="submit" name="button1" value="ボタン1">
<input type="hidden" name="buttons" value="button0=0:button1=1">
</form>

しかし、バグであっても IE がバグっている限りは IE に従わなければいけない、 というのは癪だなぁ…。


このサイトへのリンクには何ら許可は必要ありません。 ただし、無断で写真をダウンロードして他の場所に掲載したり、 画像加工の素材として利用するなど、再配布に当たる行為はしないようにしてください。 また、このサイトへのリンクであることを明示すること無しに <img src="..."> などで他のページの内部に画像ファイルを取り込むことも、 ご遠慮下さい。