JavaScriptによるフォームの制御

 JavaScriptでHTMLのフォームをコントロールする基本仕様をタグの種類毎に解説します。
 また、タグやフォームをコントロールするプロパティやメソッド、イベントについてまとめておきます。

タグ : FORM / INPUT / textpassword / radio / checkbox / button / submit / reset / hidden / SELECT / TEXTAREA / LABEL

プロパティ : form / text / radio / checkbox/ button /select / textarea | メソッド | イベントハンドラ


戻る

ご注意

JavaScriptでHTMLのフォームの制御をするために必要な情報をまとめました。

HTMLやJavaScriptの基本的な学習はできていることを前提としていますので、省略して表記している部分もあります。
特にタグの正しい書き方については、HTMLの仕様に準拠して記述してください。

基本的なタグが抜けているためにスクリプトが動作しないこともあります。
また、ブラウザによって対応するスクリプトの命令に差異があったり、バージョンによっても動作内容が異なるケースもあるので、JavaScriptの書籍やテストを行って動作を確認してください。

基本的なスクリプトの動作についてはbuttonの使用例を参照してください。

<form></form>タグ

属性:name / id / action / method / enctype / target / accept-charset / accept

name フォームの名前。JavaScriptからdocument.nameで指定できるようになります。
id フォームのID名。JavaScriptからdocument.forms["id"]で指定できます。
action "mailto:user@dammy.com"のように、メールの設定をするとフォームの内容をメールアドレスに発信します。
"dammy.cgi"や"dammy.html"とファイル名を指定すると、そのファイルに対してフォームの内容を送信します。
method "get"…URLを利用してフォームの内容をテキスト文字列で送信します。
"post"…大量のデータを送るのに向いており、URLにもデータが表示されない。
enctype メール送信で文字化け(エンコード)しないように"text/plain"としたり、画像などアップロードするときには"multipart/form-data"として、送信データの形式を指定します。
target window名を指定。任意の他、"_blank" "_parent" "_self" "_top"がある。

JavaScriptでフォームの指定をする場合、document.form名が使えますが、参照番号を使って、1番目のフォームという指定もできます。
その場合次のように記述します。配列と同じで「0」が最初です。

document.forms[0]

フォームの基本形

<form><input type="text"><input type="submit"></form>

<input>というタグを複数<form></form>の中に挟んで使います。この<input>タグはtypeを指定して、様々な入力形式を提供します。ここでは、textタイプを使って、文字列の入力欄を表示しています。また、submitタイプのように、送信ボタンも<input>タグによって設置されます。
上記の例文は、下のように表示されます。

表示例:

上記の例ではボタンを押してもフォームが送信されないようにしてあります。

フォームの整形

テーブルの中に<form>を置くと、ブラウザによっては行間が開きデザインが乱れます。また、フォームの項目名や入力項目などをテーブルで綺麗に整形してデザインしたい場合も枠内のテキスト等が左右で揃わなくなってしまいます。
そような場合、<form></form>の中にテーブルを入れると空白行の影響を受けなくなります。

※最近のブラウザではどちらも変化がないようです。(Firefox 34、Safari 8で確認)

<table><form>   <form><table>
表示例
表示例
<table>
<tr><td>表示例</td><td>
<form>
<input type="text"><input type="submit">
</form>
</td></tr>
</table>
<form>
<table>
<tr><td>表示例</td><td>
<input type="text"><input type="submit">
</td></tr>
</table>
</form>

左と右の表示例を比較してください。
左の表示例では、IE7やFirefoxで見ると</form>の後に改行が入って、テーブルの右枠内が2行になります。そのため、左枠と右枠の上下の位置がずれてしまいます。
右の表示例では、フォームによる改行がテーブル内に影響しないため、テーブルの内容が1行に揃って表示されています。

<table>の前後だけでなく、<tr>や<td>などのタグの前後に<form>を置くこともできます。タグの入れ子構造が崩れないように注意が必要です。

メールアドレスへの送信

<form action="mailto:user@dammy.com" method="post" enctype="text/plain">
<input type="text" name="textfield">
<input type="submit" value="送信" >
</form>

actionとmethod、enctype上記のように指定し、メールアドレスに対してフォームの内容を送信することができます。
メールで送信されるため、専用のサーバやCGIが使えない場合でも、フォームのデータを受信することが可能です。

表示例:
受信データ: textfield=テスト

表示例のように、入力欄に「テスト」と入力し送信ボタンを押すと、ブラウザからメールが発信されます。
発信者のメールアドレスはブラウザで設定を行います。(IEの場合、インターネットオプションで設定します)
「method="get"」にすると、メールソフトが起動します。
enctypeを省略すると、データはエンコード(コード化)された状態で送信されますので、そのままでは読むことが出来ません。
複数の項目がある場合、項目毎に改行されて表示されます。

※文字化けなど不具合も多いため、IE8では使用不可。Firefox6ではメールが起動し文字化けして止まります。Firefox34では、メールが起動して本文に送信文字列が表示されます。

HTMLファイルへの送信(URLエンコードの注意点)

HTMLファイルからHTMLファイルへデータを送信する場合、一般的なフォームからデータを送信するとURLにデータが付加して送られます。
URLは元々日本語が使えないことが前提で、また一部の文字記号も使えません。
そこでブラウザは、それら特殊な文字を%で始まる英数字に置き換える、URLエンコードという処理を行います。この時に問題が発生します。
このURLエンコードでは、HTMLファイルの保存形式(表示形式)が影響を与えてしまうのです。

一般的に多くの日本語の文書がまだまだShift-JISで作られていると思います。そのようなShift-JIS形式のHTMLファイルからフォームでデータを送信した場合、JavaScriptでは直接扱えない形式のURLエンコードが行われてしまいます。
そのため、IEでもFirefoxでも、JavaScript のunescape()やdecodeURI()という関数では元の日本語に戻すことができません。

HTMLファイルの保存形式をUTF-8にすると、これが実に単純になります。URLエンコードされた文字列がdecodeURI()で元に戻るからです。
ただし、decodeURI()はこのURLエンコード問題に対処するために追加されたため、古いブラウザでは機能しないことと、UTF-8形式の文書を前提に機能が作られています。

そのため、このページでは、スクリプトを単純に見てもらえるようにするため、送信テストにはUTF-8形式を使っています。
ようするに、UTF-8形式で保存されているため、煩わしいことを考えなくて良いということになります。

もし、Shift-JISでHTMLファイルを作ってしまった場合は、UTF-8で保存し直すか、JavaScriptで事前にエンコードをする必要があります。
以下にUTF-8の場合とShift-JISの場合とを分けて解説します。また、「エンコードとデコードについて」の項目も参照してください。

HTMLファイルへの送信(UTF-8)

<form action="form_receive.html" method="get">
<input type="text" name="textfield">
<input type="submit" value="送信" >
</form>

下記フォームでは<form>内に属性「target」を使って新しいウィンドウでファイルを開いています。
「method="post"」では、エラーが発生し、ファイルを開くことができません。

表示例:
送信時のURL: form_receive.html?textfield=%E3%83%86%E3%82%B9%E3%83%88

フォームの送信ボタンを押すと受信ページが開きます。そのURLを見てください。
上記のように、ファイル名の後ろに「?」、「項目名」「=」「データ」と続けて入っているのが判るでしょうか。
このとき、データはエンコードされて日本語ではなくなっています。

複数の項目がある場合、各項目事に「&」でつながれて、「?textfield=%83e&textfield2=%83g」のようになります。

受信用のページでは以下の手順でデータを取り出し、元に戻しています。

get_text = document.location.search;
get_text = get_text.substring(1,get_text.length);

JavaScriptにはURLからデータ部分を取り出すためのプロパティが用意されています。それが「search」です。
ただし、そこには「?」を含んで、それ以降の文字列が入ってしまいますので、1文字目の「?」を取り除く必要があります。

document.receive.textfield2.value = decodeURI(get_text);

取り出した文字列を最後にdecodeURI()で元に戻します。

HTMLファイルへの送信(Shift-JIS)

表示例:
URLエンコード: textfield=%83e%83X%83g
escape(): textfield=%u30C6%u30B9%u30C8
encodeURI(): textfield=%E3%83%86%E3%82%B9%E3%83%88

このドキュメントがUTF-8でエンコーディングされているため、上記の表示例を送信しても、URLエンコードがShift-JISではなくUTF-8になってしまうため、使用不可にしています。
そのため、表示例の下に、3つのエンコードの結果を表示しています。

実際にフォームを送信してみると、URLエンコードはShift-JIS形式になり、escape()はユニコードのコード番号、encodeURI()はUTF-8のURLエンコードと全ての結果が異なります。

