イントロダクション

4.10.1 イントロダクション

このセクションは非規定です。

フォームは、テキスト・フィールド、ボタン、チェックボックス、レンジ・コントロール、カラー・ピッカーといったフォーム・コントロールを持つウェブ・ページの構成要素です。ユーザーは、フォームを使ってデータをサーバーへ送信して、さらに処理(検索や計算の結果を返すなど)を行わせることができます。多くの場合で、クライアント側にスクリプトが不要となります。もちろん、スクリプトから API を使うことで、ユーザー体験を向上させたり、サーバーへデータを送信せずに別の目的でフォームを使うこともできます。

いくつかの手順を踏めばフォームを書くことができます。順番は問いません:ユーザー・インタフェースを書き、サーバー側の処理を実装し、サーバーと通信するユーザー・インタフェースを定義します。

4.10.1.1 フォームのユーザー・インタフェースを書く

このセクションは非規定です。

まずは手始めに、ピザの注文フォームを作ってみましょう。

どんなフォームも、form 要素から始まります。この中に、コントロールを置くことになります。ほとんどのコントロールは、input 要素で表されます。これはデフォルトでは 1 行テキスト・フィールドを提供します。コントロールにラベルを付けたいなら、label 要素を使います。ラベルのテキストとコントロールそのものは、label 要素の中に入れます。フォームのそれぞれの部分は段落と見なされ、通常は p 要素を使って、他の部分と分離されます。以上をまとめると、もし顧客の名前をも求めるなら、このようになるでしょう:

<form>
 <p><label>お客様名: <input></label></p>
</form>

ユーザーにピザのサイズを選択させるために、ラジオ・ボタンのセットを使うことができます。input 要素はラジオ・ボタンにも使います。今回は、その type 属性の値を radio にします。ラジオ・ボタンをグループとして機能するようにするために、それらの name 属性に共通の値を指定します。この場合のラジオ・ボタンのように、コントロールをひとつのグループにグループ化したい場合は、fieldset 要素を使うことができます。コントロールのグループのタイトルは、fieldset 要素の中で最初の要素に指定します。それは legend 要素でなければいけません。

<form>
 <p><label>お客様名: <input></label></p>
 <fieldset>
  <legend> ピザのサイズ </legend>
  <p><label> <input type=radio name=size> 小 </label></p>
  <p><label> <input type=radio name=size> 中 </label></p>
  <p><label> <input type=radio name=size> 大 </label></p>
 </fieldset>
</form>

前の手順からの変更点がハイライトされています。

トッピングの選択には、チェックボックスを使うことができます。これらには、type 属性の値を checkbox にした input 要素を使います:

<form>
 <p><label>お客様名: <input></label></p>
 <fieldset>
  <legend> ピザのサイズ </legend>
  <p><label> <input type=radio name=size> 小 </label></p>
  <p><label> <input type=radio name=size> 中 </label></p>
  <p><label> <input type=radio name=size> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> ピザ・トッピング </legend>
  <p><label> <input type=checkbox> ベーコン </label></p>
  <p><label> <input type=checkbox> チーズ増量 </label></p>
  <p><label> <input type=checkbox> オニオン </label></p>
  <p><label> <input type=checkbox> マッシュルーム </label></p>
 </fieldset>
</form>

このフォームのお店であるピゼリアは、いつもミスばかりしています。そのため、顧客への連絡方法が必要です。これには、電話番号(type 属性の値を tel にセットした input 要素)、e-mail アドレス(type 属性の値を email にセットした input 要素)に特化したフォーム・コントロールを使うことができます:

<form>
 <p><label>お客様名: <input></label></p>
 <p><label>電話番号: <input type=tel></label></p>
 <p><label>E-mail アドレス: <input type=email></label></p>
 <fieldset>
  <legend> ピザのサイズ </legend>
  <p><label> <input type=radio name=size> 小 </label></p>
  <p><label> <input type=radio name=size> 中 </label></p>
  <p><label> <input type=radio name=size> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> Pizza Toppings </legend>
  <p><label> <input type=checkbox> ベーコン </label></p>
  <p><label> <input type=checkbox> チーズ増量 </label></p>
  <p><label> <input type=checkbox> オニオン </label></p>
  <p><label> <input type=checkbox> マッシュルーム </label></p>
 </fieldset>
