2010-03-24 100 views
8

我有两个验证组:父母和孩子如何验证多个验证组?

我有一个添加按钮,只需要验证轻松完成的子验证组。保存按钮需要根据父和子验证组(客户端和服务器端)进行验证。我想我知道如何通过为每个组调用Page.Validate(“groupname”)方法来实现服务器端,但是如何在客户端完成?

回答

13

你应该能够创建一个使用Page_ClientValidate JavaScript函数,然后有按钮调用该函数

<asp:Button ID="btnSave" Text="Save" OnClientClick="return validate()" runat="server" /> 

<script type="text/javascript"> 
    function validate() { 
     var t1 = Page_ClientValidate("parent"); 
     var t2 = Page_ClientValidate("child"); 

     if (!t1 || !t2) return false; 

     return true; 
    } 
</script> 
+1

我认为你需要改变的OnClientClick “回归的validate()” – 2011-01-28 16:52:02

1

如果调用Page_ClientValidate(..)来做到这一点的两倍,只有最后的验证结果被显示,并且它可以是好的,而第一个不是。所以第二个呼叫应当仅在第一返回真

<script type="text/javascript"> 
    var parentOk= Page_ClientValidate('parent'); 
    var childOk = false; 
    if (parentOk) { 
     childOk = Page_ClientValidate('child'); 
    } 

    return parentOk && childOk; 
</script> 
1

你做什么方式,它需要一些黑客获得一轮ASP.Net的假设,你会不会尝试这样做。我赞成采用可重复使用的方法,对涉及的黑客行为作出明确规定。

using System; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace WebSandbox.Validators 
{ 
    /// <summary> 
    /// <para> 
    ///  Validates a different validation group. Among the use cases envisioned are 
    ///  <list type=""> 
    ///  <item> 
    ///   Validating one set of rules when the user clicks "Save draft" and validating those rules plus some 
    ///   extra consistency checks when they click "Send". 
    ///  </item> 
    ///  <item> 
    ///   Grouping controls in a <code>fieldset</code> into a validation group with a 
    ///   <code>ValidationSummary</code> and then having a final <code>ValidationSummary</code> which tells the 
    ///   user which groups still have errors. 
    ///  </item> 
    ///  </list> 
    /// </para> 
    /// <para> 
    ///  We include checks against setting <code>GroupToValidate</code> to the same value as 
    ///  <code>ValidationGroup</code>, but we don't yet include checks for infinite recursion with one validator 
    ///  in group A which validates group B and another in group B which validates group A. Caveat utilitor. 
    /// </para> 
    /// </summary> 
    public class ValidationGroupValidator : BaseValidator 
    { 
     public string GroupToValidate 
     { 
      get { return ViewState["G2V"] as string; } 
      set { ViewState["G2V"] = value; } 
     } 

     protected override bool ControlPropertiesValid() 
     { 
      if (string.IsNullOrEmpty(GroupToValidate)) throw new HttpException("GroupToValidate not specified"); 
      if (GroupToValidate == ValidationGroup) throw new HttpException("Circular dependency"); 
      // Don't call the base, because we don't want a "control to validate" 
      return true; 
     } 

     protected override void AddAttributesToRender(HtmlTextWriter writer) 
     { 
      base.AddAttributesToRender(writer); 

      writer.AddAttribute("evaluationfunction", "ValidateValidationGroup"); 
      writer.AddAttribute("GroupToValidate", GroupToValidate); 
     } 

     protected override void OnPreRender(EventArgs e) 
     { 
      // The standard validation JavaScript is too restrictive for this validator to work, so we have to replace a key function. 
      // Fortunately this runs later than the standard JS, so we can simply overwrite the existing value of Page_ClientValidate. 
      Page.ClientScript.RegisterStartupScript(typeof(ValidationGroupValidator), "validationJS", _ValidationJS); 

      base.OnPreRender(e); 
     } 

     protected override bool EvaluateIsValid() 
     { 
      if (string.IsNullOrEmpty(GroupToValidate)) return false; 

      bool groupValid = true; 
      foreach (IValidator validator in Page.GetValidators(GroupToValidate)) 
      { 
       validator.Validate(); 
       groupValid &= validator.IsValid; 
      } 

      return groupValid; 
     } 

     private const string _ValidationJS = @"<script type=""text/javascript""> 
function ValidateValidationGroup(val) { 
    if (typeof(val.GroupToValidate) == ""string"") { 
     val.valid = PageMod_DoValidation(val.GroupToValidate); 
    } 
} 

function Page_ClientValidate(validationGroup) { 
    Page_InvalidControlToBeFocused = null; 
    if (!Page_Validators) return true; 

    var i, ctrl; 

    // Mark everything as valid. 
    for (i = 0; i &lt; Page_Validators.length; i++) { 
     Page_Validators[i].finalValid = true; 
    } 
    if (Page_ValidationSummaries) { 
     for (i = 0; i &lt; Page_ValidationSummaries.length; i++) { 
      Page_ValidationSummaries[i].finalDisplay = ""none""; 
     } 
    } 

    // Validate. 
    var groupValid = PageMod_DoValidation(validationGroup); 

    // Update displays once. 
    for (i = 0; i &lt; Page_Validators.length; i++) { 
     ctrl = Page_Validators[i]; 
     ctrl.isvalid = ctrl.finalValid; 
     ValidatorUpdateDisplay(ctrl); 
    } 
    if (Page_ValidationSummaries) { 
     for (i = 0; i &lt; Page_ValidationSummaries.length; i++) { 
      ctrl = Page_ValidationSummaries[i]; 
      ctrl.style.display = ctrl.finalDisplay; 
     } 
    } 

    ValidatorUpdateIsValid(); 
    Page_BlockSubmit = !Page_IsValid; 
    return Page_IsValid; 
} 

function PageMod_DoValidation(validationGroup) { 
    var groupValid = true, validator, i; 
    for (i = 0; i &lt; Page_Validators.length; i++) { 
     validator = Page_Validators[i]; 
     ValidatorValidate(validator, validationGroup, null); 
     validator.finalValid &amp;= validator.isvalid; 
     groupValid &amp;= validator.isvalid; 
    } 

    if (Page_ValidationSummaries) { 
     ValidationSummaryOnSubmit(validationGroup, groupValid); 

     var summary; 
     for (i = 0; i &lt; Page_ValidationSummaries.length; i++) { 
      summary = Page_ValidationSummaries[i]; 
      if (summary.style.display !== ""none"") summary.finalDisplay = summary.style.display; 
     } 
    } 

    return groupValid; 
} 
</script>"; 
    } 
} 
4

