• HTML5のoutput要素は計算結果と入力欄をfor属性で対応させる

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属性で入力元を示してください。

戻る