hifiveのバリデーションを使いこなす
ユーザの入力値を検証するのはWebアプリケーションを開発する上で大事な機能です。従来はユーザの入力をサーバサイドで検証し、入力エラーがあれば再度フォームをエラーメッセージとともに表示するのが一般的でした。しかしこの場合、レンダリングにかかる時間であったり、入力を再現するのが面倒(特にファイル送信など)でした。
そこで最近ではJavaScriptを使った入力チェック(バリデーション)が使われるようになっています。もちろんサーバサイドでの入力チェックはこれまで通り必要ですが、まずJavaScript側でチェックをすることで、ユーザストレスを軽減したUXが提供できるようになります。
そこで今回はhifiveの提供する入力値検証ライブラリ、FormControllerの使い方を紹介します。
ベースとなるコントローラ
まず元になるコントローラのコードを紹介します。 .confirmをクリックすると入力値の検証を行うこととします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
var reportController = { | |
__name: 'ReportController', | |
__ready: function() { | |
}, | |
'.confirm click': function(context, $el) { | |
// 入力値の検証 | |
}, | |
}; | |
h5.core.expose(reportController); | |
})(jQuery); | |
$(function() { | |
h5.core.controller(document.body, ReportController); | |
}); |
ベースとなるHTMLについて
さらにベースとなるHTML(body内)は次のようになります。UIライブラリとしてBootstrapを読み込んでいます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<body> | |
<div class="edit container "> | |
<form class="form-horizontal"> | |
<div class="report-content"> | |
<div class="msg alert alert-danger"></div> | |
<div class="worklog"> | |
<div class="common-items row"> | |
<div class="col-sm-4"> | |
<div class="form-group"> | |
<label class="col-sm-3 control-label" for="reportDate">日付</label> | |
<div class="col-sm-9"><input id="reportDate" name="reportDate" type="date" class="form-control"></div> | |
</div> | |
</div> | |
<div class="col-sm-8"> | |
<div class="form-group"> | |
<label class="col-sm-3 control-label" for="startTime">勤務時間</label> | |
<div class="col-sm-9"> | |
<div class="input-group"> | |
<input id="startTime" name="startTime" type="time" class="form-control"> | |
<span class="input-group-addon">~</span> | |
<input id="endTime" name="endTime" type="time" class="form-control"> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="section-wrap"> | |
<div class="section"> | |
<div class="section-header row"> | |
<div class="col-sm-6"> | |
<div class="form-group"> | |
<label class="col-sm-2 control-label" for="category">報告区分</label> | |
<div class="col-sm-10"> | |
<input id="category" name="category" type="text" class="form-control"> | |
</div> | |
</div> | |
</div> | |
<div class="col-sm-6"> | |
<div class="form-group"> | |
<label class="col-sm-3 control-label" for="title">タイトル</label> | |
<div class="col-sm-9"><input id="title" name="title" type="text" class="form-control"></div> | |
</div> | |
</div> | |
</div> | |
<div class="section-content form-group"> | |
<label class="col-sm-1 control-label" for="comment">報告内容</label> | |
<div class="col-sm-11 comment"><textarea id="comment" name="comment" class="form-control"></textarea></div> | |
</div> | |
<div class="section-img form-group"> | |
<label class="col-sm-1 control-label">添付画像</label> | |
<div class="col-sm-11 img-input-wrap"> | |
<input class="form-control" accept="image/*" name="img" type="file"/> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="btn-wrap text-center"> | |
<div class="btn-group"> | |
<button class="cancel">キャンセル</button> | |
<button class="confirm">確認する</button> | |
</div> | |
</div> | |
</form> | |
</div> | |
</body> |
FormControllerを設定する
まず js/index.js
に対してFormControllerを利用する設定を行います。
元:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
var reportController = { | |
__name: 'ReportController', | |
__ready: function() { | |
: |
修正後:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
var reportController = { | |
__name: 'ReportController', | |
// バリデーションコントローラの設定 | |
_formController: h5.ui.FormController, | |
__meta: { | |
_formController: { | |
rootElement: 'form' | |
} | |
}, | |
__ready: function() { | |
: |
rootElementというのはバリデーション対象になるフォームのことです。今回はフォームが一つなので form としていますが、複数ある場合は id やクラス名で指定できます。
次に __ready
内で FormControllerの設定を行います。今回は個別の入力項目に対してエラー表示を行うstyleと、フォーム全体のエラーメッセージを表示するcompositionというプラグインを利用します。他にも
- bsBalloon
- message
- balloon
といったプラグインが用意されており、自分で新しいプラグインを作ることもできます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// バリデーションのプラグイン設定 | |
this._formController.addOutput(['style', 'composition']); |
そして、プラグインに関する設定を行います。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// バリデーションの設定 | |
this._formController.setSetting({ | |
output: { | |
style: { | |
errorClassName: 'has-error', | |
replaceElement: function(element) { | |
return $(element).closest('.form-group'); | |
} | |
}, | |
composition: { | |
container: this.$find('.msg'), | |
wrapper: 'div' | |
}, | |
}, | |
}); |
エラークラス名などはBootstrapのものを使うように指定しています。全体のエラーメッセージは .msg に対して表示するように指定しています。
バリデーションを実行する
バリデーションは確認ボタンを押したタイミングで実行します。
元:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'.confirm click': function(context, $el) { | |
// 初期化 | |
context.event.preventDefault(); | |
: |
修正後:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'.confirm click': function(context, $el) { | |
// 初期化 | |
context.event.preventDefault(); | |
// バリデーション実行 | |
if (!this._formController.validate().isValid) { | |
this.$find(".msg").show(); | |
return false; | |
} else { | |
this.$find(".msg").hide(); | |
} | |
: |
バリデーション自体は this._formController.validate()
にて実行されます。その返却値としてオブジェクトが返ってきますので、その isValid
を使ってバリデーション結果が確認できます。
バリデーションが失敗した場合は、 .msg
を可視化しつつ、処理を完了しています。バリデーションが成功した場合は .msg
を非表示にしています。
index.html の修正
続いて index.html を修正します。こちらでは入力項目に対してバリデーション条件を設定していきます。
元:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<input id="startTime" name="startTime" type="time" class="form-control"> |
修正後:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<input id="startTime" name="startTime" type="time" class="form-control" data-required /> |
このように data-required を追加するだけでstartTimeに対する必須チェックが追加されます。
同じように、
元:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<input id="category" name="category" type="text" class="form-control"> |
修正後:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<input id="category" name="category" type="text" class="form-control" data-required /> |
元:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="col-sm-9"><input id="title" name="title" type="text" class="form-control"></div> |
修正後:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="col-sm-9"><input id="title" name="title" type="text" class="form-control" data-required /></div> |
元:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="col-sm-11 comment"><textarea id="comment" name="comment" class="form-control"></textarea></div> |
修正後:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="col-sm-11 comment"><textarea id="comment" name="comment" class="form-control" data-required data-size="[10,200]" /></textarea></div> |
この報告欄については data-size も使っています。これによって10文字から200文字までの入力という制限を追加しています。
ラベルを日本語化する
ここまでの変更で試すと、エラーメッセージの一部が英語になっているのが分かるかと思います。
categoryは必須項目です
titleは必須項目です
commentは必須項目です
これでは見栄えがよくありませんので、 js/index.js
の this._formController.setSetting
に設定を追加します。
元:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
this._formController.setSetting({ | |
output: { | |
style: { | |
errorClassName: 'has-error', | |
replaceElement: function(element) { | |
return $(element).closest('.form-group'); | |
} | |
}, | |
composition: { | |
container: this.$find('.msg'), | |
wrapper: 'div' | |
}, | |
} | |
}); |
修正後:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
this._formController.setSetting({ | |
output: { | |
style: { | |
errorClassName: 'has-error', | |
replaceElement: function(element) { | |
return $(element).closest('.form-group'); | |
} | |
}, | |
composition: { | |
container: this.$find('.msg'), | |
wrapper: 'div' | |
}, | |
}, // カンマを忘れずに! | |
property: { | |
title: { | |
displayName: 'タイトル' | |
}, | |
category: { | |
displayName: '報告区分' | |
}, | |
comment: { | |
displayName: '報告内容' | |
} | |
}, | |
}); |
propertyを使って、各入力項目毎に displayName
設定を追加します。ここでラベルを設定してあげることで、入力エラーが
報告区分は必須項目です
タイトルは必須項目です
報告内容は必須項目です
といった具合に日本語化されます。
バリデーションのデモはこちらで試せます。確認ボタンをクリックするとエラーが表示されます。JavaScriptのコード自体はごく短く、設定しか記述していないのを確認してください。
バリデーションを使いこなし、よりユーザビリティの高いWebアプリケーションを目指してください!
コメントは受け付けていません。