CAbbott答案的问题是在验证“子”组后发生的“父”组中出现的验证错误将不会显示。 Oleg的回答中更小的问题是,直到“父”组准备就绪后,才会对“子”组进行验证。

我们真正需要做的,以允许同时对多个组进行客户端验证,即重写Javascript IsValidationGroupMatch方法,该方法确定控件是否包含在要验证的当前集合中。

例如:

(function replaceValidationGroupMatch() { 

    // If this is true, IsValidationGroupMatch doesn't exist - oddness is afoot! 
    if (!IsValidationGroupMatch) throw "WHAT? IsValidationGroupmatch not found!"; 

    // Replace ASP.net's IsValidationGroupMatch method with our own... 
    IsValidationGroupMatch = function(control, validationGroup) { 
     if (!validationGroup) return true; 

     var controlGroup = ''; 
     if (typeof(control.validationGroup) === 'string') controlGroup = control.validationGroup; 

     // Deal with potential multiple space-delimited groups being validated 
     var validatingGroups = validationGroup.split(' '); 

     for (var i = 0; i < validatingGroups.length; i++) { 
      if (validatingGroups[i] === controlGroup) return true; 
     } 

     // Control's group not in any being validated, return false 
     return false; 
    }; 
}()); 

// You can now validate against multiple groups at once, for example: 
// space-delimited list. This would validate against the Decline group: 
// 
// Page_ClientValidate('Decline'); 
// 
// while this would validate against the Decline, Open and Complete groups: 
// 
// Page_ClientValidate('Open Decline Complete'); 
// 
// so if you wanted to validate all three upon click of a button, you'd do: 

<asp:Button ID="yourButton" runat="server" 
    OnClick="ButtonSave_Click" CausesValidation="false" 
    OnClientClick="return Page_ClientValidate('Open Decline Complete');" />