コンテンツへスキップ

hifiveとjQuery UIを組み合わせる【バリデーション】

by : 2017/07/12

hifiveは業務システム開発に特化しているのでjQuery UIやBootstrapと組み合わせて使われることが多くなっています。そこで今回はよく使われるライブラリについて、その組み合わせ方を紹介します。

今回はバリデーションです。

デモコードについて

実際に動作するデモはJSFiddleにアップロードしてあります。入力して送信ボタンを押すとバリデーションが実行されます。

HTMLについて

HTMLは次のようになります。通常のHTMLと変わりません。


<form method="get" action="#" id="form1">
<fieldset>
<legend>アンケート</legend>
<div>
<div>好きな食べ物を選択して下さい</div>
<input type="checkbox" value="1" name="food">和食 <input
type="checkbox" value="2" name="food">中華 <input
type="checkbox" value="3" name="food">イタリアン <input
type="checkbox" value="4" name="food">フレンチ <span
class="errorMsg"></span>
</div>
<br>
<div>
<div>タバコを吸っていますか?</div>
<div>
<input type="radio" value="yes" name="conf_tobacco">はい <input
type="radio" value="no" name="conf_tobacco">いいえ <span
class="errorMsg"></span>
</div>
<br>
<div>1日の喫煙本数</div>
<div>
<input type="text" name="count"><span class="errorMsg"></span>
</div>
</div>
</fieldset>
<p>
<fieldset>
<legend>ユーザ情報登録</legend>
<div>
<div>URL(任意)</div>
<input type="text" name="url"> <span class="errorMsg"></span>
</div>
<p>
<div>
<div>ユーザID&nbsp;&nbsp;("hifive"以外を入力すると「入力されたユーザ名は既に使用されています」がエラーメッセージに表示されます)</div>
<input type="text" name="userid"> <span class="errorMsg"></span>
</div>
<div>
<div>パスワードを入力(8~12文字)</div>
<input type="password" name="pass"> <span class="errorMsg"></span>
</div>
<div>
<div>パスワードを再入力</div>
<input type="password" name="conf_pass"> <span
class="errorMsg"></span>
</div>
<br>
</fieldset>
<br />
<input type="submit" value="送信" />
</p>
</form>

view raw

index.html

hosted with ❤ by GitHub

CSSについて

CSSはエラー時の色をつけるクラスなどを追加しています。


@charset "utf-8";
#form1 {
border: 1px solid black;
padding: 15px;
}
.errorMsg {
color: red;
}
.strong {
font-weight: bold;
}
.rules {
border-collapse: collapse;
}
.rules td {
border: 1px solid black;
}

view raw

index.css

hosted with ❤ by GitHub

JavaScriptについて

JavaScriptは長いので、幾つかに分けて紹介します。まず、hifiveのコントローラ化が完了した際の__readyイベントにてバリデーションの設定を行います。


this.$find('#form1').validate({
// Submitイベントが実行された場合に、自動でバリデーションを実行
onsubmit: true,
// フォーカスが当たった場合に現在のエラー内容を一旦クリア
focusCleanup: true,
// バリデーションルール
rules: {
food: {
required: true
},
conf_tobacco: {
required: true
},
count: {
required: {
depends: '[name="conf_tobacco"][value="male"]:checked'
},
number: {
depends: '[name="conf_tobacco"][value="male"]:checked'
},
min: {
param: 1,
depends: '[name="conf_tobacco"][value="male"]:checked'
},
max: {
param: 999,
depends: '[name="conf_tobacco"][value="male"]:checked'
}
},
lastname: {
required: true
},
firstname: {
required: true
},
email: {
required: true,
email: true
},
url: {
url: true
},
userid: {
required: true,
minlength: 6,
remote: '/exists' // useridをパラメータのキーにして、/existsに結果を問い合わせる (サーバは"true"または"false"の文字列を返す必要がある)
},
pass: {
required: true,
rangelength: [8, 12]
},
conf_pass: {
equalTo: '[name="pass"]'
},
policy: {
required: true
}
},
messages: { // エラー時に表示するメッセージ
food: {
required: '1つ以上選択して下さい。'
},
conf_tobacco: {
required: '「はい」または「いいえ」のいずれかを選択して下さい'
},
count: {
required: '「はい」を選択した場合は、喫煙本数を入力して下さい',
number: '本数は数字で入力して下さい',
min: '{0}以上の値を入力して下さい',
max: '{0}以下の値で入力して下さい'
},
lastname: {
required: '姓を入力して下さい'
},
firstname: {
required: '名を入力して下さい'
},
email: {
required: 'メールアドレスを入力して下さい',
email: '正しいメールアドレスを入力して下さい'
},
url: {
url: '正しいURLを入力して下さい'
},
userid: {
required: 'ユーザIDを入力して下さい。',
minlength: '{0}以上で入力して下さい。',
remote: '入力されたユーザ名は既に使用されています'
},
pass: {
required: 'パスワードを入力して下さい',
rangelength: '{0}以上{1}文字以下で入力して下さい'
},
conf_pass: {
equalTo: 'パスワードが一致しません'
},
policy: {
required: '同意される場合はチェックを入れて下さい'
}
},
// エラーメッセージの表示先を指定する
errorPlacement: function(error, el) {
el.parent().children('.errorMsg').append(error);
},
// エラーがある要素毎に実行するコールバック
showErrors: function(errorMap, errorList) {
this.defaultShowErrors();
},
// 入力項目でエラーがあったときに実行されるハンドラ
highlight: this.ownWithOrg(this.highLightArea),
// エラーが解消されたときに実行されるハンドラ,
unhighlight: this.ownWithOrg(this.unHighLightArea),
// validateのチェックが通り、submitが行われるときに実行するハンドラ
submitHandler: this.ownWithOrg(this.submitHandler),
// validateでエラーが1つでもあると実行されるハンドラ
invalidHandler: this.ownWithOrg(this.invalidHandler),
// 入力項目でエラーが解消されるたびに実行されるハンドラ
success: this.ownWithOrg(this.successHandler)
});

