web-dev-qa-db-fra.com

La validation discrète ne fonctionne pas avec Ajax.BeginForm

J'ai View avec Model1 où je mets Ajax.BeginForm() et dans cette vue j'ai PartialView avec Model2 où je mets Ajax.BeginForm(). Donc, seulement dans la première forme de travail unobtrusive validation. Pourquoi seulement lors de la première validation de travail?

première vue  

@model Model1

@using (Ajax.BeginForm("Action1","Controller",null,new AjaxOption(){ onSuccess = "alert('=)')"},null)
{

   <intput type="submit" value="Save" />
}


Model2 model2 = new Model2();
@Html.EditorFor(m=>model2)

** Dans la vue Model2, j'ai. ** 

@model Model2 
@using (Ajax.BeginForm("AddStreet","Controller",new AjaxOption(){onSuccess = "alert('=)'")},option,null)
{

        @Html.LabelFor(m => Model.Name):
        @Html.TextBoxFor(m => Model.Name)
        @Html.ValidationMessageFor(m => Model.Name)

       <intput type="submit" value="Save" />
}

Merci @Darin Dimitrov pour la réponse.  

31
Sasha Fentsyk

En effet, la deuxième vue est chargée avec AJAX ultérieurement et vous devez appeler $.validator.unobtrusive.parse(...) immédiatement après son contenu est injecté dans le DOM afin de permettre une validation discrète. Regardez le post suivant pour plus de détails.

Ainsi, dans votre cas, au lieu de alerting dans le callback OnSuccess du premier appel AJAX, abonnez-vous à une fonction javascript qui invoquera cette méthode:

@using (Ajax.BeginForm(
    "Action1",
    "Controller",
    null,
    new AjaxOptions { 
        OnSuccess = "onSuccess",
        UpdateTargetId = "result"
    },
    null)
)
{
    <input type="submit" value="Save" />
}

et ensuite dans votre fichier javascript:

var onSuccess = function(result) {
    // enable unobtrusive validation for the contents
    // that was injected into the <div id="result"></div> node
    $.validator.unobtrusive.parse($(result));
};
52
Darin Dimitrov

Vous devez ajouter ces 2 fichiers dans votre vue partielle même s'il se trouve déjà dans Shared/_Layout.cshtml:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>

Ou placez ceci dans votre Partial:

<script type="text/javascript" language=javascript>
    $.validator.unobtrusive.parse(document);
</script>
24
dperez

Vous devez ajouter une référence à jquery.unobtrusive-ajax.js pour activer la validation dans Ajax Form

Quelque chose comme ça:

<script type="text/javascript" src="/Scripts/jquery.unobtrusive-ajax.js"></script>
2
gdoron

La réponse de Darin Dimitrov ne fonctionne que lorsque validate() du jquery validate plugin n'a pas été appelé jusqu'à ce que le gestionnaire de succès Ajax soit appelé. Je ne peux pas penser à un scénario où cela pourrait être le cas, donc je me demande pourquoi la réponse a été acceptée comme correcte.

Peut-être un changement dans le code de validation jquery dans le passé provoque maintenant le problème suivant:

Le problème est que validate() exécute la ligne suivante en premier

// Check if a validator for this form was already created
var validator = $.data( this[ 0 ], "validator" );
if ( validator ) {
  return validator;

ce qui signifie que l'objet validator est renvoyé lorsque validate () est appelée sans et que les options passées .

Cela signifie également qu'un appel ultérieur à $.validator.unobtrusive.parse(...) ou $.validator.unobtrusive.parseElement(...) qui exécute une

$form.validate(this.options) <- this.options holds the new rules parsed from HTML

mettre à jour les options du validateur n'a aucun effet car les options ne sont pas traitées du tout.

La solution ici est de mettre à jour le validateur manuellement, comme

var $htmlCode = $("your html");

$.validator.unobtrusive.parse($htmlCode, true); // true means no validate() call

// now get the validation info collected in parse()
var validationInfo = $form.data("unobtrusiveValidation"); 

var $validator = $form.validate(); // get validator and ...
$validator.settings.rules = validationInfo.options.rules; // ... update its rules
$validator.settings.messages = validationInfo.options.messages; // ... update its messages

La revalidation du formulaire (par exemple, en cliquant sur Soumettre) devrait maintenant donner les résultats attendus.

Voici un exemple complet qui inclut également le code de la réponse déjà acceptée:

Rasoir

@using (Ajax.BeginForm(
    "Action1",
    "Controller",
    null,
    new AjaxOptions { 
        OnSuccess = "onSuccess",
        UpdateTargetId = "result"
    },
    null)
)
{
    <input type="submit" value="Save" />
}

Javascript

var onSuccess = function(result) {
    var $htmlCode = $(result);

    $.validator.unobtrusive.parse($htmlCode, true); // true means no validate() call

    // now get the validation info collected in parse()
    var validationInfo = $form.data("unobtrusiveValidation"); 

    var $validator = $form.validate(); // get validator and ...
    $validator.settings.rules = validationInfo.options.rules; // ... update its rules
    $validator.settings.messages = validationInfo.options.messages; // ... update its messages
};

-

De plus, il est également possible de mettre à jour manuellement le validateur en utilisant la méthode rules() comme

$yourHtmlField.rules( "add", {
  required: true,
  messages: {
    required: "Required input"
  }
});

comme cela met à jour directement les règles du validateur sans le truc discret. Mais alors les attributs data-val sont rendus inutiles.

1
ViRuSTriNiTy

Cette solution a fonctionné mieux pour moi.

$.validator.unobtrusive.parse(document);
1
JeremyFromNaples