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

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

Last modified by kashi on 2016/04/28, 20:32

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

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

  • 基本的なルールの書き方(HTMLの場合)
    HTML要素にdata-{ルール名}="{値}"を付加することでルールの指定が可能
 <input name="name" type="text" class="form-control" placeholder="名前" data-size="[0,16]" />
  • 基本的なルールの書き方(JavaScriptの場合)
    formControllerのaddRuleを使い、プロパティごとにルールのオブジェクトを指定する
this.formController.addRule({
    userid: {
        required: true,
        size: [3, 10]
    }
});
  • 任意のバリデーションを行う書き方
    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();
}
    }
});

プラグインの種類

  • ErrorClassプラグイン
  • AllMessageプラグイン
  • ErrorMessageプラグイン
  • ErrorBalloonプラグイン

⇒それぞれはControllerとして実装

エラーを画面に出力するタイミング例(プラグインにより異なる)

  • フォーカスアウト
  • Validation失敗時、フォーカスを当てたらPopupを出す仕組み
  • 任意にvalidate()が呼ばれたとき

表示の仕方例

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

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

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について

TBD: 持っているプロパティとその説明を書く

メモ

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

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