2011-07-25 8 views
9

Salut Je suis prototpying un assistant ajax avec MVC 3 (rasoir). Une anomalie que j'ai remarqué est lorsque vous retournez une vue partielle à UpdateTargetId branche la vue mais n'ajoute/n'applique pas le JavaScript discret. Si je charge la vue partielle en dehors du bloc ajax, par ex.MVC 3, (rasoir) charge partielle avec validation

@Html.Partial("Company") 

Il fonctionne parfaitement si je ne manque aucune des bibliothèques standard et Ma config web est tout bon.

Ainsi, au moment où je suis peu perplexe.

Mon point de vue est le suivant:

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

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

Controller:

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(); 
} 

Ma question est peut la validation de la vue partielle est initalised/mis en œuvre à partir de la mise à jour partielle?

Répondre

10

Après avoir lu quelques forums et de faire quelques expériences. la dernière pièce du puzzle, ce qui a permis à la validation de fonctionner après avoir renvoyé une vue partielle. 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" /> 
} 

fonctionne parfaitement.

+0

Malheureusement, il y a un problème majeur avec cette solution - s'il vous plaît jeter un oeil à ma réponse. – chris

9

Essayez d'initialiser FormContext s'il est null dans votre vue. Cela devrait ajouter la validation discrète « -Val- de données * » attributs aux contrôles générés

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

merci, je vais y aller. – Nickz

+3

Cheers son ajouté le data-val- * discret. Maintenant, je dois trouver un moyen de déclencher la validation par ajax.beginform soumettre une action. étrangement, la validation ne déclenche pas. – Nickz

0

Il y a un gros problème avec la solution Nickz, qui m'a fait sortir mes cheveux jusqu'à ce que je trouve une autre solution.

// 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"); 

Quand vous faites cela, chaque fois que vous appelez $.validator.unobtrusive.parse(), un nouveau gestionnaire d'événements sera joint à l'événement de la présenter sous forme, tout en laissant l'ancien gestionnaire d'événements intact. Cela signifie que lorsque vous exécutez le code ci-dessus plusieurs fois, le validateur s'exécute inutilement plusieurs fois lorsque l'événement submit est déclenché. Cela a causé de graves problèmes de performance pour moi. Donc, je fini par écrire une alternative personnalisée à la méthode parse() que j'ai appelé 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"; 
       } 
      } 
     }); 
    } 

Cela mettra à jour les règles de validation de l'objet validateur existant, au lieu de forcer la création d'un nouveau validateur tout en ajoutant une somme supplémentaire de présenter gestionnaire d'événements. Dans mon option, la méthode parse() devrait fonctionner quand un validateur existe déjà.

Questions connexes