#htmlだけでinputの合計した入力値を出力
単純な値の計算であればonClickやonChangeで計算出来ますが複雑な計算だと
以前はjQueryなんかで要素の変更を検知したり、ライブラリーなんかで双方向データバインディングで結果を出力したりしてました
今はhtml5 のinput を使えばjavascriptを使わずに値を計算して結果を出力できることを恥ずかしながらつい最近知りました・・・
html5もcss3もちゃんと把握できていないのを最近痛感しています
Output属性
今回使うのはhtml5で追加されたOutput要素です
これを使うことでform内の値を計算して出力することが出来ます
Output - 加算
まずはAとBのinputの要素の加算です
よくあるのが買い物カゴの中身を計算する時とかに使います
oninput
oninputでform内のフィールドに値が入力された時実行します
その際にoutputに指定したname属性に計算した値の結果を入れています
parseIntで整数にしているのは変換しないと文字列連結になってしまうため整数値に一度変換しています
<form oninput="result.value = (hoge.value && fuga.value) && parseInt(hoge.value) + parseInt(fuga.value)">
<input type="number" name="hoge"> + <input type="number" name="fuga">
= <output name="result">
</form>
最終的にリファクタするとこんな感じに外部で関数化したもので評価すれば使い回せるはずです
See the Pen html output 1 by Hideto (@HidetoNagamatsu) on CodePen.
# OutPut 表示要素の切り替え今度はある一定の合計値以上に文字列を表示してみたいと思います
<script>
const add = (x,y) => {
if(!x || !y) return "";
x = parseInt(x);
y = parseInt(y);
if(x+y < 10){
return "10より小さい";
}
return "10より大きい"
}
</script>
<form oninput="result.value = add(hoge.value,fuga.value)">
<input type="number" name="hoge"> + <input type="number" name="fuga">
= <output name="result">
</form>
value値以外の文字列などのも表示できます
またif文などの判定も使えるので処理によって特定の要素のclassやスタイルを変えることもできます
See the Pen html output 2 by Hideto (@HidetoNagamatsu) on CodePen.
Output エラー時の表示
今度はinputのバリデーションエラーの文言を表示して見たいと思います
<form
oninput="result.value = hoge.validity.valid ? hoge.value : hoge.validationMessage"
>
<input type="number" name="hoge" required
oninvalid="this.setCustomValidity('入力内容が空です')"
oninput="this.validity.valid ? this.setCustomValidity('') : this.setCustomValidity('入力内容が空です')"
/>
:<output name="result"></output>
<div>
<input type="submit" />
</div>
</form>
バリデーションメッセージの表示
input要素の validity
にはバリデーションのフラグ情報が入っています
それを判別して要素が持っているバリデーション用のメッセージを表示します
oninput="result.value = hoge.validity.valid ? hoge.value : hoge.validationMessage"
バリデーションメッセージの変更
oninvalid
でsubmit時にバリデーションに引っかかればここが発火します
setCustomValidity
でバリデーションメッセージを書き換えられるので変更します
入力時にも変更したいのでoninput
イベントにもsetCustomValidity
でメッセージを書き換えます
注意しなければいけないのが、下記のように書き換えた場合です
<input type="number" name="hoge" required
oninput="this.setCustomValidity('入力内容が空です')"
/>
setCustomValidity()
で内容を書き換えると validationMessage
が書き変わるのですが
validity.valid
もfalseに変わるため常にバリデーションでエラーが出た状態になってしまいます
なので通常時は this.setCustomValidity('')
で初期化してあげる必要があります
補足
<input type="number" name="hoge" required
oninvalid="this.setCustomValidity('入力内容が空です')"
oninput="this.validity.valid ? this.setCustomValidity('') : this.setCustomValidity('入力内容が空です')"
/>
この内容だとthis.validity.valid
がfalseの時にthis.setCustomValidity()
でメッセージをセットするのはいいけど
その際validity.valid
もfalseに変わるため常にfalseになってしまっていた。。。(上で全く同じことを自分で説明しているのに・・・)
なので正しくは下記になります
<input type="number" name="hoge" required
oninvalid="this.setCustomValidity('入力内容が空です')"
oninput="
this.setCustomValidity('');
this.validity.valid ? this.setCustomValidity('') : this.setCustomValidity('入力内容が空です')
"
/>
つまり判定処理を入れる前に必ず this.setCustomValidity('')
で初期化する必要がありました・・・
See the Pen html output 3 error by Hideto (@HidetoNagamatsu) on CodePen.
複数のバリデーションエラー
まぁ、ただ単にinputとoutputを増やしただけですw
でも一番見るパターンがこれなので一応載せておきます
formの配列を回して作成するとか色々考えましたが多分、これが一番無難な作り方です
See the Pen html output 4 errors by Hideto (@HidetoNagamatsu) on CodePen.
#おまけ
ちなみにCodePenでタブなどの自動整列をしたい場合は全選択したのち shift + tab とかで綺麗になるのでオススメです