</form>

配達時間を尋ねるのであれば、type 属性の値を time にセットした input 要素を使うことができます。これらのフォーム・コントロールの多くは、どんな値を指定できるのかを正確に制御するための属性を持っています。特に興味深い属性は、min, max, step の 3 つです。これらは、最小の時間、最大の時間、そして、指定可能な時間の間隔(秒)をセットします。このピゼリアは、午前 11 時から午後 9 時に限って配達しており、15 分単位でしか承っていません。これは次のようにマークアップすることができます:

<form>
 <p><label>お客様名: <input></label></p>
 <p><label>電話番号: <input type=tel></label></p>
 <p><label>E-mail アドレス: <input type=email></label></p>
 <fieldset>
  <legend> Pizza Size </legend>
  <p><label> <input type=radio name=size> 小 </label></p>
  <p><label> <input type=radio name=size> 中 </label></p>
  <p><label> <input type=radio name=size> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> Pizza Toppings </legend>
  <p><label> <input type=checkbox> ベーコン </label></p>
  <p><label> <input type=checkbox> チーズ増量 </label></p>
  <p><label> <input type=checkbox> オニオン </label></p>
  <p><label> <input type=checkbox> マッシュルーム </label></p>
 </fieldset>
 <p><label>ご希望の配達時間: <input type=time min="11:00" max="21:00" step="900"></label></p>
</form>

フリー入力欄を用意したいなら、textarea 要素を使うことができます。この例では、配達の指示を顧客が入力できる場所を用意するために、これを使うことにします:

<form>
 <p><label>お客様名: <input></label></p>
 <p><label>電話番号: <input type=tel></label></p>
 <p><label>E-mail アドレス: <input type=email></label></p>
 <fieldset>
  <legend> Pizza Size </legend>
  <p><label> <input type=radio name=size> 小 </label></p>
  <p><label> <input type=radio name=size> 中 </label></p>
  <p><label> <input type=radio name=size> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> Pizza Toppings </legend>
  <p><label> <input type=checkbox> ベーコン </label></p>
  <p><label> <input type=checkbox> チーズ増量 </label></p>
  <p><label> <input type=checkbox> オニオン </label></p>
  <p><label> <input type=checkbox> マッシュルーム </label></p>
 </fieldset>
 <p><label>ご希望の配達時間: <input type=time min="11:00" max="21:00" step="900"></label></p>
 <p><label>配達の指示: <textarea></textarea></label></p>
</form>

最後に、button 要素を使って、このフォームを送信できるようにします:

<form>
 <p><label>お客様名: <input></label></p>
 <p><label>電話番号: <input type=tel></label></p>
 <p><label>E-mail アドレス: <input type=email></label></p>
 <fieldset>
  <legend> Pizza Size </legend>
  <p><label> <input type=radio name=size> 小 </label></p>
  <p><label> <input type=radio name=size> 中 </label></p>
  <p><label> <input type=radio name=size> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> Pizza Toppings </legend>
  <p><label> <input type=checkbox> ベーコン </label></p>
  <p><label> <input type=checkbox> チーズ増量 </label></p>
  <p><label> <input type=checkbox> オニオン </label></p>
  <p><label> <input type=checkbox> マッシュルーム </label></p>
 </fieldset>
 <p><label>ご希望の配達時間: <input type=time min="11:00" max="21:00" step="900"></label></p>
 <p><label>配達の指示: <textarea></textarea></label></p>
 <p><button>注文確定</button><p>
</form>
4.10.1.2 フォームに対するサーバー側の処理を実装する

このセクションは非規定です。

サーバー側の処理の詳細な書き方については、この仕様の範囲外となります。このイントロダクションでは、https://pizza.example.com/order.cgi におけるスクリプトが、application/x-www-form-urlencoded のフォーマットを使ったサブミットを受け付けるようになっているとしましょう。次のパラメータが HTTP POST ボディの中に入れて送信されるはずです:

custname
顧客の名前
custtel
顧客の電話番号
custemail
顧客の e-mail アドレス
size
ピザのサイズ。small, medium, large のいずれか。
toppings
トッピング。選択されたトッピングの取り得る値は、bacon, cheese, onion, mushroom です。
delivery
希望の配達時間
comments
配達の指示
4.10.1.3 サーバーと通信するためフォームを定義する

