2012-09-21 81 views
3

我一直在努力獲取多個字段的驗證以通用方式工作。我的表單有一個父跨度,其中有兩個文本字段,當一個或兩個文本字段失敗時,跨度應該用errorclass高亮顯示,在我的情況下,兩個文本字段之間有一個紅色框,當兩個字段都有效時,跨度應該不顯示。但實際的行爲是,如果第一個文本框被賦予一個有效值,jquery highlight/unhighlight函數將刪除圍繞這兩個字段的errorClass/redbox,即使第二個字段的required/regex驗證尚未通過。我寫了一個自定義的方法,併爲texboxes添加了額外的驗證規則,將tesbox分組,但沒有任何工作,我實際上是jquery的新手,無法從我現在的位置開始,所以任何幫助都是高度讚賞。Jquery - 驗證所有字段有效的多個字段(分組字段)

示例代碼在這裏

setUpValidations:函數(){

$.validator.addMethod(
     'regex', function(value, element, param) { 
      var regex = new RegExp(param); 
      return regex.test(value); 
     }, 'Regex failed' 
    ); 

    $.validator.addMethod(
     'validateGroupFields', function(value, element) { 
     var spanElement = $(element).closest('span'); 
     var spanChildren = listChildren(spanElement); 
     var result = true; 
        spanChildren.each(function(index, value) { 
      //alert("index" + index + "value" + value); 
       if((this).valid() == true) 
       { 
        $(this).siblings('div.errorbuble1').hide(); 
       }else { 
        result = false; 
       } 
      }); 
      return result; 
     }, 'Group validation failed' 
    ); 

function listChildren(element) { 
     var children = $(element).find(':input'); 
     return children; 
    }; 

    $.validator.setDefaults({ 

     highlight: function(element) { 
      $(element).closest('span').attr('class','error'); 
     }, 

     unhighlight: function(element) { 
      $(element).closest('span').attr('class',''); 
     }, 

     onfocusout: function(element, event) { 
      if (!this.checkable(element) || !this.optional(element)) { 
       this.element(element); 
       $(element).siblings('div.errorbuble1').hide(); 
      } 
     }, 

     onfocusin: function(element) { 
      if((element.name in this.submitted) && !$(element).valid()){ 
        $(element).siblings('div.errorbuble1').show(); 
      } 
     }, 

     onclick: function(element, event) { 
     // click on selects, radiobuttons and checkboxes 
      if(element.type === 'radio' || element.type === 'checkbox'){ 
       this.element(element); 
      } 
      else if((element.name in this.submitted)){ //select 
       this.element(element); 
      } 
     }, 


    }); 
}, 

onValidate : function() { 

    $('#form11').validate({ 
     errorClass: 'newError', 

     submithandler: function(form11){ 
      (form11).submit(); 
     }, 

     invalidHandler: function(form, validator) { 
     submitted = true; 
     }, 

     rules : { 
       'errorIndicator2:textField3':{ 
       required:true, 
       regex : { 
        param : /^[0-9]+$/ 
       }, 
     validateGroupFields: true 
      }, 
      'errorIndicator2:textField4':{ 
       required:true, 
       regex : { 
        param : /^[a-z]+$/ 
       }, 
       validateGroupFields: true 
      }, 
      }, 
      groups: { 
    nameGroup: "errorIndicator2:textField3 
      errorIndicator2:textField4" 
     }, 

      showErrors: function(errorMap, errorList) { 
      this.defaultShowErrors(); 
      if (submitted) { 
       $('div.errorbuble1').hide(); 
       submitted = false; 
      } 
     }, 

      errorElement: "div", 
     wrapper: "div", // a wrapper around the error message 

     errorPlacement: function(error, element) { 

      offset = element.offset(); 

      error.addClass('errorbuble1'); // add a class to the wrapper 
      error.css('position', 'absolute'); 
      error.css('left', offset.left + (element.outerWidth()) + 5); 
      error.css('top', offset.top + (element.outerHeight())/3); 
      error.insertAfter(element); 
     }, 


      var submitted = false; 
     $(document).ready(function(){ 

JavaScriptValidator.setUpValidations(); 
JavaScriptValidator.onValidate(); 

$("[type=submit]").on({ 
    click: function(event) { 
    JavaScriptValidator.onValidate(); 
    } 
    }); 
}); 


<h3>Error box around two fields:</h3> 
<span wicket:id="errorIndicator2"> 
<table> 
    <tbody><tr> 
    <td>Number:</td><td><input wicket:id="textField3" name="errorIndicator2:textField3" type="text"></td> 
    </tr> 
    <tr> 
    <td>Alpha</td><td><input wicket:id="textField4" name="errorIndicator2:textField4" type="text"></td> 
    </tr> 
</tbody></table> 
<!-- error popup div gets added here --> 

+0

你可以提供你正在使用一些樣本HTML上。可能是一個jsFiddle?我幾乎肯定你有一個'this'在你的一個函數中被誤用了。 – Qpirate

+0

我相信這是一個帶validate插件的bug - https://github.com/jzaefferer/jquery-validation/issues/364我最終不得不使用addMethod來定製一個自定義的驗證方法,該方法對於特定的分組這些投入顯然並不理想,但當時做了這項工作。 – riscarrott

回答

1

在unhighlight功能,您必須檢查是否在同一容器中的所有其他字段都有效去除錯誤之前班級從容器。類似於

$('input,select', $(element).closest('span')).not(element) 

應選擇同一容器中的所有其他表單元素。但是,您可能會遇到遞歸問題(我還沒有嘗試過您的情況,但請參閱require_from_group方法上的discssion)。

此外,你不應該通過attr方法設置類。該元素可能有其他類用於其他目的,當您設置/取消設置錯誤類時,您將刪除其他類。使用jQuery的addClass與removeClass函數來代替:

$(element).closest('span').addClass('error'); 
$(element).closest('span').removeClass('error'); 
+0

這是有用的 - 請參閱我的回答哪個地址遞歸問題 –

1

調用像元素的驗證方法(),$(...)有效的(),或形式()亮點回調中會造成死循環,但是你可以使用validator實例屬性'invalid'來維護一個無效字段列表。

$("form").validate({ 
    highlight: function (element, errorClass, validClass) { 
     $(element).closest('div.container').addClass('errorClass'); 
    }, 
    unhighlight: function (element, errorClass, validClass) { 
     var validator = this, result = true; 

     // check for invalid elements here 
     $(element).closest('div.container').find(':input').each(function() { 
      if (validator.invalid[this.name] !== undefined) { 
       result = false; 
      } 
     }); 
     if (result) { 
      $(element).closest('div.container').removeClass('errorClass') 
     } 
    } 
}); 

感謝@Adam設置我在正確的軌道fiddle here

+0

這看起來不錯。不幸的是,它不能解決我們需要重新驗證其他字段的需求組問題。有辦法避免我可能應該提到的明顯的無限循環。例如:if(!$(element).data('reval')){$(all_elements_in_group).data('reval',true); $(others_in_group).valid(); $(all_elements_in_group).data('reval',false); }但是,我的答案中仍存在遞歸問題和鏈接討論。你的解決方案對你的問題更好:) – Adam