view raw

index.js

hosted with ❤ by GitHub

この際、入力チェックを行う際などのイベントハンドラも設定もします。this.ownWithOrgを使うことでhifiveのコントローラ自身を渡せるようになります。


// エラーがある要素毎に実行するコールバック
showErrors: function(errorMap, errorList) {
this.defaultShowErrors();
},
// 入力項目でエラーがあったときに実行されるハンドラ
highlight: this.ownWithOrg(this.highLightArea),
// エラーが解消されたときに実行されるハンドラ,
unhighlight: this.ownWithOrg(this.unHighLightArea),
// validateのチェックが通り、submitが行われるときに実行するハンドラ
submitHandler: this.ownWithOrg(this.submitHandler),
// validateでエラーが1つでもあると実行されるハンドラ
invalidHandler: this.ownWithOrg(this.invalidHandler),
// 入力項目でエラーが解消されるたびに実行されるハンドラ
success: this.ownWithOrg(this.successHandler)

view raw

index.js

hosted with ❤ by GitHub

後は各イベントハンドラの実装になります。


// 入力項目でエラーがあったときに実行されるハンドラ
highLightArea: function(orgThis, el, error, errorClass) {
$(el).css('background-color', 'red');
},

view raw

index.js

hosted with ❤ by GitHub


// エラーが解消されたときに実行されるハンドラ,
unHighLightArea: function(orgThis, el, error, errorClass) {
var $el = $(el);
$el.css('background-color', '');
// 操作した要素が「1日の喫煙本数」テキストボックスでかつ、「たばこを吸っていますか」チェックボックスが「いいえ」の場合は、
// 「1日の喫煙本数」テキストボックスのハイライトを除去する
if ($el.is('[name="conf_tobacco"]') && this.$find('[name="conf_tobacco"]:checked').val() === 'female') {
this.$find('[name="count"]').css('background-color', '');
}
},

view raw

index.js

hosted with ❤ by GitHub


// validateのチェックが通り、submitが行われるときに実行するハンドラ
submitHandler: function(orgThis, form, ev) {
alert('FORMの内容をサーバに送信します。');
form.submit();
},

view raw

index.js

hosted with ❤ by GitHub


// validateでエラーが1つでもあると実行されるハンドラ
invalidHandler: function(orgThis, ev, validator) {
alert('入力内容に誤りがあります。');
},

view raw

index.js

hosted with ❤ by GitHub


// 入力項目でエラーが解消されるたびに実行されるハンドラ
successHandler: function(orgThis, errMsgElement, inputElement) {
if (window.console) {
console.log('入力OK: '+ inputElement.name);
}
},

view raw

index.js

hosted with ❤ by GitHub

最後にチェックボックス、ラジオボタンのバリデーションについて別途実装します。


//「好きな食べ物を選択して下さい」のバリデーション
'[name="food"] click': function(context, $ct) {
// input[name="food"]の要素に対してバリデーションを実行する
$ct.valid();
},
//「1日の喫煙本数」テキストボックスのバリデーション
'[name="count"] focusout': function(context, $ct) {
// input[name="count"]の要素に対してバリデーションを実行する
$ct.valid();
}

view raw

gistfile1.txt

hosted with ❤ by GitHub