「テ」の文字コード番号 JIS:2546 Shift-JIS:8365 区点コード:00538 ユニコード:U+306C

Shift-JISの場合、「テ」を1バイト毎に分けてから、それぞれをエンコードしています。 エンコードは英数字及び記号の一部はそのままなので、 英数字にない上位を「%83」とし、下位は「%65」にせず「e」として認識するため、「%83e」となっています。
参照:http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1

JavaScriptにはShift-JIS形式を元に戻すための関数がありません。
そこで、送信前になんらかの方法で、JavaScriptが対応できるようにする必要があります。

Shift-JISでの送信テストとして、下記に3つのパターンを用意しました。

データ受信テスト: [A] URLエンコードで送信 加工をせずにフォームのデータをそのまま送信します。
受信したデータはunescape()しています。decodeURIを使うとエラーが発生します。
[B] escapeして送信

送信直前にテキストフィールドのデータをescape()で書き換えてから、送信しています。
受信したデータは2回unescape()しています。

[C] encodeURIして送信 送信直前にテキストフィールドのデータをencodeURIして、変数にURLエンコードと同じ文字列を入れています。
送信にはsubmitを使わず、変数の文字列を直接URLに出力しています。
受信したデータはdecodeURI()しています。

[A]では、データをそのままURLエンコードに任せて送信しています。受信データは正しく表示されません。

//デコードして表示
document.receive.textfield2.value = unescape(unescape(get_text));
 
function submit_data() {
	document.forms[0].textfield.value = escape(document.forms[0].textfield.value);
	document.forms[0].submit();
}

[B]では、送信前にデータをescape()でエンコードしたものを、テキストフィールドに戻してから、送信しています。更にURLエンコードの影響をうけるため、受信時に2度unescape()すると元に戻ります。

//デコードして表示
document.receive.textfield2.value = decodeURI(get_text);
 
function submit_data() {
	encode_text = document.forms[0].textfield.name + "=" + encodeURI(document.forms[0].textfield.value);
	document.location.href = "form_receive_JIS3.html?" + encode_text;
}

[C]では、テキストフィールドのデータをencodeURI()でエンコードし、変数に入れています。変数にフォーム送信時と同じ文字列を作って、URLの一部としてファイルを呼び出しています。擬似的にデータを送信したことにしているのです。受信時はdecodeURI()で元に戻しています。

CGIファイルへの送信

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

method="get"でも送信はできますが、postかgetかでCGIの受信方法が異なります。
下にCGIで受信方法する場合のperlのソースを示します。

#受信バッファ
if ($ENV{'REQUEST_METHOD'} eq 'GET') {
	$buffer = $ENV{'QUERY_STRING'};
} elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
	read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
}
 
#デコード
$buffer =~ s/\+/ /eg;
$buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

perlでは環境変数を使ってデータの受信を行います。getの場合とpostの場合で受信する環境変数が違うため、送信方法を確認して$bufferにデータを入れています。
次のデコード処理で「+」を半角スペースに戻したり、日本語を元の状態に戻しています。ただし、これはShift-JIS用のデコード方法です。
JavaScriptとは直接関係がなくなるため、今回はここまでにしておきます。

JavaScriptによるフォームの生成と送信

HTMLの上では<form>タグや<input>タグを使ってフォームを作成しますが、これらを全てJavaScript上でやってみましょう。

document.write()

HTML内に直接的にタグを書き出します。属性nameやidでJavaScriptから指示することが可能です。

document.write("<form><input type='text' name='field1'><input type='text' name='field2'><input type='submit' value='送信'></form>");

document.getElementById()

事前にHTML内に<div>または<span>を設置し、下記例ではタグ属性をid="form_position"とします。

document.getElementById("form_position").innerHTML = "<form><input type='text' name=''field1''><input type='text' name='field1'><input type='submit' value='送信'></form>"; 

document.createElement()

入力操作をする必要がない場合、送信時にエレメントを作成します。

var send_form = document.createElement("form");
send_form.name = "fsend"; //省略可 
send_form.action = "recieve.cgi";
send_form.method = "POST"; //GETも可能
send_form.style.visibility = "hidden"; //画面に表示しない 
document.body.appendChild(send_form); //画面内に追加

var fld1 = document.createElement("input");
fld1.name = "field1";
fld1.type = "text"; //省略可 or hidden
fld1.value = "data1";
send_form.appendChild(fld1);

var fld2 = document.createElement("input");
fld2.name = "field2";
fld2.type = "text"; //省略可 or hidden
fld2.value = "data2"; 
send_form.appendChild(fld2);

send_form.submit();

上記を実行すると「recieve.cgi」に対し、2つの項目のデータが送信されます。
属性methodが「POST」の場合、データは「field1=data1&field2=data2」という形式で送信されます。
属性methodを「GET」にした場合、「recieve.cgi?field1=data1&field2=data2」というURLがアドレス欄に表示されます。

注意点

send_formの各プロパティをまとめるためwith()を使用すると、送信データが「field1=data1\r\nfield2=data2」という形式になってしまいます。

送信テスト

データ受信テストはこちらで実行できます。

エンコードとデコードについて

日本語の文字がフォーム内の入力項目に含まれる場合、自動的にURLエンコードが行われ、1バイトの文字列に置き換えられます。
そのため、受信側で元の日本語が読めるようにデコードする処理が必要になります。

JavaScriptにはShift-JISをデコードする関数がありません。CGIで処理を行う場合は、受信側の処理で対応することができます。
しかし、JavaScriptでエンコードとデコードをしたいともあります。URLエンコードの影響を受けないように事前にエンコードする場合や、cookieを扱うときにもエンコードは必要になります。
それでは、JavaScriptにはどんな関数が備わっているのか確認しておきましょう。それぞれ対になるように使います。

表示例:
escape():
encodeURI():
encodeURIComponent():

テキストフィールドに文字を入力し、変換ボタンを押すと、3つの変換例を表示します。
エンコードされた文字は赤色、されなかった文字は青色で表示します。
変換ボタンをダブルクリックするとフォームをリセットできます。

文字だけでなくスペースの空白記号も「%20」とエンコードされています。
以下にそれぞれのメソッドでエンコードされない文字も提示していますので、比較してみてください。

escape()とunescape()

//エンコード
get_data = escape(get_data);
//デコード
get_data = unescape(get_data);

エンコードされない文字:英数字、「- _ . *」「/ @ +

encodeURI()とdecodeURI()

//エンコード
get_data = encodeURI(get_data);
//デコード
get_data = decodeURI(get_data);

エンコードされない文字:英数字、「- _ . ! ~ * ' ( )」「; , / ? : @ & = + $ #

encodeURIComponent()とdecodeURIComponent()

//エンコード
get_data = encodeURIComponent(get_data);
//デコード
get_data = decodeURIComponent(get_data);

エンコードされない文字:英数字、「- _ . ! ~ * ' ( )

JavaScriptでのプロパティ

document.forms[0].name 文字 <form>のnameを参照/設定
document.forms[0].id 文字 <form>のidを参照/設定
document.forms[0].action 文字 <form>のactionを参照/設定
document.forms[0].encoding 文字 <form>のenctypeを参照/設定
document.forms[0].enctype 文字 <form>のenctypeを参照/設定
document.forms[0].method 文字 <form>のmethodを参照/設定
document.forms[0].target 文字 <form>のtargetを参照/設定

(入…値を参照/出…値を設定)

<input>タグ共通仕様

属性:name / id / type / value / disabled

name 項目の名前。データを送信するときに、項目名として必ず送信されます。
JavaScriptからdocument.form名.nameで指定できるようになります。
id 項目のid名。JavaScriptからdocument.getElementById("id")で指定できます。
type タイプの指定によって項目の入力形式そのものが変わります。以後の項目で詳しく紹介しています。
"text" "password" "radio" "check" "button" "submit" "reset" "hidden" "file" "image"
value その項目に既存の入力値として表示するデータを指定します。JavaScriptからdocument.form名.name.valueでデータの入出力が可能です。
size 横幅を数値で指定します。
disabled 入力できないようにグレー表示にしてしまいます。

使用例

<input>を指定するためには、nameやidを使って名前で識別する方法と、要素をその順番に番号で指定する方法があります。

[A] nameでの指定

<form>や<input>にnameを使って名前を付け、どのフォームのどの項目かを直接的に指示します。
フォームから送信される項目には必ずnameが必要です。

document.forms["name"].elements["name"]

また、これは次のようにも書くことが出来ます。

document.name.name

[B] idでの指定

nameとidは同じように扱えますが、idは主にCSSでの対応に利用されます。
nameとidを混在して利用する場合、同じ名称でもかまいませんが、まったく異なる名称でもかまいません。処理の都合で使い分けます。

