2011-07-25 12 views
9

Hola, estoy prototipando un asistente de ajax con MVC 3 (cuchilla de afeitar). Una rareza que he notado es cuando devuelves una vista parcial a UpdateTargetId para enchufar la vista, pero no agrega/aplica el JavaScript discreto. Si cargo la vista parcial fuera del bloque ajax, p.MVC 3, (cuchilla de afeitar) carga parcial con validación

@Html.Partial("Company") 

Funciona perfectamente, así que no me falta cualquiera de las bibliotecas estándar y Mi web.config es todo bueno.

Así que por el momento estoy poco perplejo.

Mi opinión es la siguiente:

@using(Ajax.BeginForm("Step", "Origination", new AjaxOptions { UpdateTargetId = "stepArea" })){ 

    <div id="stepArea"></div> 
    <input id="btnSubmit" type="submit" value="submit" /> 
} 

controlador:

public ActionResult Step(FormCollection formCollection) 
{ 
    if (this.Request.IsAjaxRequest()) 
    { 
     switch ((TempData["step"] as string)) 
     { 
      case "Company": 
       TempData["step"] = "Person"; 
       return PartialView("Company"); 

      case "Person": 
       TempData["step"] = "Pay"; 
       return PartialView("Person"); 

      case "Settlement": 
       return PartialView("Pay"); 

      default: 
       TempData["step"] = "Company"; 
       return PartialView("UserType"); 
     } 
    } 
    return View(); 
} 

Mi pregunta es ¿puede la validación de la visión parcial se initalised/implementada desde la actualización parcial?

Respuesta

10

Después de leer algunos foros y haciendo algunos experimentos. la pieza final del rompecabezas, haciendo que la validación funcione después de devolver una vista parcial. jquery.validate.unobtrusive not working with dynamic injected elements

<script type="text/javascript"> 

    function validateAjaxForm() { 
     $("form").removeData("validator"); 
     $("form").removeData("unobtrusiveValidation"); 
     $.validator.unobtrusive.parse("form"); 
     return $('#form').valid(); 
    } 
</script> 


@{ Html.EnableClientValidation(true); } 
@using (Ajax.BeginForm("Step", "Origination", new AjaxOptions { UpdateTargetId = "stepArea", OnBegin = "return validateAjaxForm();" }, new { id = "form" })) 
{ 
    <div id="stepArea"></div> 
    <input id="btnSubmit" type="submit" value="submit" /> 
} 

funciona perfectamente.

+0

Lamentablemente, hay un problema importante con esa solución: por favor, eche un vistazo a mi respuesta. – chris

9

Intente inicializar FormContext si es nulo en su vista. Esto se debe añadir la validación discreta "datos-Val- *" atribuye a los controles generados

@{ 
    if (Html.ViewContext.FormContext == null) 
    { 
     Html.ViewContext.FormContext = new FormContext(); 
    } 
} 
+2

gracias Lo daré. – Nickz

+3

Cheers se agregó el discreto data-val- *. Ahora necesito encontrar una manera de hacer que la validación se active mediante ajax.beginform submit action. Curiosamente, la validación no es desencadenante. – Nickz

0

Hay un gran problema con la solución de Nickz, que me hizo sacar el pelo hasta que encontré una solución diferente.

// forces creation of a new validator, which in turn causes 
    // an extra submit event handler to be attached!!! 
    $("form").removeData("validator"); 
    $("form").removeData("unobtrusiveValidation"); 
    $.validator.unobtrusive.parse("form"); 

Cuando se hace esto, cada vez que llame $.validator.unobtrusive.parse(), un nuevo controlador de eventos se adjuntará a presentar eventos del formulario, dejando intacto el antiguo controlador de eventos. Esto significa que cuando ejecuta el código anterior varias veces, el validador se ejecutará innecesariamente varias veces cuando se active el evento de envío. Esto me causó severos problemas de rendimiento. Así que terminé escribiendo una alternativa personalizada para el método parse() que llamé updateParse:

$.extend($.validator.unobtrusive, { 
    updateParse: function (selector) { 
     /// <summary> 
     /// Custom alternative for the built in method $.validator.unobtrusive.parse() which can updates an existing validator. 
     /// Use this only when a validator has not yet been initialized, i.e. when $.validator.unobtrusive.parse() 
     /// has not yet been called before. 
     /// This is intended for use after you dynamically add/remove/modify validatable elements to a form via AJAX. 
     /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 
     /// with the [data-val=true] attribute value and enables validation according to the data-val-* 
     /// attribute values. 
     /// </summary> 
     /// <param name="selector" type="String">Any valid jQuery selector.</param> 
     var $forms = $(selector) 
      .parents("form") 
      .andSelf() 
      .add($(selector).find("form")) 
      .filter("form"); 

     $(selector).find(":input[data-val=true]").each(function() { 
      $.validator.unobtrusive.parseElement(this, true); 
     }); 

     $forms.each(function() { 
      var form = $(this); 
      var info = form.data("unobtrusiveValidation"); 
      if (info) { 
       var validator = form.data("validator"); 
       if (validator) { 
        validator.settings.rules = info.options.rules; 
       } 
       else { 
        throw "validator not yet initialized for this form yet -- use $.validator.unobtrusive.parse() instead"; 
       } 
      } 
     }); 
    } 

Esto actualizará las reglas de validación del objeto validador existente, en vez de forzar la creación de un nuevo validador al tiempo que añade un extra de presentar controlador de eventos. En mi opción, el método parse() debería funcionar cuando ya existe un validador.

Cuestiones relacionadas