HTML5 formとinputを分けて記述する方法

2020年5月21日

つい最近まで知らなかったので。

[amazonjs asin="B00VV5C40M" locale="JP" title="現場のプロが教えるHTML+CSSコーディングの最新常識 知らないと困るWebデザインの新ルール4″]

管理画面などを作るときに、

スクリーンショット 2015-06-03 19.57.02

のように、formとtableを組み合わせて作りたくなることがある。
そのときにformタグがtrタグ,tdタグの入れ子になって煩雑になってしまう。
(少なくとも自分は。。。)

そんな時にHTML5から、formタグとinputタグを分けて記述できることを知った。

手順としては

  • formタグにidをつける。(下の例だと form_id )
  • formタグと関連付けたいinputタグ(selectタグ等も)にformプロパティを付加し、formタグのidを与える。(「form="form_id"」)

のようにする。具体的には、

<form action="/action" method="post">
<input type="text" name="name" />
<input type="submit" value="送信" />
</form>

としていたものを、

<form action="/action" method="post" id="form_id"></form>
......

<input type="text" form="form_id" name="name" />
<input type="submit" form="form_id" value="送信" />

のように記述することで、formタグを分けて記述できる。
ちなみにformタグはinputタグのあとに記述しても問題ない。

利用例

サンプルコードはこちら
(他の回に紹介したコードも含む)
フレームワークを利用して一括してフォームを作成したいときなどに便利。
(以降の手順はbottle+jinja2の紹介内容を踏まえている。それらの使い方に関しては割愛。)

まず、次のようなcsvファイルを用意する。

ID,名前,レベル
1,ネス,68
2,ポーラ,62
3,ジェフ,58
4,プー,34
5,ダンジョン男,99

上のcsvのデータを読み込んで、テンプレートファイルに渡す。

"""省略"""

@route('/form/')
def form():

import csv

# キャラクター一覧を格納する配列
character_list = []
# character.csvを展開する
with open("character.csv", "r") as csv_file:

# csvライブラリでcsvファイルを読み込む
reader = csv.reader(csv_file)
# csvのタイトル部分を飛ばす
next(reader)

# 読み込んだcsvを一行ずつ処理
for row in reader:
character_list.append(
{
"id": row[0],
"name": row[1],
"level": row[2]
}
)

return template('form', character_list=character_list)

"""省略"""

テンプレート側で、上で紹介した方法でフォームを作成する。
formタグにつけるidは任意のもので構わないが、idの仕様上、ユニークになるようにしたいため、"form_{{その行のid}}"のようにするとわかりやすい。

{% extends 'base.html' %}

{# base.html の title の中に入れるコンテンツ #}
{% block title %}
HTML5のフォーム紹介ページ
{% endblock %}

{# ヘッダー情報を追加する場合はここに記述する。 #}
{% block header %}
{% endblock%}

{# base.html の contents の中に入れるコンテンツ #}
{% block contents %}

{# 別途、id="form_`キャラクターのID`"を付加した、formの一覧を作成する。 #}
{% for cl in character_list %}
<form action="#" method="post" id="form_{{cl.id}}" accept-charset="utf-8"></form>
{% endfor %}

<table class="table">
<thead>
<tr>
<th>ID</th>
<th>名前</th>
<th>レベル</th>
</tr>
</thead>
<tbody>
{# character_list を1つずつ処理する #}
{% for cl in character_list %}
<tr>
{# form="form_`キャラクターのID`" (== "上のformのid") を付加してテーブルを作成する #}
<td>
{{cl.id}}
<input type="hidden" form="form_{{cl.id}}" name="id" value="{{cl.id}}" />
</td>
<td> <input type="text" form="form_{{cl.id}}" name="name" value="{{cl.name}}" /></td>
<td> <input type="text" form="form_{{cl.id}}" name="level" value="{{cl.level}}" /></td>
<td> <input type="submit" form="form_{{cl.id}}" value="更新" class="btn btn-info" /></td>
</tr>
{% endfor %}
</tbody>
</table>

{% endblock %}

ブラウザでアクセスすると次のようになる。

スクリーンショット 2015-06-03 19.57.02

また、展開されたソースは次のようになっている。




<form action="#" method="post" id="form_1" accept-charset="utf-8"></form>

<form action="#" method="post" id="form_2" accept-charset="utf-8"></form>

<form action="#" method="post" id="form_3" accept-charset="utf-8"></form>

<form action="#" method="post" id="form_4" accept-charset="utf-8"></form>

<form action="#" method="post" id="form_5" accept-charset="utf-8"></form>

<table class="table">
<thead>
<tr>
<th>ID</th>
<th>名前</th>
<th>レベル</th>
</tr>
</thead>
<tbody>

<tr>

<td>
1
<input type="hidden" form="form_1" name="id" value="1" />
</td>
<td> <input type="text" form="form_1" name="name" value="ネス" /></td>
<td> <input type="text" form="form_1" name="level" value="68" /></td>
<td> <input type="submit" form="form_1" value="更新" class="btn btn-info" /></td>
</tr>

<tr>

<td>
2
<input type="hidden" form="form_2" name="id" value="2" />
</td>
<td> <input type="text" form="form_2" name="name" value="ポーラ" /></td>
<td> <input type="text" form="form_2" name="level" value="62" /></td>
<td> <input type="submit" form="form_2" value="更新" class="btn btn-info" /></td>
</tr>

<tr>

<td>
3
<input type="hidden" form="form_3" name="id" value="3" />
</td>
<td> <input type="text" form="form_3" name="name" value="ジェフ" /></td>
<td> <input type="text" form="form_3" name="level" value="58" /></td>
<td> <input type="submit" form="form_3" value="更新" class="btn btn-info" /></td>
</tr>

<tr>

<td>
4
<input type="hidden" form="form_4" name="id" value="4" />
</td>
<td> <input type="text" form="form_4" name="name" value="プー" /></td>
<td> <input type="text" form="form_4" name="level" value="34" /></td>
<td> <input type="submit" form="form_4" value="更新" class="btn btn-info" /></td>
</tr>

<tr>

<td>
5
<input type="hidden" form="form_5" name="id" value="5" />
</td>
<td> <input type="text" form="form_5" name="name" value="ダンジョン男" /></td>
<td> <input type="text" form="form_5" name="level" value="99" /></td>
<td> <input type="submit" form="form_5" value="更新" class="btn btn-info" /></td>
</tr>