• disabled属性は送信しない値に使い確認画面で見せる入力はreadonlyと分ける

disabled属性は送信しない値に使い確認画面で見せる入力はreadonlyと分ける

公開日: 執筆:佐藤

disabled属性は、利用者に操作させないform controlへ使います。確認画面で値を見せたいからといってdisabledを付けると、その値はform送信のdataに含まれません。画面で読ませること、利用者に変更させないこと、serverへ送ることは別の役割です。確認画面で必要な値を受け取るなら、readonlyやhidden inputを含めて設計します。

HTML 5.1は、button、input、select、textareaへdisabledを指定するとform controlが無効になること、無効なcontrolはconstraint validationの対象外になることを定義しています。form送信ではdisabled controlはsuccessful controlとして扱われません。見た目を灰色にする指定と、送信dataから外す指定を同じものとして使いません。

操作できないことと送られないことを分ける

問い合わせformや注文formでは、入力を確認する画面を作ることがあります。利用者が入力した氏名、mail address、希望内容を表示し、最後に送信buttonを押す構成です。このとき、確認用のinputへdisabledを付けると、画面には値が見えても次の送信でserverへ渡りません。

説明用の仮例として、問い合わせformで「会社名」「担当者名」「相談内容」を受ける場合を考えます。入力画面ではそれぞれのinputやtextareaへ値を入れます。確認画面で編集を止めるために三つのinputをdisabledにしたとします。利用者が送信buttonを押しても、server側にはその三つの値が届かない可能性があります。画面に表示した値と、受信mailの内容が違う原因になります。

disabledは、選べない配送方法、利用できないoption、処理中に二度押しさせたくない送信buttonなどに向きます。送信buttonへ一時的に付けるなら、送信を開始した後の二重操作を抑える目的を持てます。一方で、利用者が入力した内容を確認画面へ出し、次の送信でも使うinputに付ける目的には向きません。

画面で実現したいこと まず検討する方法 送信時に確認すること
利用者に入力を変更させない readonlyを使えるinputまたはtextarea 値がrequestへ入るか
値を読ませるだけにする textとして表示し、必要ならhidden inputを置く 表示値とhidden valueが一致するか
今は選べない選択肢を示す disabledを付ける 選択肢の値を送る必要がないか
送信buttonの二度押しを抑える 送信開始後に一時的にdisabled 通信失敗時に再送できるか

この表は、hidden inputを常に使うよう勧めるものではありません。server側で入力内容を一時保存し、確認画面ではそのdataを読む構成なら、hidden inputがなくてもよい場合があります。大切なのは、画面に出す値の正本がどこにあり、最終送信で何をserverへ渡すかを決めることです。

readonlyは全てのform controlに使えるわけではない

readonlyは、入力を編集させないための属性ですが、全てのform controlへ同じように使えるものではありません。text inputやtextareaには使えますが、select、checkbox、radio buttonを操作できなくしたい場合には別の設計が必要です。見た目を変えるCSSだけで操作を止めたように見せると、keyboard操作やscriptからの操作と食い違います。

たとえば、確認画面で希望する連絡方法が「mail」「電話」のradio buttonで選ばれているとします。選択結果を読ませるだけなら、「連絡方法:mail」とtextで表示する方が分かりやすい場合があります。最終送信でその値が必要なら、server側の一時dataを使うか、値を持つhidden inputを用意します。radio buttonを無効にして画面に残す方法だけに頼ると、表示と送信dataを別に確認する必要が出ます。

住所の都道府県をselectで選ぶformも同じです。確認画面でselectをdisabledにすると、見えている選択値は送信dataに入りません。変更を許さない確認画面なら、都道府県名を文章として表示し、必要なコードや値をserver側で保持する方法を検討します。確認画面のHTMLをそのまま送信dataの正本にしない方が、途中で画面を直したときに内容が混ざりにくくなります。

readonlyのinputも、server側の検査を省く理由にはなりません。利用者はbrowserの画面を操作しなくても、requestを作って送ることができます。金額、割引率、在庫数、権限のように事業側で決める値を、readonly inputの値だけで信頼しません。server側に持つ正しい値と、利用者が送った値を照合します。

確認画面は表示用の値と受付用の値をそろえる

確認画面を作る目的は、利用者が送信前に内容を読み直せることです。画面に表示する値と、受付systemやmailへ渡す値が違えば、確認する意味がありません。確認画面を表示した直後だけでなく、送信後に届くmail、管理画面の記録、完了pageまで見ます。

説明用の仮例として、利用者が「午前中に電話を希望する」と選んだ場合を考えます。確認画面には「電話:午前中」と表示します。最終送信後に担当者へ届くmailにも同じ内容があり、受付一覧にも同じ選択が記録されるかを確認します。disabledを使ったためにmailから値が消えた、hidden inputに前の値が残った、確認画面だけ書き換わった、といった違いを見つけるためです。

formをJavaScriptで切り替える場合は、表示されていないinputにも注意します。利用者が「電話」を選んだときだけ電話番号の欄を出す構成で、隠したmail欄の古い値まで送ることがあります。逆に、必要な欄をdisabledにしてしまい、選択した値が送られないこともあります。入力欄を見せるかどうか、必須にするかどうか、送信するかどうかを、一つのCSS classだけで決めません。

確認時には、少なくとも二つの選択を使います。ひとつは短い入力、もうひとつは長い相談内容や別の選択肢です。入力画面から確認画面へ進み、戻って修正し、送信します。届いたmailと管理画面の値を確認します。短い仮の文字だけでは、textareaの改行、optionの選択、長い会社名が抜ける問題に気づきにくいためです。

二度押しを止めるbuttonは失敗時に戻せるようにする

送信buttonの二度押しを防ぐために、click後すぐdisabledへ替えることがあります。これは同じ問い合わせを何度も送る事故を減らす助けになります。ただし、通信に失敗した、server側でerrorになった、入力errorが返った場合までbuttonを無効のままにすると、利用者は修正も再送もできません。

送信開始時には、buttonだけを一時的に無効にし、「送信しています」のように状態を伝えます。成功した完了画面へ進んだら、同じformはもう使わないため、そのままでもかまいません。errorが返った場合は、どの入力を直すかを示し、buttonを再び操作できる状態へ戻します。disabledは送信済みの印ではなく、その時点で操作を受け付けない状態を表します。

JavaScriptが動かない場合にも、server側で重複送信の扱いを考えます。browserでbuttonを無効にする処理は補助です。受付番号、送信時刻、同じ内容をどう扱うかをserver側で決めなければ、画面だけで重複を完全には防げません。表示上の対策と、受付dataの扱いを分けます。

外部へform制作を頼むときは、「確認画面を付ける」だけでは足りません。どの値を見せるか、値の正本をどこに保存するか、最終送信で何が届くか、送信buttonをいつ無効にするか、error時にどう戻すかを伝えます。納品時には、入力、確認、戻る、送信、受信の順でtestした結果を受け取ります。画面を作る仕事と、問い合わせを受ける仕組みを同じ責任へ曖昧に集めないためです。

最初の一手は、確認画面にあるinput、select、textareaを一つ選び、その値が最終送信のrequestと受信mailへ入るかを確認することです。送る必要がある値ならdisabledを外し、表示用と正本の保存場所を分けます。

戻る