開発者ブログ
リファレンス(仕様詳細) » 入力値チェック(バリデーション)

入力値チェック(バリデーション)

Last modified by simdy on 2018/03/28, 14:19

FormControllerでできること

  • バリデーション
  • フォーカス制御(遷移先の指定、遷移を拒否する)

フォームバリデーションの流れ

バリデーションを含むフォーム制御はFormControllerが行います。
FormControllerは、内部にFormValidatorを持ち、これによって入力値チェック(バリデーション)を行います。
また、入力エラーがある場合のエラー出力はプラグイン可能になっています(内部的には。API非公開@1.2.0)。

FormControllerのメソッド

* validate()
* addRule(name)
* removeRule(name)
* getBlankElements()
* getBlankNames()
* getFilledElements()
* getFilledNames()
* getElements();

参照:JSDoc: Class: FormController

FormControllerの挙動

  • エラー時はsubmitを行わない
  • HTML5のformによる標準のバリデーションは行わない
    • <form>にnovalidate属性を書いてもらう(無ければ自動的に付与)

TODO: ルールの書き方

* ある項目の値がXになったら⇒別の項目を必須にする、項目を出現させる等
 validChain / invalidChain

validationUpdateイベント [ver.1.3.2]

入力項目の変更、validate()メソッドが呼ばれた、など
なんらかの理由でバリデーションが実行された場合、FormControllerから「validationUpdate」イベントが発生します。
イベント引数はありません。

FormControllerに対する設定可能パラメータ

{
  isAllValidatorsEnabledWhenEmpty: /* (ver.1.3.2)trueを設定すると、すべてのバリデータについて、空文字の場合でも検出チェックを行うようになります。ただし、ルール側のisForceEnabledWhenEmptyの設定の方が優先されます(ルールのisForceEnabledWhenEmptyがfalseの場合、このパラメータをtrueにしても入力値が空の場合はそのルールは実行されません)。デフォルト値はfalseです。 */
}

バリデーションの実行タイミングの制御 [ver.1.3.2]

FormController.setPreValidationHook(func)を使用すると、バリデーションの実行を細かく制御できます。
funcには、以下のような関数をセットします。

function preValidationHook(validationContext) {
 /* validationContext = { name: (入力項目名), value: (入力値), rule: { name: (ルール名) , arg: (ルールパラメータ) }, timing: (タイミング(ValidationTiming)) } */
  validationContext.skip();  //skip()を呼び出すと、その項目のバリデーションをスキップします。
}

formController.setPreValidationHook(preValidationHook); //フック関数をセット

ルールのデフォルト挙動のオーバーライド

FormControllerの設定で、ruleDefaultを記述することで、ルールのデフォルト挙動をオーバーライドすることができます。

var setting ={
  ruleDefault: {
    required: {  /* オーバーライドするルール名をキーにする */
      isEnabledWhenEmpty: true  /* 入力値が空の場合でもこのルールを適用するかどうか */
    }
  }
}
formController.setSetting(setting);

バリデータのルールの書き方

  • 基本的なルールの書き方(HTMLの場合)
    HTML要素にdata-{ルール名}="{値}"を付加することでルールの指定が可能
 <input name="name" type="text" class="form-control" placeholder="名前" data-size="[0,16]" />

また、カスタムバリデータ(ver.1.3.2以降)を定義した場合、
「data-h5-v-(バリデータ名)」のように指定すると、そのバリデータがその要素に対して実行されます。

  • 基本的なルールの書き方(JavaScriptの場合)
    formControllerのaddRuleを使い、プロパティごとにルールのオブジェクトを指定する
this.formController.addRule({
    userid: {
        required: true,
        size: [3, 10],
        max: 20
    }
});
  • 任意のバリデーションを行う書き方
    hifiveで用意されていないバリデーションを行う場合、customFuncルールでバリデート関数を指定する
this.formController.addRule({
    birthday: {
        customFunc: function(value) {
           var y = value.year;
           var m = value.month;
           var d = value.day;
   var numRegexp = /^[0-9]+$/;
   return numRegexp.test(y) && numRegexp.test(m) && numRegexp.test(d)
&& !isNaN(new Date(y + '/' + m + '/' + d).getDate());
}
    }
});
  • 非同期バリデーションを行う書き方
    項目ごとにサーバと通信をしてバリデーションを行いたい場合など、非同期でバリデーションを行う場合も、customFuncを使用する。
    customFuncで指定する関数がpromiseを返すようにし、成功の場合はresolveを、失敗の場合は、rejectするようにしておく。
