HTML5のバリテーション機能を使っておてがるバリデーションを試してみている
今日も今日とてちまちまと趣味開発のほうを進めているのですが、各種値を入力->チェック->OKかどうかを確かめる実装を各所に行わなければならず、めんどい~となっていました。
たとえば以下の画面の入力欄は「編集画面のグリッド(点々)の幅を決める」ためのものですが、プログラム上では「数値かどうか」「最小値を下回っていないか」「最大値を超えていないか」を検証しなければなりません。
そして、検証の結果、不正な値とみなせば、ユーザーにその旨伝えなければならないですが、そのための表示領域を設けたり、表示させたり、などなど面倒です。
そこで、HTML5のバリデーション機能を使ってこのような確認をやらせると楽だなと思い、今作っている趣味開発のものにおためしで実装したりしてみています。
例えばこんな感じ。最大値(max)最小値(min)必須入力項目(required)を設定しています。
<form id="confirm-form"> x: <input type="number" class="size-input" min="5" max="300" required> y: <input type="number" class="size-input" min="5" max="300" required> <div class="bottom-buttons"> <input class="button" type="submit" value="適用"> <a class="button" href="#" @click.prevent="close">閉じる</a> </div> </form> <script type="text/javascript"> document.getElementById("confirm-form").addEventListener('submit', function(e) { alert('値の検証に成功しました!'); e.preventDefault(); }); </script>
最小値や最大値に収まらない値を入力して「適用」ボタンを押すと、数値が間違っている旨メッセージが表示されます。 このメッセージはブラウザが勝手につくって表示してくれるので、別途表示領域を設けたり、警告文を作ったりする必要がないのでらくちんです。 ルールに沿った値を入力して「適用」を押せば、alertが表示されます。
(表示はブラウザによって異なります。上記はGoogle Chromeの場合)
form要素とsubmitボタンを置くことでバリデーションをさせることができますが、検証に成功するとページ遷移してしまいます。
ふつうにFormでPOST送信する場合はそれでもいいですが、JavaScriptで入力された値を使ったり、Ajaxで値を取りに行くような実装にしたいときは困ります。
そこで、e.preventDefault()
をしてあげることでデフォルトの挙動を停止し、ページ遷移を防ぐことができます。
Vue.jsで同様のことをする場合は、 @submit.prepend
としてあげることで、「適用」ボタンが押されてもフォーム送信によるページ遷移を防ぐことができます。
(唐突にVue.jsが出てきたのは、今作っている趣味開発のものがVue.js製のためです)
以下のような記述をした場合、検証に成功したら @submit
で設定したメソッド(以下の場合だと appendSettings
)が呼ばれます。
<form @submit.prepend="appendSettings"> x: <input type="number" class="size-input" min="5" max="300" required> y: <input type="number" class="size-input" min="5" max="300" required> <div class="bottom-buttons"> <input class="button" type="submit" value="適用"> <a class="button" href="#" @click.prevent="close">閉じる</a> </div> </form>
さきほどの「グリッド間隔を変更するメニュー」画面に適用するとこんな感じになりました。「適用」ボタンが隠れてしまっていますが、値を再入力することで警告ふきだしは消えます。
警告文を示す吹き出しはブラウザが勝手に作ってくれる分、警告文の文言や表示位置、デザインに融通を効かせたい場合は不都合ですが、おてがるな点が良いと思っています。
ちなみに、ブラウザによっては、この手のバリデーションに対応していなかったりしますが、趣味開発なので気にしないことにしています。
ではでは~