このセクションは非規定です。

フォーム・サブミットは、さまざまな方法でサーバーに送信されます。ごく一般的には、HTTP GET または HTTP POST リクエストが使われます。採用するメソッドを正確に指定するために、method 属性を form 要素に指定します。これは、フォーム・データがどのようにエンコードされるのかを指定するものではありません。それを指定するには、enctype 属性を使います。さらに、サブミットするデータを処理するサービスの URL も指定しなければいけません。それには action 属性を使います。

サブミットさせたいフォーム・コントロールに対して、サブミットでデータを参照するために使う名前を指定しなければいけません。すでにラジオ・ボタンのグループに名前を指定しました。この同じ属性(name)がサブミットの名前をも指定することになります。ラジオ・ボタンは value 属性を使って異なる値を指定することによって、サブミットにおいて、それぞれを区別できるようになります。

マルチプル・コントロールは、同じ名前を持つことができます。例えば、ここでは、すべてのチェックボックスに同じ名前を与えています。サーバーは、どんな値がその名前を伴ってサブミットされたのかを調べることで、どのチェック・ボックスがチェックされたのかを区別します。ラジオ・ボタンと同じように、それらには、value 属性にユニークな値が与えられています。

前のセクションのセッティングを加えると、次のようになります:

<form method="post"
      enctype="application/x-www-form-urlencoded"
      action="https://pizza.example.com/order.cgi">
 <p><label>お客様名: <input name="custname"></label></p>
 <p><label>電話番号: <input type=tel name="custtel"></label></p>
 <p><label>E-mail アドレス: <input type=email name="custemail"></label></p>
 <fieldset>
  <legend> Pizza Size </legend>
  <p><label> <input type=radio name=size value="small"> 小 </label></p>
  <p><label> <input type=radio name=size value="medium"> 中 </label></p>
  <p><label> <input type=radio name=size value="large"> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> Pizza Toppings </legend>
  <p><label> <input type=checkbox name="topping" value="bacon"> ベーコン </label></p>
  <p><label> <input type=checkbox name="topping" value="cheese"> チーズ増量 </label></p>
  <p><label> <input type=checkbox name="topping" value="onion"> オニオン </label></p>
  <p><label> <input type=checkbox name="topping" value="mushroom"> マッシュルーム </label></p>
 </fieldset>
 <p><label>ご希望の配達時間: <input type=time min="11:00" max="21:00" step="900" name="delivery"></label></p>
 <p><label>配達の指示: <textarea name="comments"></textarea></label></p>
 <p><button>注文確定</button><p>
</form>

例えば、もし顧客が自分の名前に "Denise Lawrence" と入力し、電話番号に "555-321-8642" と入力し、e-mail アドレスを指定せず、中サイズのピザを希望し、トッピングにチーズ増量とマッシュルームを選択し、配達時間に午後 7 時を指定し、配達の指示には何も入力しなかったら、ユーザーエージェントは、オンライン・ウェブ・サービスに次の値をサブミットするでしょう:

custname=Denise+Lawrence&custtel=555-321-8624&custemail=&size=medium&topping=cheese&topping=mushroom&delivery=19%3A00&comments=
4.10.1.4 クライアント側のフォーム・バリデーション

このセクションは非規定です。

フォームがサブミットされる前にユーザーの入力をユーザーエージェントがチェックできるよう、フォームを記述することができます。とはいえ、サーバー側でもその入力が妥当かどうかを確認する必要はあります(悪意のあるユーザーはそのフォームのバリデーションを簡単にバイパスできるからです)。しかし、こうすることで、サーバーだけにユーザー入力をチェックさせていた分だけ、ユーザーは待たされずに済みます。

最もシンプルなのは required 属性ですが、これを input 要素に指定すると、値が指定されるまで、そのフォームはサブミットされないようにすることができます。この属性を顧客名と配達時間に加えれば、これらのフィールドを入力せずにフォームを送信しようと、ユーザーエージェントはユーザーに通知することがでるようになります:

