2010-03-24 10 views
8

Ho due gruppi di convalida: genitore e figlioCome convalidare gruppi di convalida multipli?

Ho un pulsante di aggiunta che deve solo convalidare il gruppo di convalida figlio che è fatto facilmente. Il pulsante di salvataggio deve essere convalidato rispetto ai gruppi di convalida padre e figlio, lato client e lato server. Penso di sapere come farlo lato server chiamando il metodo Page.Validate ("nomegruppo") per ogni gruppo, ma come può essere fatto lato client?

risposta

13

Si dovrebbe essere in grado di realizzare questo attraverso la creazione di una funzione JavaScript che utilizza Page_ClientValidate e poi avere la chiamata tasto che funziona

<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

Credo che è necessario modificare OnClientClick a "validate tornare()" –

1

Se si chiama Page_ClientValidate (..) due volte, solo il risultato dell'ultimo validazione essere mostrato e può essere OK mentre il primo non lo è. Così la seconda chiamata deve essere eseguita solo se la prima è tornata vero

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

    return parentOk && childOk; 
</script> 
1

In qualunque modo lo si fa richiede un po 'di hacking per aggirare l'ipotesi di ASP.Net che non avrebbe provare a fare questo. Sono a favore di un approccio riutilizzabile che è esplicito riguardo l'hacker coinvolto.

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

Il problema con la risposta di CAbbott è che gli errori di convalida che si verificano nel gruppo "padre" non verranno visualizzati dopo la chiamata a convalidare il gruppo "bambino". Il problema minore con la risposta di Oleg è che la convalida del gruppo "figlio" non si verificherà fino a quando il gruppo "genitore" non sarà pronto.

Tutto quello che dobbiamo veramente fare per consentire la validazione lato client di più di un gruppo allo stesso tempo è sovrascrivere il metodo JavaScript IsValidationGroupMatch che determina se un controllo deve essere incluso nel set corrente che viene validato.

Ad esempio:

(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');" /> 
Problemi correlati