document.forms["id"].elements["id"]

「document.id.id」のように<form>のidは直接指定できません。必ず「forms["id"]」とします。
「document.name.id」としてidで指定することはできますが、次のようにgetElementById()を使用する方が良いでしょう。

document.getElementById("id")

[C] 参照番号での指定

1つ目のフォームの1つ目の項目は次のように指定します。

document.forms[0].elements[0]

nameやidと混在することもできます。

document.forms[0].elements["name"]

これら項目名やid名には変数を使うこともできます。
また、一部を変数名にして「"data"+num」のようにして、num=0のとき「data0」を指定することもできます。

num = 0;
document.forms[0].elements["data" + num].value = s[num];

使用不可

<form><input type="text" disabled><input type="checkbox" checked disabled><input type="submit" disabled></form>

使わせたくない項目にはdisabledで入力を拒否することが出来ます。
スクリプトを使って、条件を満たすと解除するように作ります。

表示例:

グレーになった項目やボタンはクリックしても変化がありません。

<input type="text">

属性:size / maxlength

size 項目の横幅。文字数ではない。
maxlength 最大入力文字数。半角文字も全角文字も1文字として扱われる。
readonly 読み取り専用でテキストの書き換えをできなくします。

使用例

<form><input type="text" name="textfield" size="20" maxlength="15" value="あいうえお"></form>

<form>タグと送信ボタンは省略しています。
valueを指定すると初期値として文字が入りますが、省略すると空で表示されます。

表示例:

送信ボタンを押すと受信フォームにデータが送られます。

JavaScriptからの入出力

JavaScriptで入力されたデータにアクセスするには、「document.フォーム名.項目名.value」と指定します。

//フォームのデータを変数へ入力
get_data = document.forms[0].elements[0].value;
//変数のデータをフォームへ出力
document.forms[0].elements[0].value = get_data;

上記の例では、項目の入力内容を変数get_dataへ、また変数get_dataから項目へデータを写しています。

JavaScriptでのプロパティ

document.forms[0].TEXTFIELD.value 文字 タグ属性のvalueで指定された文字列
document.forms[0].TEXTFIELD.disabled 条件 選択肢が使用禁止か調べたり、状態を変更します

<input type="password">

属性:size / maxlength

size 項目の横幅。文字数ではない。
maxlength 最大入力文字数。文字が見えないため、文字数の確認をしやすくするために設定する方がよい。

使用例

パスワードなど、画面上で表示を伏せながら入力することができます。

<form><input type="password" name="password" size="10" maxlength="8" value="abcdef"></form>

ここではvalueを使って文字を入れていますので、ソースファイルを見ると入力された内容が判ります。
この状態では検索サイトなどにデータとして収集される恐れがあり、通常は送信時に入力させます。
パスワードや暗証番号の入力に使用され、受信したサーバ側で管理しているデータと照合するために使います。

フォームを送信する場合、passwordの内容はそのまま送られます。画面の表示を隠すだけの機能ですので、通信の安全性は考慮されていません。
安全にパスワードを送信する必要がある場合、SSL等の暗号通信をする必要があり、対応したサーバが必要になります。

表示例:

送信ボタンを押して、入力内容が受信されることを確認してください。
日本語を入れることもできますが、入力しにくいため、通常は英数字を使用します。

<input type="radio">

属性:name / value / checked

name ラジオボタンでのnameは項目名というだけでなく、1つのグループとしてラジオボタンを認識する役目も持っています。
value 送信されるデータで、どのボタンが押されているのか識別するために必要です。
checked 初期値としてラジオボタンに印を付けます。

使用例

<form name="fr">
設問1<input type="radio" name="Q1"  value="win" checked>Windows <input type="radio" name="Q1"  value="mac">Macintosh
設問2<input type="radio" name="Q2"  value="Spring" checked>春 <input type="radio" name="Q2"  value="Summer">夏 <input type="radio" name="Q2"  value="Autumn">秋 <input type="radio" name="Q2"  value="Winter">冬
</form>

上記の例では2種類の設問を用意して、name="Q1"には2つのボタンを、name="Q2"には4つのボタンがあります。
valueで指定したデータは画面には表示されません。別途タグの後などに判りやすい項目を記述します。

表示例:
設問1Windows Macintosh
設問2

JavaScriptからの入出力

  	

//設問1の項目を表示
function check_radio() {
	if (document.fr.Q1[0].checked) {get_data = "Windows";}
	else {get_data = "Macintosh";}
	alert("設問1:"+get_data);
} 	
 	
//設問1のvalueを表示
function check_radio2() {
	if (document.fr.Q1[0].checked) {get_data = document.fr.Q1[0].value;}
	else {get_data = document.fr.Q1[1].value;}
	alert("設問1:"+get_data);
}

ラジオボタンの状態を調べるには、1つ1つの状態を確認するしかありません。
設問1のように選択肢が2つの場合は1つだけ調べて判断できますが、設問2のように3つ以上ある場合はfor文で必要な回数調べるのが良いでしょう。
上記例の場合、nameがQ1となっているボタンのうち「0」番(1つ目)のチェック状態をif文で調べています。

次に、ラジオボタンの状態をスクリプトで変更する方法を見てみましょう。
各ボタンを押すとスクリプトが呼び出され、上記フォームの対応したラジオボタンがチェック状態になります。

   

<input type="button" onClick="input_radio(0)" value="Spring">
<input type="button" onClick="input_radio(1)" value="Summer">
<input type="button" onClick="input_radio(2)" value="Autumn">
<input type="button" onClick="input_radio(3)" value="Winter">

<script>
function input_radio(num) {
	document.fr.Q2[num].checked = true;
}
</script>

JavaScriptでのプロパティ

document.forms[0].RADIO.length 数値 × RADIO(<input>のnameで指定した固有名)の選択肢の数
document.forms[0].RADIO[num].~   選択肢を指定するときの共通表記。1つ目が「0」
document.forms[0].RADIO[num].value 文字 <option>のvalueで指定された文字列
document.forms[0].RADIO[num].checked 条件 <option>のnum番目が選択されている場合true
document.forms[0].RADIO[num].defaultChecked 条件 <option>のnum番目が初期状態で選択されている場合true
document.forms[0].RADIO[num].disabled 条件 選択肢が使用禁止か調べたり、状態を変更します

数値/文字/条件…プロパティで入出力されるデータの種類。数値…数値のみ。文字…数値も含まれる。条件…true/false。
入…書込(入力)可能なプロパティ。
出…読込(出力)可能なプロパティ。

<input type="checkbox">

属性:name / value / checked

name チェックボックスの場合、グループ化の必要はなく。チェックされたボタンの数だけ項目名とデータが送信されます。
value 送信されるデータで、どのボタンが押されているのか識別するために必要です。
checked 初期値としてチェックボックスに印を付けます。

使用例

<form name="fc">
設問1<input type="checkbox" name="Q1" value="win" checked>Windows
		<input type="checkbox" name="Q1" value="mac">Macintosh
設問2<input type="checkbox" name="Q2" value="Spring" checked>春
		<input type="checkbox" name="Q2" value="Summer">夏
		<input type="checkbox" name="Q2" value="Autumn">秋
		<input type="checkbox" name="Q2" value="Winter">冬
</form>

設問1では、ラジオボタンと同様にnameをQ1で統一しています。
設問2の方は、nameをQ2で統一し、valueで項目名を識別しています。

表示例:
設問1 Windows Macintosh
設問2

チェックが入った項目だけが送信され、「name=value」の形式で送信されます。valueを省略しても「on」と表示されます。

JavaScriptからの入出力

  	

//設問1の項目を表示
function check_checkbox() {
	get_data = "";
	if (document.fc.Q1[0].checked) {get_data = "Windows";}
	if (document.fc.Q1[1].checked) {
		if (get_data != "") {get_data += " / ";}
		get_data += "Macintosh";
	}
	alert("設問1:"+get_data);
}
 	
//設問2のvalueを表示
function check_checkbox2() {
	get_data = "";
	for (i=0;i<4;i++) {
		if (document.fc.Q2[i].checked) {
			if (get_data != "") {get_data += " / ";}
			get_data += document.fc.Q2[i].value;
		}
	}
	alert("設問2:"+get_data);
}

チェックボックスの状態を調べるのも、ラジオボタン同様に1つ1つ確認する必要があります。
「if (get_data != "") {get_data += " / ";}」の部分は、項目をつなげるときに間に「/」を挟むための処理です。get_dataに文字列が入っている場合を調べるために、条件式ではget_dataが空でない場合を真としています。
設問2のvalueはfor文を使って4つのチェックボックスを順番に調べています。

