2010-03-24 15 views
8

Tengo dos grupos de validación: padre e hijo¿Cómo validar frente a múltiples grupos de validación?

Tengo un botón de agregar que solo necesita validar el grupo de validación del niño que se realiza fácilmente. El botón Guardar debe validarse contra los grupos de validación padre e hijo, tanto del lado del cliente como del servidor. Creo que sé cómo hacerlo desde el lado del servidor llamando al método Page.Validate ("nombre de grupo") para cada grupo, pero ¿cómo se puede hacer con el lado del cliente?

Respuesta

13

Usted debe ser capaz de lograr esto mediante la creación de una función de JavaScript que utiliza Page_ClientValidate y luego tener la llamada botón que funciona

<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

Creo que se necesita para cambiar OnClientClick para "validar volver()" –

1

Si llama Page_ClientValidate (..) dos veces, sólo el último resultado de validación se mostrará y puede estar bien mientras que el primero no. Así que la segunda llamada debe hacerse sólo si el primero ha devuelto cierto

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

    return parentOk && childOk; 
</script> 
1

De cualquier forma que lo hace la piratería requiere un poco de eludir la asunción de ASP.Net que usted no trate de hacer esto. Estoy a favor de un enfoque reutilizable que sea explícito sobre el pirateo involucrado.

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

El problema con la respuesta de CAbbott es que los errores de validación que se producen en el grupo "padre" no se mostrarán después de la llamada para validar el grupo "niño". El problema menor con la respuesta de Oleg es que la validación del grupo "hijo" no ocurrirá hasta que el grupo "padre" esté listo.

Todo lo que realmente necesitamos hacer para permitir la validación del lado del cliente de más de un grupo al mismo tiempo es anular el método Javascript IsValidationGroupMatch que determina si un control debe o no ser incluido en el conjunto actual que se está validando.

Por ejemplo:

(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');" /> 
Cuestiones relacionadas