this.formController.addRule({
    userId: {
        customFunc: function(value) {
           var dfd = h5.async.deferred();
            h5.ajax('existUser', {
               type: 'GET',
               data: {
                   user: value
               },
               dataType: 'json'
           }).done(function(resp) {
              if (resp.isExist) {
                   dfd.resolve({
                       valid: true,
                       userId: value
                   });
               } else {
                   dfd.reject({
                       valid: false,
                       userId: value
                   });
               }
           });
          return dfd.promise();
}
    }
});

エラーメッセージの生成

エラーメッセージを生成する際、フォーマット文字列による生成と関数による生成が可能です。

関数の場合、下記のような仕様の関数を指定します。

function (param) {
 /* param = { name, value, rule: { ruleName, ruleValue }, violation: [{}, ...], displayName, targetViolation } */
 /* targetViolationはver.1.3.2から */
 var message = 'この項目はルール1に違反しています。';
 return message;  //最終的に表示させるエラーメッセージを返す
}

エラー出力プラグイン

FormControllerで検出したバリデーションエラーは、「出力プラグイン」を介して画面に出力することができます。
hifiveでは、以下の出力プラグインをデフォルトで提供しています。

  • Message
  • Composition
  • ErrorBalloon および BootstrapErrorBalloon
  • Style
  • AsyncIndicator

Composition出力プラグイン

この出力プラグインは、検出したすべての項目のバリデーションエラーをまとめてリスト表示します。

設定可能パラメータ:

{
  container: '#errors',  /* エラー出力先の親要素(セレクタまたはDOM要素を指定)。ここで指定された要素の子要素としてエラーを出力します。) */
  wrapper: '<li></li>',  /* 個々のエラー文字列をくるむタグ。この例だと「<li>XXは必須です。</li>」のように出力されます。 */
  showAllErrors: true,  /* (ver.1.3.2以降) trueにすると、常に、これまでに検出されたすべての項目のすべてのエラーを出力します。falseにすると、最後に行われたバリデーション結果のみを表示します。例えば、ある項目1に必須チェック、別の項目2に長さチェックが設定されており、どちらも入力値が変更されたタイミングでバリデーションが行われるように設定されていたとき、項目1で必須エラーが出ている状態で項目2のバリデーションが行われて長さエラーが検出された場合、true⇒項目1の必須エラーと項目2の長さエラーの両方を表示。false⇒項目2の長さエラーのみ表示。となります。デフォルト値はtrueです。 */
  hideWhenEmpty: true,  /* (ver.1.3.2以降) エラーが一件もない場合に、containerで指定された要素自体を非表示(display:none)に設定します。デフォルト値はfalseです。なお、エラーがある場合にはコンテナ要素に"h5-composition-has-error"クラスが付与されます。 */
  updateOn: ['validate', 'change'],  /* (ver.1.3.2以降) この出力プラグインの出力をいつ更新するかを指定します。配列で複数指定することも可能です。指定可能な値は、h5.validation.ValidationTiming列挙体の値です。デフォルトは"validate"(validate()メソッドが呼ばれたとき、またはフォームが送信される直前)です。 */
  property: {}  /* 入力項目ごとの個別設定です。 */
}

なお、showAllErrorsをtrueにした場合、エラーは1回以上フォーカスがあたった要素(厳密には「バリデーションが一度以上行われた要素」)についてのみ出力されます。なお、FormController.validate()を引数なしで呼ぶとすべての入力項目に対して("validate"のタイミングで実行すると指定された)バリデーションが実行されるので、すべての項目のすべてのエラーが出力されます。[ver.1.3.2]

入力項目ごとの個別設定:

{
  displayName: '電話番号',  /* 入力項目の表示名です。 */
  message: '{displayName}は必須です。'  /* この項目でエラーがあった場合のエラーメッセージです。決められたプレースホルダを記述すると、出力時に実際の項目名などと置き換えられます。また、関数を設定することも可能です。 */
}

エラーを画面に出力するタイミング

h5.validation.ValidationTiming列挙体で定義されています(ver.1.3.2以降)。

  • CHANGE:値が変更されたとき(input要素のchangeイベント相当)
  • VALIDATE:フォームが送信される直前、または任意にvalidate()が呼ばれたとき
  • FOCUS:フォーカスがあたったとき
  • BLUR:フォーカスが外れたとき
  • KEY_UP:キーボード入力時、キーが離されたとき