チェックボックスを操作する場合は次のようになります。

   

<input type="button" onClick="input_checkbox(0)" value="春">
<input type="button" onClick="input_checkbox(1)" value="夏">
<input type="button" onClick="input_checkbox(2)" value="秋">
<input type="button" onClick="input_checkbox(3)" value="冬">

<script>
function input_checkbox(num) {
	document.fc.Q2[num].checked = !(document.fc.Q2[num].checked);
}
</script>

式は単純で、()は条件判断式になっており、「!」は条件の否定になっています。条件であるチェックボックスの内容がtrueなら逆のfalseを代入することになり、この1文でチェックの状態を切り換えています。

JavaScriptでのプロパティ

document.forms[0].CHECKBOX.length 数値 × CHECKBOX(<input>のnameで指定した固有名)の選択肢の数
document.forms[0].CHECKBOX[num].~   選択肢を指定するときの共通表記。1つ目が「0」
document.forms[0].CHECKBOX[num].value 文字 <option>のvalueで指定された文字列
document.forms[0].CHECKBOX[num].checked 条件 <option>のnum番目が選択されている場合true
document.forms[0].CHECKBOX[num].defaultChecked 条件 <option>のnum番目が初期状態で選択されている場合true
document.forms[0].CHECKBOX[num].disabled 条件 選択肢が使用禁止か調べたり、状態を変更します

<input type="button">

属性:value / size

value ボタンの中に表示される文字列を指定します。省略すると文字のないボタンになります。
size ボタンの横幅を指定します。

使用例

<form>
<input type="text" name="test" value="テスト">
<input type="submit">
<input type="reset">
<input type="button" value="表示">
</form>

フォームで使用できるボタンには3種類あります。
フォームのデータを送信する「submit」、フォームの内容を初期状態に戻す「reset」、決められた機能のないボタンを置くための「button」です。
それぞれ、submitボタン、resetボタン、buttonボタンと呼ぶことにします。

表示例:

上記のbuttonボタンにはvalue以外の設定がありません。そのためボタンを押しても何も起こりません。

buttonボタンにJavaScriptを組み合わせることで、ボタンに反応した動作を実行させることができるようになります。

<input type="button" value="表示" onClick="javascript:alert('表示ボタンが押されました。')">

上記の例では、ボタンを押すとイベントハンドラ「onClick」が呼び出され、記述されたスクリプトが実行されます。
下のボタンを押すと警告画面が表示されます。

表示例:

スクリプトの命令文は「javascript:alert();alert();alert()」と複数書き連ねることも可能です。

ユーザー関数の呼び出し

前項の例のようにイベントハンドラに直接命令文を記述する場合、長くて複雑なスクリプトを書くには適しません。

そこで、<script>タグと組み合わせてユーザー関数の呼び出しにボタンを利用します。

<input type="button" value="実行" onClick="goScript()">

<script>
function goScript() {
	alert("ユーザー関数が呼び出されました。");
}
</script>

下のボタンを押すと、ユーザー関数が呼び出され、警告画面が表示されます。

表示例:

複数のボタンから同じユーザー関数を呼び出したり、引数を渡してボタン毎に動作を切り替えることも可能です。

<input type="button" value="実行1" onClick="goScript(0)">
<input type="button" value="実行2" onClick="goScript(1)">
<input type="button" value="実行3" onClick="goScript(2)">

<script>
function goScript(num) {
	num++;
	if (num > 0) {
		alert("実行" + num + "が押されました。");
	}
}
</script>

下のボタンを押すと、同じユーザー関数が呼び出され、異なる警告画面が表示されます。

表示例:

JavaScriptによる事前確認と送信

送信ボタンを使わずにボタンからスクリプトの処理をしてフォームを送信することができます。
これは、送信前にフォームの入力内容を確認して、送信をキャンセルしたり、送信先を分岐させたりするのに利用されます。

<form name="fb" action="sample6-2.html" method="get">
<input type="text" name="textfield">
<input type="button" name="submit_buton" value="送信" onClick="check_submit()">
</form>

<script>
function check_submit() {
	//項目が空白の場合にアラート
	if (document.fb.textfield.value == "") {
		alert("項目が入力されていません。");
	} else {
		//ダイアログを表示
		var r = confirm("送信しても良いですか?");
		//フォームの送信
		if (r) {document.fb.submit();}
	}
}
</script>

ボタンの表示は「送信」としていますが、送信ボタン(submit)ではありません。
ボタンを押すとユーザー関数「check_submit()」が実行されます。
スクリプトでは、まず「test」項目が空白かどうかを調べています。空白ならアラートを表示し、空白でなければ次のelse以降を実行し、confirmによってダイアログが表示されます。
ダイアログで「OK」が押されると変数rにはtrueが入りますので、次のif文によりフォームの送信が実行されます。

表示例:

上記フォームの項目に適当に文字を入力し、送信ボタンを押すとダイアログが表示されます。そこで「OK」を押すとフォームが送信されます。

JavaScriptでのプロパティ

document.forms[0].BUTTON.value 文字 タグ属性のvalueで指定された文字列
document.forms[0].BUTTON.disabled 条件 選択肢が使用禁止か調べたり、状態を変更します

<input type="submit">

属性:value / size

value ボタンの中に表示される文字列を指定します。省略すると、ブラウザが「Submit」「クエリー送信」などと表示します。
size ボタンの横幅を指定します。

使用例

<form name="fs" action="sample6-2.html" method="get">
<input type="text" name="textfield" value="テスト">
<input type="submit" name="b_submit" value="送信">	
</form>

送信ボタンを押すとフォームが送信されます。

表示例:

送信の方法や送信先については<form>内のactionやmethodで指示しておきます。

上記の表示例では、送信ボタンにnameが設定されています。
そのため、送信データに「b_submit=送信」と含まれています。
動作上は、必須の物ではありませんので、余計なデータを省きたい場合は、nameを省略した方が良いでしょう。

<input type="submit" value="送信"> 

JavaScriptによる事前確認と送信

送信のための確認について2つの表現を紹介します。
1つ目は、「onKeyUp」を使ってキー入力のイベントを監視して、項目への入力があったかどうかの確認です。
もう1つは、スクリプトを使って送信前に確認処理をします。これには<form>内で 「onSubmit」を使います。

<form name="fs2" action="sample6-2.html" method="get" onSubmit="return check_submit2()" >
<input type="text" name="textfield" onKeyUp="check_field()">
<input type="submit" id="b_submit" value="送信" disabled>
</form>

<script> 	
function check_field() {
	//項目の入力状態を確認する
	document.fs2.b_submit.disabled = (document.fs2.textfield.value == "");
}
 
function check_submit2() {
	//ダイアログの表示とフォームの送信
	return confirm("送信しても良いですか?");
}
</script> 

[A] 入力状況の確認

送信ボタンは初期状態では使用不可になっています。
テキストフィールドに文字が入力されたら、ボタンを使用可能にします。

タグ内には2つの準備が必要です。
1つはテキストフィールドにイベントハンドラを組み込むことです。文字入力後にイベント処理をしたいので「onKeyUp」を使います。1文字入力する事にイベントが発生します。
もう1つは、submitボタンに名前を付けることです。これがないとスクリプトの対象を指示することが出来ません。ここではnameの代わりにidを使っています。

nameを使うと、送信データにボタン名が入ってしまいますが、idを使えばnameではないので送信データには影響がありません。
また、前項目のようにbuttonボタンを使うと、nameは送信されません。

ユーザー関数「check_field()」では、テキストフィールドが空欄かどうかを判定し、その結果をb_submitのdisabledプロパティに適用しています。

[B] 送信の事前確認

submitボタンが押されると、<form>のイベントハンドラ「onSubmit」が呼び出されます。
直接<input>の中にないイベントハンドラでも、タグの範囲内で発生したイベントを受け取ってくれます。
当然、今回のイベントは<form></form>の間にあるsubmitボタンにだけ、反応します。

「onSubmit」には返値が必要で、「return true」ならばフォームを送信し、「return false」なら送信は行いません。
そこで、ユーザー関数「check_submit2()」も「true」か「false」を「return」で戻しています。

onSubmitを使わず、スクリプト内でメソッド「submit()」を使っても送信を行うことができます。前項目buttonを参照してください。

表示例:

テキストフィールドに文字を入力して、送信ボタンを押せばダイアログが出ます。「OK」を押すとデータの送信が行われます。

onSubmitの注意点

onSubmitでユーザー関数を利用する場合、特に次のようにフォームの送信を決める戻り値を設定する場合の注意点です。

<form onSubmit="return ユーザー関数">