$(function() {
h5.core.controller('body', {
__name: 'sample.plugin.validationSampleController',
__ready:function() {
// バリデーターにルールやメッセージ等を設定
this.$find('#form1').validate({
// Submitイベントが実行された場合に、自動でバリデーションを実行
onsubmit: true,
// フォーカスが当たった場合に現在のエラー内容を一旦クリア
focusCleanup: true,
// バリデーションルール
rules: {
food: {
required: true
},
conf_tobacco: {
required: true
},
count: {
required: {
depends: '[name="conf_tobacco"][value="yes"]:checked'
},
number: {
depends: '[name="conf_tobacco"][value="yes"]:checked'
},
min: {
param: 1,
depends: '[name="conf_tobacco"][value="yes"]:checked'
},
max: {
param: 999,
depends: '[name="conf_tobacco"][value="yes"]:checked'
}
},
url: {
url: true
},
// useridをパラメータのキーにして、/existsに結果を問い合わせる
// サーバは"true"または"false"の文字列を返す必要がある
userid: {
required: true,
minlength: 6,
remote: '/exists'
},
pass: {
required: true,
rangelength: [8, 12]
},
conf_pass: {
equalTo: '[name="pass"]'
},
policy: {
required: true
}
},
messages: { // エラー時に表示するメッセージ
food: {
required: '1つ以上選択して下さい。'
},
conf_tobacco: {
required: 'はい、またはいいえを選択して下さい'
},
count: {
required: '「はい」を選択した場合は、喫煙本数を入力して下さい',
number: '本数は数字で入力して下さい',
min: '{0}以上の値を入力して下さい',
max: '{0}以下の値で入力して下さい'
},
url: {
url: '正しいURLを入力して下さい'
},
userid: {
required: 'ユーザIDを入力して下さい。',
minlength: '{0}以上で入力して下さい。',
remote: '入力されたユーザ名は既に使用されています'
},
pass: {
required: 'パスワードを入力して下さい',
rangelength: '{0}以上{1}文字以下で入力して下さい'
},
conf_pass: {
equalTo: 'パスワードが一致しません'
}
},
// エラーメッセージの表示先を指定する
errorPlacement: function(error, el) {
el.parent().children('.errorMsg').append(error);
},
// エラーがある要素毎に実行するコールバック
showErrors: function(errorMap, errorList) {
this.defaultShowErrors();
},
// 入力項目でエラーがあったときに実行されるハンドラ
highlight: this.ownWithOrg(this.highLightArea),
// エラーが解消されたときに実行されるハンドラ,
unhighlight: this.ownWithOrg(this.unHighLightArea),
// validateのチェックが通り、submitが行われるときに実行するハンドラ
submitHandler: this.ownWithOrg(this.submitHandler),
// validateでエラーが1つでもあると実行されるハンドラ
invalidHandler: this.ownWithOrg(this.invalidHandler),
// 入力項目でエラーが解消されるたびに実行されるハンドラ
success: this.ownWithOrg(this.successHandler)
});
},
highLightArea: function(orgThis, el, error, errorClass) {
$(el).css('background-color', 'red');
},
unHighLightArea: function(orgThis, el, error, errorClass) {
var $el = $(el);
$el.css('background-color', '');
// 操作した要素が「1日の喫煙本数」テキストボックスでかつ、「たばこを吸っていますか」チェックボックスが「いいえ」の場合は、
// 「1日の喫煙本数」テキストボックスのハイライトを除去する
if ($el.is('[name="conf_tobacco"]') && this.$find('[name="conf_tobacco"]:checked').val() === 'no') {
this.$find('[name="count"]').css('background-color', '');
}
},
submitHandler: function(orgThis, form, ev) {
alert('FORMの内容をサーバに送信します。');
form.submit();
},
invalidHandler: function(orgThis, ev, validator) {
alert('入力内容に誤りがあります。');
},
successHandler: function(orgThis, errMsgElement, inputElement) {
if (window.console) {
console.log('入力OK: '+ inputElement.name);
}
},
//「好きな食べ物を選択して下さい」のバリデーション
'[name="food"] click': function(context, $ct) {
// input[name="food"]の要素に対してバリデーションを実行する
$ct.valid();
},
//「1日の喫煙本数」テキストボックスのバリデーション
'[name="count"] focusout': function(context, $ct) {
// input[name="count"]の要素に対してバリデーションを実行する
$ct.valid();
}
});
});

view raw

index.js

hosted with ❤ by GitHub


hifiveでもvalidation機能を提供していますが、使い慣れた方を採用するケースもあるでしょう。そうした時にはコールバックの管理などはhifiveで行うことで、よりメンテナンスしやすいバリデーション実装ができるようになります。

実際に動作するデモはJSFiddleにアップロードしてあります。お試しください。

From → hifive

コメントは受け付けていません。

%d人のブロガーが「いいね」をつけました。