HTML5のoutput要素は計算結果と入力欄をfor属性で対応させる
公開日: 執筆:佐藤
フォーム内で計算した小計や換算値は、読み取り専用の入力欄へ入れる前にoutput要素を検討してください。output要素は計算または利用者の操作による結果を表し、for属性で、その結果に影響した入力欄を示せます。
ただし、output要素を置くだけでは計算されません。入力値を読み、結果を更新する処理はJavaScriptなどで実装します。また、画面の計算結果をそのまま注文金額として信用せず、送信後にサーバー側でも計算してください。
output要素は結果を表す
W3CのHTML5仕様にあるoutput要素は、計算または利用者の操作による結果を表します。値を入力するinput要素とは役割が違います。
次は説明用の仮例です。数量と単価から小計を表示します。
<form id="estimate-form">
<p>
<label for="quantity">数量</label>
<input id="quantity" name="quantity" type="number" min="0" value="1">
</p>
<p>
<label for="unit-price">単価</label>
<input id="unit-price" name="unit-price" type="number" min="0" value="1000">
</p>
<p>
小計
<output id="subtotal" for="quantity unit-price">1000</output>円
</p>
</form>
outputの内容は、利用者へ表示する初期値です。数量や単価を変更したときの再計算は、別の処理で行います。
for属性には計算へ使う要素のIDを書く
output要素のfor属性には、計算へ影響する要素のIDを空白で区切って書きます。上の例では、quantityとunit-priceです。
label要素のfor属性は、一つの入力欄と説明を結び付けます。output要素のfor属性は、結果と一つ以上の入力元との関係を示します。同じ属性名でも、対応させる目的が違います。
for属性は関係を示すだけです。入力値の変更を監視したり、足し算や掛け算を実行したりはしません。IDを書けば自動計算される、と考えないでください。
JavaScriptは入力を数値にしてから結果を更新する
先ほどの仮例へ、再計算処理を加えます。
<script>
(function () {
var form = document.getElementById('estimate-form');
var quantity = document.getElementById('quantity');
var unitPrice = document.getElementById('unit-price');
var subtotal = document.getElementById('subtotal');
function updateSubtotal() {
var quantityValue = Number(quantity.value);
var unitPriceValue = Number(unitPrice.value);
if (!isFinite(quantityValue) || !isFinite(unitPriceValue)) {
subtotal.value = '';
return;
}
subtotal.value = String(quantityValue * unitPriceValue);
}
form.addEventListener('input', updateSubtotal, false);
updateSubtotal();
}());
</script>
文字列のまま+を使うと、数の加算ではなく文字の連結になる場合があります。入力値を数値へ変換し、計算できない値を分けてからoutputのvalueへ入れます。
小数の丸め方、通貨の表示、税、値引き、上限は、この例へ含めていません。計算規則がある場合は、画面表示だけでなく、サーバー側で使う規則とそろえます。
form属性はフォームの外に置く場合に使う
output要素は、form属性で特定のform要素と関連付けられます。レイアウトの都合で結果をフォームの外へ置くなら、フォームのIDを指定します。
<form id="estimate-form-2">
<label for="amount">数量</label>
<input id="amount" name="amount" type="number" min="0">
</form>
<p>
計算結果
<output form="estimate-form-2" for="amount"></output>
</p>
見た目の配置だけを理由に、関係まで切らないための指定です。ただし、form属性を付けても計算処理は追加されません。
送信する入力と画面の結果を分ける
output要素は計算結果の表示に使いますが、送信後の処理が画面表示を信用してよい理由にはなりません。利用者はブラウザー上のHTMLやJavaScriptを変更できます。数量や選択項目を受け取り、単価や割引条件をサーバー側で確認して、最終金額を計算します。
制作を委託する場合は、HTML要素の実装と、金額を決める業務規則を分けて渡します。制作者がoutput要素を正しく使っても、単価、税、割引、端数処理の正本が決まっていなければ、正しい結果は作れません。
最初の一手は、既存フォームにある「入力できない結果欄」を一つ選び、その値が利用者の入力か、計算結果かを確認することです。計算結果ならoutput要素へ置き換え、for属性で入力元を示してください。
関連記事