もし、ユーザー関数内でエラーが発生するとユーザー関数内の処理はそこで止まるのですが、フォームの送信が実行されてしまいます。
ユーザー関数内でエラーが発生しないように、関数や変数の処理には最新の注意が必要です。

submitボタンをbuttonボタンに置き換えて、onClickで処理した方が安全かも知れません。

<input type="button" onClick="ユーザー関数">

実証試験用のフォームはこちらです。

JavaScriptによるフォームの生成と送信

<form></form>タグの項目を参照してください。

<input type="reset">

属性:value / size

value ボタンの中に表示される文字列を指定します。省略すると、ブラウザが「Reset」「リセット」などと表示します。
size ボタンの横幅を指定します。

使用例

<form>
<input type="text" name="textfield" value="テスト">	
<input type="reset" value="リセット">
<br>
<input type="checkbox" name="Q2" value="Spring" checked > 春
<input type="checkbox" name="Q2" value="Summer"> 夏
<input type="checkbox" name="Q2" value="Autumn"> 秋
<input type="checkbox" name="Q2" value="Winter"> 冬
</form>

resetボタンを押すと、フォームの入力内容を初期状態に戻します。

表示例:

resetボタンはフォームを初期状態に戻すため、項目に文字が入っていた場合は再び初期の文字列に戻ります。

JavaScriptによるリセットの代用

送信のようにリセットもスクリプトから行うことができます。

<form name="fs3">
(A)<input type="text" name="a" value="ここに文字を入力" onMouseUp="reset_field()">
(B)<input type="text" name="b" onClick="reset_field()">
(C)<input type="text" name="c" onDblClick="reset_field()">
</form>

<script>
function reset_field() {
	document.fs3.reset();
}
</script>

リセットはユーザー関数「reset_field()」内の「reset()」で行っています。
3つのテキストフィールドに3種類のイベントを用意しました。どれもリセットを行います。

「onMouseUp」では、マウスで項目内をクリックした後、マウスのボタンを放した時に実行されます。
「onClick」では、マウスで項目内をクリックしたときに、イベント処理が実行されます。
「onDblClick」では、マウスで項目内をダブルクリックしたときに、イベント処理が実行されます。

表示例:
(A) (B) (C)

1つ目のテキストフィールドにはあらかじめ文字が入っています。各項目に文字を入れたり消したりして、マウスでクリックして動作確認してみましょう。

イベント処理については、別項目で詳しく解説します。

<input type="hidden">

属性:name / value

name 送信するデータのタグとなります。
value 送信するデータの内容となります。

画面には項目として表示されないタグです。cookieや前処理から引き継いだデータをフォームに隠して置いて、送信されるデータに含みたい場合に使います。

例えば、利用者を区別するために任意のID番号を与えます。書き換えられると困るので、見えないようにしておきます。送信データには含まれるので、誰が送信したのか区別することができます。
CGIにフォームを送信する場合、CGIへの命令やキーワードを明記して置くことで、1つのCGIに複数の仕事を分岐させることもできます。

使用例

<form action="sample6-2.html" method="get">
<input type="hidden" name="ID" value="007">
<input type="text" name="test" value="テスト">
<input type="submit" value="送信">
</form>

hiddenの項目はどこに置いても構いません。送信されるデータはタグの順番なので、受信側の処理の手順に合わせて順番を決めます。

表示例:

送信ボタンを押すとフォームが送信され、hiddenの項目も一緒に受信されます。

JavaScriptからの入出力

スクリプトで送信時間を作って、それをhiddenに入れて送信してみましょう。

<form name="fh" action="sample6-2.html" method="get"  onSubmit="get_time()">
<input type="hidden" name="time" value="">
<input type="text" name="test" value="テスト">
<input type="submit" value="送信">
</form>

<script>
function get_time() {
	//現在時刻の取得
	gt = new Date();
	hour = gt.getHours();
	if (hour< 10) {hour = "0" + hour;}
	min = gt.getMinutes();
	if (min< 10) {min = "0" + min;}
	sec = gt.getSeconds(); 
	if (sec< 10) {sec = "0" + sec;}
	//時間をまとめる
	gt = hour + ":" + min + ":" + sec;
	//アラートで表示
	alert(gt);
	//hiddenに入れる
	document.fh.time.value = gt;
}
</script>

hiddenの項目はどこに置いても構いません。送信されるデータはタグの順番なので、受信側の処理の手順に合わせて順番を決めます。
送信ボタンを押すとonSubmitでユーザー関数を呼び出します。
ユーザー関数「get_time()」では、時刻を取得し、成型して、アラートの表示と送信データを作っています。時分秒のそれぞれについて、一桁の場合は前に0を加えるという処理も行っています。

表示例:

送信ボタンを押すとonSubmitが実行された後でフォームが送信されます。

時間を連結するときに「:」を使わないで数字をそのまま連結する場合は次のようにします。

gt = hour + "" + min + "" + sec;

「gt = hour + min + sec」としてしまうと、文字列の結合ではなく、足し算が行われてしまうため、間に文字列を挟む必要があります。JavaScriptでは、変数の型宣言がないため、1つの変数を数値用にも文字列用にも使えます。途中で用途が自動的に変更されます。
そこで、 「""」は何もありませんが、文字列の処理とみなされるので、JavaScriptでは数値を文字列として接続するのに使うのです。

<select><option></select>

属性:name / size / multiple / disabled / value / selected

name <select>に指定します。<option>には指定できません。
size <select>で、メニューの高さを指定します。デフォルトは1で、プルダウンメニューが表示されます。2以上にすると表示の段数が増え、項目数が収まりきらない場合はスクロールバーが表示されます。
multiple <select>で、複数の項目を選択可能にします。
disabled

<select>または<option>を使用不可にします。

value <option>で、選択した項目に対応する送信内容を指示します。
selected <option>で、最初に選択される項目を指定します。

プルダウンメニューで選択項目を表示します。選択項目が多い場合に使われます。

使用例

<form name="fsel1" action="sample6-2.html" method="get" target="win_receive">
<select name="place">
<option value="25" selected>滋賀</option>
<option value="26">京都</option>
<option value="27">大阪</option>
</select>
<input type="submit" value="送信">
</form>

送信するデータの項目名は<select>内にnameで指定し、データ内容は<option>内にvalueで指定します。画面の表示は<option>タグで挟んだ文字列になります。(</option>はなくても動作します。)

表示例:

プルダウンメニューを選択して、送信してください。都道府県番号が送信されます。

次にsizeとmultipleを使ってメニューの形を変えてみましょう。

<form name="fsel2" action="sample6-2.html" method="get" target="win_receive">
<select name="place" size="3" multiple>
<option value="25" selected>滋賀</option>
<option value="26">京都</option>
<option value="27">大阪</option>
</select>
<input type="submit" value="送信">
</form>

<select>内にsizeで高さ(段数)を指定することでリストメニューになります。こちらの場合、複数行を選択することができます。

表示例:

複数の項目を選択する場合、WindowsならばCtrlキーを押しながらクリック、MacOSならcommandキーを押しながら項目をクリックします。

JavaScriptからの入出力(1)placeの切換

[A] selected で指定

  

<input type="button" onClick="sel_place(0)" value="滋賀">
<input type="button" onClick="sel_place(1)" value="京都">
<input type="button" onClick="sel_place(2)" value="大阪">

<script>
//placeの切換
function sel_place(num) { 
	//プルダウンメニュー
	document.fsel1.place[num].selected = true;
	//リストメニュー
	document.fsel2.place[num].selected = !(document.fsel2.place[num].selected);
}
</script>
  プルダウンメニュー リストメニュー
表示例:

<option>の選択項目に対して、選択のon/offをtrueとfalseで指示します。
この時、何番目の選択肢なのかインデックス番号で指示します。1つ目の選択項目が0になります。

<select>のnameで「place」が指定されていますので、これを対象にし、place[num]でその中の何番目(num)の選択肢かを指定します。
プロパティのselectedに対して、trueを与えることでその選択肢が選択状態になります。falseなら選択解除です。

フォームのfsel2については、複数選択が可能なので、fsel1の場合と同じ処理では選択が増えるばかりです。
そこで、まず「=」の右辺で、その行の現在の状態を取得して()内で条件判断します。状態を切り換えるため、trueならfalseに、falseならtrueにするので、条件を「!」で否定することで条件が逆になるので、状態を切り換えることになります。

[B] value で指定

	   	

<input type="button" onClick="sel_place2(25)" value="滋賀">
<input type="button" onClick="sel_place2(26)" value="京都">
<input type="button" onClick="sel_place2(27)" value="大阪">
<input type="button" onClick="sel_place2('')" value="解除">

