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

j'ai Vue avec Model1 où j'ai mis Ajax.BeginForm() et dans cette vue J'ai PartialView avec Model2 où je mets Ajax.BeginForm(). Donc, seulement en première forme de travail unobtrusive validation. Pourquoi seulement en 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.

28
demandé sur Sasha Fentsyk 2012-01-19 18:40:26

5 réponses

c'est parce que la deuxième vue est chargée avec AJAX à un stade ultérieur et vous devez appeler $.validator.unobtrusive.parse(...) immédiatement après l'injection de son contenu dans le DOM afin de permettre une validation discrète. Regarder les suivant le billet de blog pour plus de détails.

Donc dans votre cas, au lieu de alertes dans le OnSuccess callback du premier appel AJAX, abonnez - vous à une fonction javascript qui va invoquer cette méthode:

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

puis, 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));
};
51
répondu Darin Dimitrov 2012-01-20 07:17:32

Vous devez ajouter ces 2 fichiers dans vous Vue Partielle même si c'est déjà dans le 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 Partielle:

<script type="text/javascript" language=javascript>
    $.validator.unobtrusive.parse(document);
</script>
23
répondu dperez 2013-01-14 01:50:32

Vous devez ajouter une référence à jquery.unobtrusive-ajax.js pour activer la validation en moins!--2-->

quelque Chose comme ceci:

<script type="text/javascript" src="/Scripts/jquery.unobtrusive-ajax.js"></script>
2
répondu gdoron 2012-01-19 14:43:59

Cette solution a fonctionné le mieux pour moi.

$.validator.unobtrusive.parse(document);
1
répondu JeremyFromNaples 2015-02-24 21:36:02

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

peut-être qu'un changement dans le code de validation jquery dans le passé cause maintenant le problème suivant:

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

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

ce qui signifie que le validator l'objet est retourné lorsque validate () est appelé sans et traitement ultérieur des options passées.

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

$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

revalidation du formulaire (p.ex. en cliquant soumettre) devrait maintenant donner les résultats attendus.

voici un exemple complet witch 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
};

--

comme note d'accompagnement, la mise à jour manuelle du validateur est également possible en utilisant le rules() méthode

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

comme ceci met directement à jour les règles du validateur sans discrète choses. Mais alors les attributs data-val sont rendus inutiles.

1
répondu ViRuSTriNiTy 2018-05-10 22:39:27