Ненавязчивая проверка не работает с Ajax.BeginForm

у меня есть вид с Model1, где я ставлю Ajax.BeginForm() и в этом представлении у меня есть PartialView с Model2, где я поставил Ajax.BeginForm(). Так что только в первой форме работает unobtrusive validation. Почему только в первом классе работает валидация?

первый вид

@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)

**в Model2 view у меня есть. **

@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" />
}

спасибо @Darin Dimitrov за ответ.

5 ответов


это потому, что второе представление загружается с AJAX на более позднем этапе, и вам нужно позвонить $.validator.unobtrusive.parse(...) сразу после того, как его содержимое вводится в DOM, чтобы обеспечить ненавязчивую проверку. Посмотри блоге для получения более подробной информации.

Итак, в вашем случае вместо предупреждения на OnSuccess обратный вызов первого вызова AJAX, подписаться на функцию javascript, которая будет вызывать этот метод:

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

а потом в ваш файл 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));
};

вам нужно добавить эти 2 файла в вас Частичный Вид даже если он уже находится в Общий/Файл _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>

или поместите это в ваш частичная:

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

вы должны добавить ссылку jquery.unobtrusive-ajax.js чтобы включить проверку в Ajax Form

что-то вроде этого:

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

Это решение сработало лучше всего для меня.

$.validator.unobtrusive.parse(document);

ответ Дарина Димитрова работает только тогда, когда validate() на jquery validate plugin не вызывался до тех пор, пока не будет вызван обработчик успеха Ajax. Я не могу придумать сценарий, в котором это могло бы быть так, поэтому я задаюсь вопросом, почему ответ был принят как правильный.

возможно, изменение кода проверки jquery в прошлом теперь вызывает следующую проблему:

проблема в том, что validate() сначала выполняет следующую строку

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

что означает, что объект validator возвращается, когда validate () вызывается без дальнейшей обработки переданных параметров.

это также означает, что последний вызов $.validator.unobtrusive.parse(...) или $.validator.unobtrusive.parseElement(...) выполнение

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

обновить параметры валидатора не имеет никакого эффекта, потому что вариантов не обрабатываются вообще.

решение здесь состоит в том, чтобы обновить валидатор вручную, как

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

повторная проверка формы (например, щелчок submit) теперь должны привести к ожидаемым результатам.

вот полный пример ведьма также включает в себя код из уже принятого ответа:

бритвы

@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
};

--

в качестве примечания, ручное обновление валидатора также возможно с помощью rules() методом

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

поскольку это напрямую обновляет правила валидатора без ненавязчивый материал. Но тогда атрибуты data-val становятся бесполезными.