<script>
//placeの切換
function sel_place2(num) { 	
	//プルダウンメニュー
	document.fsel1.place.value = num;
	//リストメニュー
	document.fsel2.place.value = num;
}
</script>

上の表示例を使ってもう1つの方法を試してみましょう。
こちらの場合、valueを使って、直接選択項目を指定しています。
インデックス番号での指定と異なり、個別に解除することができません。変数numを空で渡すことで未選択状態を作り出すことができます。

JavaScriptからの入出力(2)placeを取得

 	 	

//fsel1の現在地
function get_place() {
	var get = "";
	get += "value=" + document.fsel1.place.value + "\n";
	get += "selectedIndex=" + document.fsel1.place.selectedIndex + "\n";
	get += "text=" + document.fsel1.place[document.fsel1.place.selectedIndex].text + "\n";
 
	alert(get);
}
 
//fsel2の現在地
function get_place() {
	var get = "";
	get += "value=" + document.fsel2.place.value + "\n";
	get += "selectedIndex=" + document.fsel2.place.selectedIndex + "\n";
	get += "text=" + document.fsel2.place[document.fsel2.place.selectedIndex].text + "\n";
 
	for (i=0;i<document.fsel2.place.length;i++) {
		get += "place[" + document.fsel2.place[i].value + "]=";
		get += document.fsel2.place[i].selected + "\n";
	}
 
	alert(get);
}

重要な部分を赤字にしています。アラートでの表示用に見出しや改行を付け加えています。
「place」に対して「value」でoptionタグの値、「selectedIndex」でメニューのインデックス番号(1つ目が0)を取得しています。どちらも現在選択中のデータを取得しています。
「text」については、「document.fsel1.place.text」では選択中のメニューを表示させることができません。インデックス番号を指定して取得します。

fsel1は、プルダウンメニューでしたので選択できるのは1つだけですが、fsel2では複数選択が可能です。複数のメニューを選んだ場合、「value」や「selectedIndex」では最初の選択肢のデータのみ取得されます。
そのためfsel2では、全ての選択肢を取得するために、for文を使って選択肢の1つ1つを順番に調べる必要があります。「place.length」で選択肢の総数を取得し、「place[i]」で選択肢のi番目を指定することで、「value」と「selected」を取得しています。

valueは<option>の指定値、selectedIndexは選択中のインデックス番号、textはインデックス番号に対応した項目のテキスト、selectedは選択肢の選択状況を返しています。

JavaScriptからの入出力(3)選択肢の削除

//削除
document.fsel3.place.length = 2;

選択肢の数よりも小さい数字を「length」に入力することで、それ以降の選択肢が削除されます。
ただし、この場合は下の選択肢から消えていくことになります。選択位置での削除・挿入は後でまとめて解説します。

表示例:

JavaScriptからの入出力(4)選択肢の変更

//変更
document.fsel3.place[0].text = "兵庫"; 
document.fsel3.place[0].value = "28"; 
document.fsel3.place[1].text = "奈良"; 
document.fsel3.place[1].value = "29"; 

変更したい選択肢は、インデックス番号で指定して、「text」「value」のプロパティを指定して書き換えます。

JavaScriptからの入出力(5)選択肢の追加

//追加
document.fsel3.place.length = 3; 
//変更
document.fsel3.place[2].text = "和歌山"; 
document.fsel3.place[2].value = "30"; 

選択肢を「length」で増やしてから、新しい選択肢の「text」「value」を設定します。
上記の表示例を使って削除の後で試してください。選択肢が3つある状態から増えませんので、削除の前に実行すると3番目が書き換わるだけとなります。

JavaScriptからの入出力(6)任意の位置にある選択肢の削除と挿入

固定値を使った削除と挿入では、選択肢がいくつあるか判らない場合に対応できません。
そこで、現時点の選択肢の数を見るだけでなく、選択された位置の選択肢を削除したり、選択位置に挿入または選択位置の後ろに追加する方法をまとめて紹介します。

表示例:

メニューを選択して、各ボタンを押してください。削除を押すと、その選択肢が消えます。挿入を押すと、その選択肢の位置に新しい選択肢が現れます。追加を押すと、その選択肢の次に新しい選択肢が追加されます。
今回は、メニューの行数は1より小さくならなず、また、6より大きくならないように制限を付けておきます。

[A] 任意の位置の選択肢を削除

//選択数を取得
l_num = document.fsel4.place.length;
//選択中のインデックス番号
i_num = document.fsel4.place.selectedIndex;
//最後の1行は削除しない
if (l_num > 1) {
	//選択肢を移動
	for (n=i_num;n<l_num-1;n++) {
		document.fsel4.place[n].text = document.fsel4.place[n+1].text;
		document.fsel4.place[n].value = document.fsel4.place[n+1].value;
	}
	//削除
	document.fsel4.place.length = n;
	document.fsel4.place.size = n;
}

最初にインデックスの数を取得し、変数l_numに代入しています。
次に削除の対象となる選択中のインデックス番号を取得して、変数i_numに代入します。
if文を使って、行数が1行しかないときには、以下の処理は実行しないようにして、最後の1行を残すことにしています。
次のfor文では、選択肢をずらしています。最初の選択位置から初めて、1つ上のtextとvalueを取ってきて書き換えています。最後の行の1つ前でfor文は終わっています。
移動の後、最後の一行を削除し、メニューの高さも調節しています。

[B] 任意の位置に選択肢を挿入及び追加

 

function select_insert2(mode) {
	var l_num,i_num,n,m,count,bool;
	//選択肢の準備
	place_name = new Array("滋賀","京都","大阪","兵庫","奈良","和歌山");
	place_num = new Array(25,26,27,28,29,30);
	num = -1; //追加の要素番号
	//選択数を取得
	l_num = document.fsel4.place.length;
	//選択中のインデックス番号
	i_num = document.fsel4.place.selectedIndex;
	//上限は6行
	if (l_num < 6) {
		//番号の確認
		for (n=0;n<6;n++) {
			//numが-1より大きいときは処理しない
			if (num < 0) {
				bool = true;
				for (m=0;m<l_num;m++) {
					if (document.fsel4.place[m].value == place_num[n]) {
						//同じ番号の選択肢がある場合
						bool = false;
					}
				}
				//同じ番号の選択肢がなかった場合
				if (bool) {
					//変数numに要素番号を代入
					num = n;
				}
			}
		}
		//追加する要素番号があるとき
		if (num > -1) {
			//行の追加
			document.fsel4.place.length = l_num+1;
			document.fsel4.place.size = l_num+1;
			//選択肢を移動
			for (n=l_num;n>i_num+mode;n--) {
				document.fsel4.place[n].text = document.fsel4.place[n-1].text;
				document.fsel4.place[n].value = document.fsel4.place[n-1].value;
			}
			//表示の追加
			document.fsel4.place[i_num+mode].text = place_name[num];
			document.fsel4.place[i_num+mode].value = place_num[num];
			//選択位置の調節
			document.fsel4.place[i_num].selected = false;
			document.fsel4.place[i_num+mode].selected = true;
		}
	}
}

「挿入」と「追加」を1つのユーザー関数で処理しています。「挿入」は選択位置に、「追加」はその次の行に新しい選択肢を表示します。
赤字が必須の部分で、青字は「追加」機能のために後から加えた部分です。
かなり複雑な処理をしていますが、準備された選択肢のうちメニューにないものを調べて追加するようにしているためです。
単純に入力欄から追加するのなら、「選択肢の準備」とfor文の「番号の確認」箇所は必要なくなります。

このソースでは、functionの行から載せていますが、「挿入」と「追加」のボタンから変数modeに「0」か「1」の数値を受け取って、どちらのボタンが押されたか判るようになっています。「追加」の場合「1」になるので、最後の「表示の追加」で1つ行がずれるようになっています。
「選択肢の準備」では、2つの配列変数と1つの変数を用意しています。配列変数はもちろん、任意です。変数numは最終的にどの選択肢を追加するべきか決めるためのものです。
変数l_numと変数i_numについては削除の時と同じです。
次のif文は用意された選択肢が6つしかないため、それを超える場合には処理をしないということです。
その次のfor文で、配列変数place_numで用意した都道府県番号の数値と、メニューに存在するvalueの数値を照合しています。for文は二重になっていて、先に1つ目の要素から番号と持ってきて、その番号が使われているか調べています。使われていない場合、変数boolはtrueからfalseに置き換えられます。その変化に対応し、処理を中断したり、変数numに中断時の変数nを入れることで処理すべき都道府県を決定しています。
後半のif文で、変数numが-1より大きい場合に、「挿入」及び「追加」の処理を実行しています。
空の行を追加してから、削除の時の逆の手順で表示内容をずらし、都道府県の表示を追記しています。
最後の「選択位置の調節」は、「追加」を選んだ場合に、選択肢が元の位置から動かないための調節です。「挿入」の場合には必要ありません。

