掲示板のようなホームページには、記事を入力する欄や投稿するボタンがあります。 記事を入力して投稿ボタンをクリックしますと、掲示板に投稿記事が追加されます。 また、検索エンジンのホームページには、検索語を入力する欄や検索を開始するボタンがあります。 検索語を入力して検索ボタンをクリックしますと、検索結果が表示されます。 このようなページでは、フォームとよばれるHTML要素が使われています。
フォーム ( form )とは、HTMLドキュメントの中で、入力欄やボタンなどをまとめている範囲のことです。 入力欄やボタンなどは、 コントロール ( control )とよばれます。 一般的に、フォームはコントロールだけでなく、段落や強制改行なども含みます。
フォームが使われているホームページを表示しますと、コントロールは初期値の状態で表示されます。 ユーザは、入力欄にテキストを入力したりしてコントロールを変更し、フォームを完成させます。 最後に、ユーザが送信ボタンをクリックしますと、フォーム・データが送信され、指定されたフォーム処理プログラムが動くのです。
フォームを構成するタグは
<form>
です。
このタグには
action
属性
が必要です。
この値は、フォーム処理プログラムのURLです。
また、
method
属性
も指定できます。
この値は"get"か"post"で、これはフォーム・データの送信方法を意味しています。
送信データの文字コードを指定するには、
accept-charset
属性
を書きます。
残念ながら、東京女子大学のウェブ・サーバでは、一般ユーザがフォーム処理プログラムを動かす方法はなさそうです。 そこで、この授業では、簡単なウェブ・サーバをコピーしてもらい、自分で起動することにします。 このウェブ・サーバは、送信されたフォーム・データを読みやすく表示するものです。 フォーム・データを処理しているとは言えませんが、フォームの機能を確認することはできます。
/* 1*/ import java.io.*; /* 2*/ import java.net.*; /* 3*/ import java.util.*; /* 4*/ /* 5*/ class FormTest { /* 6*/ public static void main (String[] args) throws IOException { /* 7*/ int port = 8080; /* 8*/ URL baseURL = new URL("http", "localhost", port, "/"); /* 9*/ String encoding = "UTF-8"; /* 10*/ ServerSocket ss = new ServerSocket(port); /* 11*/ Socket s; /* 12*/ InputStreamReader isr; /* 13*/ BufferedReader br; /* 14*/ String request, requestRest; /* 15*/ PrintWriter pw; /* 16*/ String query; /* 17*/ String[] formData; /* 18*/ while (true) { /* 19*/ s = ss.accept(); /* 20*/ isr = new InputStreamReader(s.getInputStream()); /* 21*/ br = new BufferedReader(isr); /* 22*/ System.out.println(request = br.readLine()); /* 23*/ while (!((requestRest = br.readLine()).equals(""))) { /* 24*/ System.out.println(requestRest); /* 25*/ } /* 26*/ pw = new PrintWriter(s.getOutputStream()); /* 27*/ pw.println("HTTP/1.1 200 OK"); /* 28*/ pw.println("Content-Type: text/html; charset=Shift_JIS"); /* 29*/ pw.println("Connection: close"); /* 30*/ pw.println(); /* 31*/ pw.println("<html>"); /* 32*/ pw.println("<head>"); /* 33*/ pw.println("<title>フォーム・テスト</title>"); /* 34*/ pw.println("</head>"); /* 35*/ pw.println("<body>"); /* 36*/ pw.println("<h1>フォーム・テスト</h1>"); /* 37*/ try { /* 38*/ query = getQuery(request, baseURL); /* 39*/ if (query == null) { /* 40*/ pw.println("<p>フォーム・データがありません。</p>"); /* 41*/ } else { /* 42*/ formData = splitQuery(query, encoding); /* 43*/ pw.println("<dl>"); /* 44*/ for (int i = 0; i < formData.length / 2; i++) { /* 45*/ pw.println("<dt>"); /* 46*/ pw.println(toCharEntity(formData[2 * i])); /* 47*/ pw.println("</dt>"); /* 48*/ pw.println("<dd>"); /* 49*/ pw.println(toCharEntity(formData[2 * i + 1])); /* 50*/ pw.println("</dd>"); /* 51*/ } /* 52*/ pw.println("</dl>"); /* 53*/ } /* 54*/ } catch (MalformedURLException e) { /* 55*/ pw.println("<p>URLが間違っています。</p>"); /* 56*/ } catch (UnsupportedEncodingException e) { /* 57*/ pw.println("<p>未知の文字コードです。</p>"); /* 58*/ } /* 59*/ pw.println("</body>"); /* 60*/ pw.println("</html>"); /* 61*/ pw.close(); /* 62*/ br.close(); /* 63*/ s.close(); /* 64*/ } /* 65*/ // ss.close(); /* 66*/ } /* 67*/ static String getQuery (String request, URL baseURL) /* 68*/ throws MalformedURLException { /* 69*/ StringTokenizer tokens = new StringTokenizer(request, " "); /* 70*/ String element = ""; /* 71*/ for (int i = 0; i < 2; i++) { /* 72*/ element = tokens.nextToken(); /* 73*/ } /* 74*/ return (new URL(baseURL, element)).getQuery(); /* 75*/ } /* 76*/ static String[] splitQuery (String query, String encoding) /* 77*/ throws MalformedURLException, UnsupportedEncodingException { /* 78*/ StringTokenizer tokens = new StringTokenizer(query, "&"); /* 79*/ int formLength = tokens.countTokens(); /* 80*/ String[] formData = new String[formLength * 2]; /* 81*/ String element, namePart, valuePart; /* 82*/ int index; /* 83*/ for (int i = 0; i < formLength; i++) { /* 84*/ element = tokens.nextToken(); /* 85*/ index = element.indexOf('='); /* 86*/ if (index == -1) { /* 87*/ throw new MalformedURLException(); /* 88*/ } /* 89*/ namePart = element.substring(0, index); /* 90*/ formData[2 * i] = URLDecoder.decode(namePart, encoding); /* 91*/ valuePart = element.substring(index + 1); /* 92*/ formData[2 * i + 1] = URLDecoder.decode(valuePart, encoding); /* 93*/ } /* 94*/ return formData; /* 95*/ } /* 96*/ static String toCharEntity (String s) { /* 97*/ StringBuffer sb = new StringBuffer(""); /* 98*/ for (int i = 0; i < s.length(); i++) { /* 99*/ switch (s.charAt(i)) { /*100*/ case '<': sb.append("<"); break; /*101*/ case '>': sb.append(">"); break; /*102*/ case '&': sb.append("&"); break; /*103*/ case 34: sb.append("""); break; // 34 = double quote /*104*/ default: sb.append(s.charAt(i)); break; /*105*/ } /*106*/ } /*107*/ return sb.toString(); /*108*/ } /*109*/ }
前回と同じように、このプログラムをJeditのウィンドウにコピーして、ファイル名を"FormTest.java", 文字コードをシフトJISとして保存してください。 そして、「ターミナル」で次のように入力してください。
b04a001@AsiaA1:~% cd WWW-local b04a001@AsiaA1:~/WWW-local% cd comp2e b04a001@AsiaA1:~/WWW-local/comp2e% javac FormTest.java b04a001@AsiaA1:~/WWW-local/comp2e% java FormTest
授業で扱うコントロールは次の通りです。
HTMLでコントロールを表すには、一般的には
<input>
タグ
を用います。
このタグに終了タグはありません。
また、一般的には、コントロールの種類は
type
属性
、コントロールの名前は
name
属性
、コントロールの初期値は
value
属性
で指定します。
ただし、コントロールによってはこの通りではありません。
テキスト入力
(
text input
)は、テキストが一行入力できる欄です。
これは、
<input type="text">
と書きます。
パスワード入力
(
password input
)も、テキストが一行入力できる欄です。
ただし、入力中のテキストは隠されます。
これは、
<input type="password">
と書きます。
テキスト入力もパスワード入力も、
size
属性
を使うと入力欄の大きさ(桁数)が指定できます。
<form action="http://localhost:8080/" method="get" accept-charset="UTF-8"> <p> ユーザ名: <input type="text" name="username" size="8"><br> パスワード: <input type="password" name="password" size="8"> </p> </form>
チェックボックス
(
checkbox
)は、クリックするとオン/オフが切り替えられるスイッチです。
これは、
<input type="checkbox">
と書きます。
チェックボックスは単独でも使えますが、いくつかのチェックボックスをまとめて、一つのグループにする場合もあります。
一つのグループの中から複数が選択可能という意味です。
name
属性の値を同じにすると、同じグループのチェックボックスと見なされます。
ラジオ・ボタン
(
radio button
)は、
<input type="radio">
と書きます。
ラジオ・ボタンは、いくつかまとめて一つのグループにするのが普通です。
クリックしたスイッチがオンになり、そのグループの他のスイッチがオフになります。
一つのグループの中から一つが選択可能という意味です。
name
属性の値を同じにすると、同じグループのラジオ・ボタンと見なされます。
チェックボックスとラジオ・ボタンの
value
属性は、初期値ではなく、グループの中でチェックボックスやラジオ・ボタンを特定する値になります。
また、
checked
属性
を使いますと、そのチェックボックスやラジオ・ボタンは、初期状態でオンになります。
<form action="http://localhost:8080/" method="get" accept-charset="UTF-8"> <p> 性別: <input type="radio" name="gender" value="male">男性 <input type="radio" name="gender" value="female">女性<br> 食事の用意: <input type="checkbox" name="meal" value="dinner">夕食 <input type="checkbox" name="meal" value="breakfast" checked>朝食 </p> </form>
送信ボタン
(
submit button
)は、クリックするとフォーム・データが送信されるボタンです。
これは、
<input type="submit">
と書きます。
リセット・ボタン
(
reset button
)は、クリックするとフォームが初期値の状態になるボタンです。
これは、
<input type="reset">
と書きます。
送信ボタンとリセット・ボタンの
value
属性は、初期値ではなく、ボタンのラベルです。
<form action="http://localhost:8080/" method="get" accept-charset="UTF-8"> <p> <input type="submit" value="送信する"> <input type="reset" value="やり直す"> </p> </form>
メニュー
(
menu
)を用いますと、あらかじめ用意された項目の中から選択ができます。
メニューを表すには、
<input>
タグではなく、
<option>
タグ
と
<select>
タグ
を組み合わせます。
まず、メニューの各項目を
<option>
〜
</option>
で囲みます。
そして、この並び全体を
<select>
〜
</select>
で囲みます。
メニューの場合、
name
属性は
<select>
タグに書き、
value
属性は
<option>
タグに書きます。
ただし、
value
属性は初期値ではなく、メニューの中で項目を特定する値になります。
また、
<option>
タグで
selected
属性
を使いますと、その項目は初期状態で選択されます。
<form action="http://localhost:8080/" method="get" accept-charset="UTF-8"> <p> 部屋の広さ: <select name="room"> <option value="j6">六畳間</option> <option value="j8" selected>八畳間</option> <option value="j10">十畳間</option> </select> </p> </form>
複数行テキスト入力
(
multi-line text input
)は、テキストが複数行入力できる欄です。
複数行テキスト入力には、
<input>
タグではなく
<textarea>
タグ
を使います。
具体的には、初期値を
<textarea>
〜
</textarea>
で囲みます。
value
属性は使いません。
複数行テキスト入力の欄の大きさは、
rows
属性
と
cols
属性
で指定します。
rows
属性が行数、
cols
属性が桁数を表します。
<form action="http://localhost:8080/" method="get" accept-charset="UTF-8"> <p> その他の連絡事項:<br> <textarea name="other" rows="5" cols="30"> その他の連絡事項はここに記入してください。 </textarea> </p> </form>
アンケートのホームページを作成してください。 以下の例を参考にして、質問をいくつか考え、回答しやすいようにコントロールを配置してください。 できれば、今日紹介したコントロールをすべて使ってください。
今日の演習10の答案(ホームページのURL)をメールで提出してください。 メールの差出人は学内のアドレス(b04a001@twcu.ac.jpなど)とし、メールの宛先はkonishi@twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(12月7日)を明記してください。