表示の仕方例

  • 特定の領域に全てのエラーをまとめて出力
  • エラー項目に対してスタイルを当てる
  • エラー項目の横や下にメッセージを表示
  • エラー項目にフォーカスが当たったら
    • エラー詳細をポップアップ表示
    • スタイル解除、エラー解除
  • エラーの項目ラベル側にスタイルを当てる
  • 非同期チェック中は送信できない
    • 送信ボタンが押せない
    • フォームをブロック
    • input, 送信ボタンがdisabled

独自のバリデーションルール(カスタムルール)を作成する方法 [ver.1.3.2]

特定のFormControllerの中でカスタムルールを作成するには、FormControllerのsettingのcustomRuleで設定します(ver.1.3.2以降)。

var setting = {
  customRule: {
    validator1: {  /* customRuleにセットするオブジェクトのキーはバリデータ名になります。バリデータの名前は[a-zA-Z][0-9a-zA-Z]* */
      func: function(value) {},  /* (必須)チェック関数です。引数には値が渡されます。エラーとみなす場合はfalse、それ以外の場合はtrueを返すようにしてください。 */
      message: '{displayName}はカスタムルール1に違反しています。' || function(param) {},  /* エラーがある場合のデフォルトのエラー文字列です。文字列または関数をセットできます。 */
      isForceEnabledWhenEmpty: true,  /* このルールを、値が空の場合にも適用するかどうかを指定します。デフォルトはfalseです。 */
      validateOn: ['validate'],  /* このルールによる「エラー検出」をいつ行うかを指定します。無指定またはnullの場合、すべてのタイミングで実行されます。 */
      resolveOn: ['change']  /* このルールの「エラー解消」をいつ行うかを指定します。validateOnで指定したタイミングは暗黙的に必ず含まれます。無指定またはnullの場合、validateOnで指定したタイミングで実行されます。 */
    }
  }
};

プラグインが実装する表示更新タイミング関数(実装していない関数は呼ばない)

var outputPluginController = {
  onValidate: function(result) {  //onValidateはinputごとでなくvalidate()の処理に対して1回だけ呼び出す
 },
  onFocus: function(element, globalSetting, setting, errorReason) { //inputごと
   if(setting.errorClass) {
      element.addClass(setting.errorClass);
    }
   else {
      addClass(global.errorClass)
    }
  }
  onBlur: function(element, errorReason) {}, //inputごと
 onChange: function(){}  //inputごと
 onKeyup: //input
 onClick:  //input
};

プラグインの追加(内部仕様)

var plugins = {};

function addOutputPlugin(pluginName, controller) {
plugins[pluginName] = controller;
}

コードイメージ

globalSetting: {
  errorClass: 'error',
  balloon: {
    showParam: xxx
  },
  allMessage: {
   container:
  }
}


outputSetting: {
  username: {  //キー名
    label: 'ユーザー名',
    formatter: func,     //省略可能

    //プラグインごとの設定オーバーライド
    balloon: {  //プラグイン名ごと
      showAt: 'right',
      timing: 'focus'
    },
    message: {
       element: ,
    },

    errorClass: 'error',  //デフォルトerror、省略可
    errorElement: '_self',  //errorClassを付与する要素、セレクタ可能 //自分自身の場合はどうする?
    messageElement: '.username.errorMessage',  //メッセージを表示する要素

    customErrorMessage: {              //Objectでなく直接Stringを渡したら、どんなエラーでもそれを表示
      required: '{label}は絶対必要です。'
    },//

    group: //電話番号みたいやなつで多分必要 何する?
  },
 
  address1: {
   
  }
}//

Validator.validate()の戻り値の型ValidationResultについて

  • バリデーション対象のすべての項目についてエラーが1件もない場合、invalidReasonは空オブジェクトになります(ver.1.3.2以降。ver.1.3.1まではnullだった。)
  • violationCount:違反したルールの総数(ver.1.3.2以降)

メモ

  • emailチェックルールについて
    • looseEmail   ..2つとかをOKにしたユルイEmailチェック
  • バリデータの種類
    • Form
    • JSon-schema
  • 非同期サポート

Copyright (C) 2012-2017 NS Solutions Corporation, All Rights Reserved.