[C] 任意のテキストを挿入する場合

表示例:
//選択数を取得
l_num = document.fsel5.place.length;
//選択中のインデックス番号
i_num = document.fsel5.place.selectedIndex;
//フォームからテキストを取得
s = document.fsel5.place_name.value;
//テキストが空でない場合
if (s != "") {	
	//行の追加
	document.fsel5.place.length = l_num+1;
	document.fsel5.place.size = l_num+1;
	//選択肢を移動
	for (n=l_num;n>i_num;n--) {
		document.fsel5.place[n].text = document.fsel5.place[n-1].text;
		document.fsel5.place[n].value = document.fsel5.place[n-1].value;
	}
	//表示の追加
	document.fsel5.place[i_num].text = s;
	document.fsel5.place[i_num].value = s;
}

フォームに入力されたテキストを変数sに取得し、「表示の追加」でtextとvalueの両方に追加しています。
[B]の方法よりもかなりシンプルになりますが、入力フォームが余分に必要になります。
内部的な処理にvalueを使わない場合は、省略することも可能です。

JavaScriptでのプロパティ

document.forms[0].SELECT.length 数値 × SELECT(<select>のnameで指定した固有名)の選択肢の数
document.forms[0].SELECT.selectedIndex 数値 × 現在選択中の選択肢(<option>)の番号。複数ある場合はその中で最も小さい番号
document.forms[0].SELECT.value 文字 現在選択中のvalueを入手、もしくは指定したvalueを選択
document.forms[0].SELECT.disabled 条件 SELECTが使用禁止か調べたり、状態を変更します。trueで禁止、falseで解除
document.forms[0].SELECT[num].~   選択肢を指定するときの共通表記。1つ目が「0」
document.forms[0].SELECT.options[num].~   SELECT[num]と同じ
document.forms[0].SELECT[num].index 数値 × 選択肢の参照番号
document.forms[0].SELECT[num].value 文字 <option>のvalueで指定された文字列
document.forms[0].SELECT[num].text 文字 <option>で指定した文字列
document.forms[0].SELECT[num].selected 条件 <option>のnum番目を選択したり、選択されている場合にtrue
document.forms[0].SELECT[num].defaultSelected 条件 <option>のnum番目が初期状態で選択されている場合true
document.forms[0].SELECT[num].disabled 条件 選択肢が使用禁止か調べたり、状態を変更します。ブラウザによっては対応しません

<textarea></textarea>

属性:name / rows / cols / wrap / disabled

rows テキストフィールドの横幅を文字数で指定します。
cols テキストフィールドの高さを行数で指定します。
wrap テキストフィールドの改行について指定します。初期値はブラウザに依存します。
off=改行しない。soft=ソフトウェア制御。hard=ハードウェア制御。
readonly 読み取り専用でテキストの書き換えをできなくします。

複数行入力できるテキストフィールドです。

使用例

<form name="fta" action="sample6-2.html" method="get">
<textarea name="textarea" cols="20" rows="5">ここに
文章を入力してください。</textarea>
<input type="submit" value="送信">
<input type="reset" value="リセット">
</form>

テキストフィールド内に文字列を表示させたい場合、<input>ではvalueを使いましたが、<tetarea>ではタグの間に文章を挟みます。改行はタグを使わずにそのまま反映されます。

表示例:

JavaScriptからの入出力

 	 	

//ftaの表示
function pop_textarea() {
	alert(document.fta.textarea.value);
}
 	
//ftaに入力
function input_textarea() {
	document.fta.textarea.value = "この文章が\n表示例に\n入ります。";
}

「ftaの表示」ボタンを押すと、最初の表示例にある<textarea>の内容がアラートで表示されます。
「ftaに入力」ボタンを押すと、用意された文章に入れ替わります。改行が使えるので「\n」で指示しています。

wrapの比較

表示例:
wrap="off"
送信例: wrap_off=ここに文章を入力してください。
offの場合、自動改行は行われません。元の文章にある改行はそのまま送信されます。

offの場合、自動改行は行われません。元の文章にある改行はそのまま送信されます。

表示例:
wrap="soft"
送信例: wrap_soft=ここに文章を入力してください。
softの場合、画面上は自動改行されますが、送信データには元の改行だけが含まれます。

softの場合、画面上は自動改行されますが、送信データには元の改行だけが含まれます。

表示例:
wrap="hard"
送信例: wrap_hard=ここに文章を入力してく
ださい。
hardの場合、画面上の自
動改行に対して、送信デ
ータにも同じ位置に改行
コードが入ります。

hardの場合、画面上の自動改行に対して、送信データにも同じ位置に改行コードが入ります。

JavaScriptでのプロパティ

document.forms[0].TEXTAREA.defaultValue 文字 TEXTAREA(<textarea>のnameで指定した固有名)の初期値
document.forms[0].TEXTAREA.value 文字 TEXTAREAの値
document.forms[0].TEXTAREA.isMultiLine 条件 × 複数行入力できるかどうか判断します。タグが<textarea>なのか<input type="text">なのかの判断に使います。IEのみ

<label></label>

属性:for

for

対応する<input>のidを指定します。

ラジオボタンやチェックボックスが小さくて押しにくい場合があります。そのために、項目名を含む広い範囲でクリックできるようにするのが<label>というタグです。
項目名などテキスト部分をクリックするとラジオボタンやチェックボックスが選択されます。

もし、<label>の中に<input>を含むことができない場合は、forを使って<input>のidを指定して対応させます。

使用例

<form action="sample6-2.html" method="get" target="win_receive">
設問1
<label><input type="radio" name="Q1" value="win" checked>Windows</label>
<label><input type="radio" name="Q1" value="mac">Macintosh</label><br>
設問2
<label><input type="checkbox" name="Q2" value="Spring" checked>春(はる)</label>
<label><input type="checkbox" name="Q2" value="Summer">夏(なつ)</label>
<label><input type="checkbox" name="Q2" value="Autumn">秋(あき)</label>
<label><input type="checkbox" name="Q2" value="Winter">冬(ふゆ)</label>
<input type="submit" value="送信">
</form>

ラジオボタン、チェックボックスと項目名をそれぞれ<label>で挟んでいます。

表示例:
設問1
設問2

挟まれた範囲は入力項目と一体となってクリックすることができます。

入力項目とラベルが離れている場合は次のように記述します。

<input type="checkbox" name="Q2" id="winter" value="Winter">
<label for="winter">冬</label>

テーブルを組んだ場合など、利用の機会はあると思います。

メソッド

オブジェクトに対して、直接的に操作を実行させるための命令です。JavaScriptの処理内でフォームを直接制御することができます。

書式:「オブジェクト.メソッド(引数)」

表示例:
名前:  
使用OS:
使用用途:

上のフォームに対して、下のメソッドの一覧にあるボタンから命令を送ります。

document.forms[0].elements[0].focus() 項目にフォーカスを当てる
document.forms[0].blur()   項目のフォーカスを外す。選択状態は解除されない
document.forms[0].elements[0].select()   テキストフィールド内の文字列を選択する
document.forms[0].elements[0].click() 項目をクリックする
左の例ではMacintoshを、右の例ではメールをクリックしている
document.forms[0].elements[0].fireEvent("イベント名")   対象の項目にイベントを送信する。受け取る側にイベントハンドラがあればイベント処理が発生
例ではonclickをLinuxに送っているが、対象にonClickがないためイベント処理は発生しない。 click()と違ってクリックが発生する訳ではない
document.forms[0].submit()   フォームを送信する
document.forms[0].reset()   フォームをリセットする
document.forms[0].scrollIntoView() 指定のフォームが表示される位置までスクロールする
値がtrue(左の例)ならフォームが画面の上に、値かfalse(右の例)ならフォームが下に登場します。

イベントを発生させるメソッドについては、次のイベントハンドラでも紹介しています。

イベントハンドラ

タグ内に属性として追加することで、タグの範囲を対象にしたイベントの発生を受けて、スクリプトを実行します。

書式:「イベントハンドラ="命令文"」または「イベントハンドラ="ユーザー関数"」

記入例:「<input type="button" onClick="命令文">」「<input type="text" onKeyUp="命令文">」

処理が1行で表記できる場合は、命令文をそのまま記述し、2行以上ある場合はユーザー関数内に処理を記述します。