<form method="post"
      enctype="application/x-www-form-urlencoded"
      action="https://pizza.example.com/order.cgi">
 <p><label>お客様名: <input name="custname" required></label></p>
 <p><label>電話番号: <input type=tel name="custtel"></label></p>
 <p><label>E-mail アドレス: <input type=email name="custemail"></label></p>
 <fieldset>
  <legend> ピザのサイズ </legend>
  <p><label> <input type=radio name=size value="small"> 小 </label></p>
  <p><label> <input type=radio name=size value="medium"> 中 </label></p>
  <p><label> <input type=radio name=size value="large"> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> ピザのトッピング </legend>
  <p><label> <input type=checkbox name="topping" value="bacon"> ベーコン </label></p>
  <p><label> <input type=checkbox name="topping" value="cheese"> チーズ増量 </label></p>
  <p><label> <input type=checkbox name="topping" value="onion"> オニオン </label></p>
  <p><label> <input type=checkbox name="topping" value="mushroom"> マッシュルーム </label></p>
 </fieldset>
 <p><label>ご希望の配達時間: <input type=time min="11:00" max="21:00" step="900" name="delivery" required></label></p>
 <p><label>配達の指示: <textarea name="comments"></textarea></label></p>
 <p><button>注文確定</button><p>
</form>

maxlength 属性を使えば、入力の長さも制限することができます。これを textarea 要素に加えると、1000 文字までに制限でき、膨大なエッセイを書けないようにすることができます。これで、忙しい配達ドライバーがそれを読むのに夢中になることなく、目的地に行けるでしょう:

<form method="post"
      enctype="application/x-www-form-urlencoded"
      action="https://pizza.example.com/order.cgi">
 <p><label>お客様名: <input name="custname" required></label></p>
 <p><label>電話番号: <input type=tel name="custtel"></label></p>
 <p><label>E-mail アドレス: <input type=email name="custemail"></label></p>
 <fieldset>
  <legend> ピザのサイズ </legend>
  <p><label> <input type=radio name=size value="small"> 小 </label></p>
  <p><label> <input type=radio name=size value="medium"> 中 </label></p>
  <p><label> <input type=radio name=size value="large"> 大 </label></p>
 </fieldset>
 <fieldset>
  <legend> Pizza Toppings </legend>
  <p><label> <input type=checkbox name="topping" value="bacon"> ベーコン </label></p>
  <p><label> <input type=checkbox name="topping" value="cheese"> チーズ増量 </label></p>
  <p><label> <input type=checkbox name="topping" value="onion"> オニオン </label></p>
  <p><label> <input type=checkbox name="topping" value="mushroom"> マッシュルーム </label></p>
 </fieldset>
 <p><label>ご希望の配達時間: <input type=time min="11:00" max="21:00" step="900" name="delivery" required></label></p>
 <p><label>配達の指示: <textarea name="comments" maxlength=1000></textarea></label></p>
 <p><button>注文確定</button><p>
</form>

4.10.2 カテゴリー

このセクションに出てくる要素は、歴史的な理由から、フロー・コンテンツフレージング・コンテンツインタラクティブ・コンテンツといった通常のカテゴリーに加え、いくつかの重複(しかし若干異なる)したカテゴリーに入ります。

多くの要素は、フォーム関連要素と呼ばれます。このような要素は、 フォーム・オーナー を持つことができ、これにアクセスできるようにするために、form コンテンツ属性とそれに対応する form IDL 属性を持つことができる、ということを意味します。

フォーム関連要素は、いくつかのサブ・カテゴリーに入ります:

リスト化要素

form.elementsfieldset.elements API にリストされる要素を意味します。

ラベル付け可能要素

label 要素と結び付けることができる要素を意味します。

サブミット可能要素

form 要素がサブミットされるとき、フォーム・データ・セットを構成するために使うことができる要素を意味します。

リセット可能要素

form 要素がリセットされるときに影響を受ける要素を意味します。

さらに、 サブミット可能な要素 は、その属性に応じて、ボタンとなることができます。要素がどういったときにボタンになるかについては、後述します。中には、特別にサブミット・ボタンになるものもあります。

object 要素もフォーム関連要素です。適切なプラグインを使うと、フォーム・サブミットに加えることができます。


※ 原文:http://www.w3.org/TR/2011/WD-html5-20110525/forms.html#introduction-1