学んだことをメモする日記

主にpythonについて自分が学んだことについてのメモ帳。理解が深まればいいんだけれども・・・

LiveValidationでID重複チェックを使う

タイトルの通り、LiveValidation - Validation as you typeでユーザーIDの重複チェックを行えるようにしてみた。

理想はTwitterの登録画面で、LiveValidationはフォームの隣にシンプルに結果を表示しているので採用した。

基本的な使い方は、

var user_id = new LiveValidation('id', {validMessage: "valid", wait: 200});
  user_id.add(Validate.Presence, {failureMessage: "invalid"});

みたいな感じで、自分で作った関数を組み込むには

  user_id.add(Validate.Custom, {failureMessage: "invalid", against: function(){return result}});

みたいにValidate.Customで行う。

ここから、ユーザーIDの重複機能を組み込むとなると組み込む関数の返り値が、ブール値のため確認中のメッセージを表示できないと思って一旦ドツボにはまる。解決策として、組み込む関数中にValidate.Errorで例外を投げることで対応できた。結局、グローバルな変数を使うなど下手な感じだけど完成。以下にコード。

  var jqxhr = null;
  var old_value = null;
  var result = false;
  var error_message = 'ユーザーIDの重複をチェックしています。';
  var is_duplicate = function(value, args){
    if(value != old_value){
      old_value = value;
      if(jqxhr)jqxhr.abort();
      jqxhr = $.ajax({
        type: "POST",
        url: '/check',
        data: {user_id: value},
        success: function(data){
          result = data == 'true';
          args.obj.is_check = false;
          args.obj.validate();
        }
      });
      args.obj.is_check = true;
      throw new Validate.Error(error_message);
    }
    if(args.obj.is_check) throw new Validate.Error(error_message);
    return result;
  }

また、これだけだと、確認中のメッセージなどに気に入らない点があったので、LiveValidationのコードをいじるために以下を追加。

  LiveValidation.prototype.is_check = false;
  LiveValidation.prototype.doOnFocus = function(e){
    this.focused = true;
  }
  LiveValidation.prototype.insertMessage = function(elementToInsert){
    this.removeMessage();
    if( (this.displayMessageWhenEmpty && (this.elementType == LiveValidation.CHECKBOX || this.element.value == '')) || this.element.value != '' ){
      var className = this.validationFailed ? this.invalidClass : this.validClass;
      if(this.is_check)elementToInsert.className += ' ' + this.messageClass;
      else elementToInsert.className += ' ' + this.messageClass + ' ' + className;
      if(this.insertAfterWhatNode.nextSibling){
        this.insertAfterWhatNode.parentNode.insertBefore(elementToInsert, this.insertAfterWhatNode.nextSibling);
      }else{
        this.insertAfterWhatNode.parentNode.appendChild(elementToInsert);
      }
    }
  }

そして、スタイルシートを下記のようにいじって終了。

.LV_validation_message{
  color: #666666;
}
.LV_valid {
  color: #009900;
}
.LV_invalid {
  color: #CC0000;
}

なんとか、フルスクラッチで作らずにすんだ・・・