イベント名 イベント発生のタイミング 実例 ソース
onClick クリックしたとき <input type="text" onClick="命令文">
onClick ボタンをクリックしたとき <input type="button" onClick="命令文">
onDblClick ダブルクリックしたとき <input type="text"onDblClick="命令文">
onMouseUp マウスのボタンを放したとき <input type="text"onMouseUp="命令文">
onMouseDown マウスのボタンを押したとき <input type="text"onMouseDown="命令文">
onMouseOut マウスが対象物の上から離れたとき <input type="text"onMouseOut="命令文">
onMouseMove マウスが対象物の上で動いたとき <input type="text"onMouseMove="命令文">
onKeyUp キーを押して放すとき <input type="text"onKeyUp="命令文">
onKeyDown キーを押したとき <input type="text"onKeyDown="命令文">
onKeyPress キー入力時(カーソルキーやDelete、BSキーは反応なし) <input type="text"onKeyPress="命令文">
onSelect 文字列を選択したとき <input type="text"onSelect="命令文">
onChange 文章が変更され、フォーカスが外れたとき <input type="text"onChange="命令文">
onChange <select>メニューが変更されたとき <select onChange="命令文"><option>選択1</select>
onFocus フォーカスされたとき <input type="text"onFocus="命令文">
onBlur フォーカスが外れたとき <input type="text"onBlur="命令文">
onLoad HTMLファイルの読込終了後(<body>内に記述) <body onLoad="命令文">
onSubmit フォームの送信時(<form>内に記述) <form onSubmit="命令文">
onReset フォームをリセットしたとき(<form>内に記述) <form onReset="命令文">

スクリプトからフォームの変更を行った場合、イベントは発生しません。これは意図しないイベントが発生することを防ぐものです。
イベント処理でユーザー関数を呼び出している場合は、フォームの変更を行ったスクリプトから対象のユーザー関数を直接呼び出しましょう。
以下でテストを行います。

イベント発生テスト

→(A)onClickで変更→ →(B)onChangeで入力→ →(C)onChangeでボタンをロック  (D)

イベント処理がそれぞれ独立して発生していることを確認してみましょう。

(A)「テスト開始」ボタンを押すと、<select>メニューが切り替わる。
(B)<select>メニューを切り替えると、テキストフィールドが変更になる。
(C)テキストフィールドを変更し、フォーカスを外すと、「テスト開始」ボタンが使用不可になる。
(D)リセットボタンを押すと、フォームがリセットされ、「テスト開始」ボタンが使用可能になる。

もし、イベントが連動して起こる場合、ボタンをクリックすると、メニューが切り替わり、テキストも入れ替わり、ボタンも使用不可になってしまいます。

まず、<select>メニュー、テキストフィールドがそれぞれ単独で動作することを確認してください。
どちらもイベント処理にonChangeを使っていますが、<select>メニューは切替と同時に機能しますが、テキストフィールドは変更後にフォーカスを失うとイベントが発生します。このようにイベントのタイミングも重要です。
また、キーボードを使って<select>メニューを切り替えた場合、IEでは切替と同時にイベントが発生しますが、FirefoxではEnterキーを押さないとイベントが発生しません。

リセットボタンにはonClickを組み込んであります。通常のリセットの機能だけでは「テスト開始」ボタンが元に戻らないため、onClickでイベント処理として実行しています。

「テスト開始」ボタンを押して、各onChangeが連動しないことを確認してください。

<form name="form_event_test">
<input type="button" name="b_test" value="テスト開始" onClick="test_Click()">
→(A)onClickで変更
→<select name="s_test" onChange="javascript:document.form_event_test.t_test.value = this.value">
<option value="Spring">春</option>
<option value="Summer">夏</option>
<option value="Autumn">秋</option>
<option value="Winter">冬</option>
</select>
→(B)onChangeで入力
→<input type="text" name="t_test" value="TEST" size="20" onChange="javascript:document.form_event_test.b_test.disabled = true">
→(C)onChangeでボタンをロック
(D)<input type="reset" name="b_reset" value="リセット" onClick="javascript:document.form_event_test.b_test.disabled = false">
</form>

<script language="javascript">
function test_Click() {
	n = document.form_event_test.s_test.selectedIndex;
	n++;
	if (n > 3) {n = 0;}
	document.form_event_test.s_test[n].selected = true;
} 	
</script>

4ヶ所のイベント処理の内、3ヶ所はイベントの記述に直接スクリプトを書いています。
ボタンを押してメニューが切り替わるところだけはユーザー関数test_Clickを用いています。

<select>メニューの選択肢を取得する場合は、selectedIndexを参照し、選択肢を設定する場合にはselectedを使っています。
<select>メニューの値を取得するには、onChangeの中で、valueが使われています。

イベントを発生させるメソッド

 

//click()
//(A)クリックの発生
document.form_event_test.b_test.click();
 	
//fireEvent(onchange)
//(C)イベントの発生
document.form_event_test.t_test.fireEvent("onchange");

click()は、フォームの項目に対してクリックを発生させるので、そこにonClickが設定されている場合にイベントが発生します。onClickがなくてもクリックは行われます。
直接的にイベントハンドラを呼び出すのが、fireEvent()です。ただし、対象となる項目にイベントハンドラがない場合はイベントもエラーも発生しません。
「b_test.click()」と「b_test.fireEvent("onclick")」は同じではないので、注意してください。対象がラジオボタンやチェックボックスの場合、前者はクリックが発生するため項目が選択(もしくは解除)されますが、後者は対象にあるイベントのみが発生します。

イベントの継承とタグの実行

イベント処理が発生すると、そのイベントは同時に上位のオブジェクト(エレメント)でも発生します。
例えば、フォーム内のボタンをクリックした場合、そのイベントはボタン→フォーム→文書内へと順次発生します。

FORM 1 : ここをクリックするとフォームが反応します。

<form onClick="alert('フォーム内にクリックイベントが発生しました')" onSubmit="alert('フォームの送信イベントが発生しました')">	
<input type="text" value="クリック" onClick="alert('テキストフィールドがクリックされました')">
<input type="submit" value="クリック" onClick="alert('ボタンがクリックされました')">
</form>

FORM 1では、ボタンをクリックするとイベントが発生し、alert()が実行されます。続いて、<form>で次のイベントが発生します。
イベント処理が終了すると、タグ内の処理が行われます。
フォーム内のボタンは送信ボタン(submit)なので、イベントの後、タグの処理が行われます。(データが新しいHTMLに送られます)

FORM 2 : ここをクリックするとフォームが反応します。

<input type="submit" value="クリック" onClick="alert('ボタンがクリックされました'); return false">

FORM 2では、送信ボタンのクリックイベントに「return false」の戻り値が用意されています。
イベント処理が行われた後、送信処理が行われるはずですが、この戻り値によってタグの機能は停止しています。そのため、送信イベントが発生しないため、onSubmitにあるalert()が実行されていません。
しかし、テキストフィールドをクリックした後、エンターキー(リターンキー)を押すと送信が実行されてしまいます。

FORM 3 : ここをクリックするとフォームが反応します。

<form onClick="alert('フォーム内にクリックイベントが発生しました')" onSubmit="alert('フォームの送信イベントが発生しました'); return false">

FORM 3では、 onSubmit内に「return false」を記述しています。
クリックイベントの後、タグが実行されて送信イベントが発生し、onSubmitが実行されますが、フォームの送信はそこで中断されます。
今回はテキストフィールド内でエンターキーを押してもフォームの送信が実行されません。
スクリプト内で送信を行う場合の二重送信を防いだり、フォーム内でエンターキーに反応して不要な送信が行われることを避けることができます。

イベント活用 onSubmit

★フォームの送信を実行する場合

onSubmit="user(); return true"

★フォームの送信を実行しない場合

onSubmit="user(); return false"

★ユーザー関数から戻り値に応じて決定する場合

onSubmit="return user()"

イベント活用 onReset

★イベントをループさせない

<form onReset="document.form.reset(); user()">
<input type="reset" value="リセット">

onSubmitでは、送信時に任意の処理を行う場合、二重送信を防ぐために戻り値を設定して防ぐことができました。
onResetで同様にリセットを行おうとすると、永久にリセットイベントが発生してしまいます。そのため「Stack overflow」というエラーも発生します。
次のように、 通常ボタンからonClickで処理すると、見せかけのリセットボタンからリセットをさせて、任意の処理も行えます。

<input type="button" value="リセット" onClick="document.form.reset(); user()">

イベント活用 onClick

★アンカーの制御

リンクが開かないアンカー

アンカーにonClickを仕込んだ場合、イベント処理が終わるとリンク先へ移動します。ここでも「return false」を指定することで、アンカータグの動作を防ぐことが出来ます。

<a href="index.html" onClick="return false">リンクが開かないアンカー</a>

戻る