Добавить ошибку в JQuery Ненавязчивое резюме проверки без ключа

У меня есть форма, которая использует ненавязчивую проверку JQuery вместе с резюме проверки. Он отлично работает. Однако эта форма выполняет AJAX POST, который возвращает результат JSON. Если результат == true, я продолжаю. Однако, если результат JSON возвращает массив сообщений, я хочу запустить проверку формы для обновления полей. Ошибки возвращаются следующим образом:

{
    "errors": [ 
       { "key" : "NameFirst", "message": "This is the message" },
       { "key" : "NameLast", "message": "This is the message" } 
     ]
}

Я разбираю результат JSON и вызываю showErrors() следующим образом:

for (var j = 0; j < response.errors.length; j++) {
    var key = response.errors[j].key;
    var error = {};
    error[key] = response.errors[j].message;
    $form.data('validator').showErrors(error);
}

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

Кроме того, иногда ошибки являются общими и не сопоставляются с определенным свойством/полем в модели. В этом случае они возвращаются с нулевыми ключами, например:

{
     "errors": [ 
        { "key" : null, "message": "This is the message" },
        { "key" : null, "message": "This is the other message" }, 
        { "key" : "NameFirst", "message": "This is the message" },
        { "key" : "NameLast", "message": "This is the message" } 
      ]
 }

Я не могу вызывать showErrors, потому что они не сопоставляются с идентификатором поля. Как только мне сообщают, как обновить сводку, я уверен, что могу добавлять элементы в список для общих сообщений, но я открыт для других предложений. Спасибо!

UPDATE

Вот что я в итоге сделал, кажется, работает неплохо. Мне нужно собрать сводку вручную в дополнение к вызову showErrors для допустимых ошибок с ключами:

var $summary = $form.find("[data-valmsg-summary=true]")
                    .addClass("validation-summary-errors")
                    .removeClass("validation-summary-valid");
var $ul = $summary.find("ul").empty();

var error = {};
$.each(response.errors, function () {
    if (this.key)
        error[this.key] = this.message;
    $("<li />").html(this.message).appendTo($ul);
});
$form.validate().showErrors(error);

Я надеюсь, что это поможет другим.

Ответ 1

Мне нужно было добавить свои собственные сообщения об ошибках в список сводок. Через день или около того, просматривая jQuery validate и ненавязчивый исходный код проверки, это решение, которое я использовал.

Сначала я объявил свою форму

@using (Html.BeginForm(null, null, FormMethod.Post, new {id = "formA"}))
{
    @Html.ValidationSummary()
           .....
           .....

Установка идентификатора важна, поскольку я использую этот идентификатор в коде javascript для извлечения объекта формы.

Я использовал следующий код для обновления сводного списка ошибок при отправке

$(function () {
    var formValidator,
        $form = $("#formA");

    // add handler to the forms submit action
    $form.submit(function () {
        if (!formValidator) {
            formValidator = $form.validate({}); // Get existing jquery validate object
        }

        var errorList = [];

        // get existing summary errors from jQuery validate
        $.each(formValidator.errorList, function (index, errorListItem) {
            errorList.push(errorListItem.message);
        });

        // add our own errors
        if (testForErrorCondidtionA()) {
            errorList.push("Please fix error condition A!");
        }

        if (testForErrorCondidtionB()) {
            errorList.push("Please fix error condition B!");
        }

        // No errors, do nothing
        if (0 === errorList.length) {
            return true; // allow submit
        }

        // find summary div
        var $summary = $form.find("[data-valmsg-summary=true]");

        // find the unordered list
        var $ul = $summary.find("ul");

        // Clear existing errors from DOM by removing all element from the list
        $ul.empty();

        // Add all errors to the list
        $.each(errorList, function (index, message) {
            $("<li />").html(message).appendTo($ul);
        });

        // Add the appropriate class to the summary div
        $summary.removeClass("validation-summary-valid")
            .addClass("validation-summary-errors");

        return false; // Block the submit
    });
});

Этот обработчик отправки всегда вызывается после ненавязчивого обработчика, что означает, что список сводных ошибок, который мы извлекаем из проверки jQuery, всегда будет актуальным.

Надеюсь, что этот ответ поможет, поскольку ненавязчивая проверка может стать волосатой, как только вы отклонитесь от стандартного случая (ов).

Ответ 2

Я столкнулся с той же проблемой и не мог понять более чистый способ. Это то, о чем я думаю делать

вместо этого

for (var j = 0; j < response.errors.length; j++) {
    var key = response.errors[j].key;
    var error = {};
    error[key] = response.errors[j].message;
    $form.data('validator').showErrors(error);
}

Поместите это,

        var error = {}, keyLess = 0;

        for (var j = 0; j < response.errors.length; j++) {
            var key = response.errors[j].key;
            error[key || keyLess++] = response.errors[j].message;
        }

        $form.validate().showErrors(error);

        var container = $form.find("[data-valmsg-summary=true]"), 
            list = container.find("ul");

        if (list && list.length) {
            list.empty();
            container
              .addClass("validation-summary-errors")
              .removeClass("validation-summary-valid");

            $.each(error, function(k,m) {
                $("<li />").html(m).appendTo(list);
            });
        }

Это в основном то, что jQuery.validate.unobtrusive делает

Как вы думаете?

Ответ 3

    if (!formValidator) {
        formValidator = $form.validate({}); // Get existing jquery validate object
    }

    // get existing summary errors from jQuery validate
    $.each(formValidator.errorList, function (index, errorListItem) {
        errorList.push(errorListItem.message);
    });

    // add our own errors
    if (testForErrorCondidtionA()) {
        errorList.push("Please fix error condition A!");
    }

    //unobtrusiveValidation should do the ul/summary dirty work.
    $form.trigger('invalid-form.validate', formValidator);

Ответ 4

Метод очистки MVC 5 (немного отличается от выше):

function resetValidation() {
    var form = $('#formName');
    var summary = form.find('[data-valmsg-summary=true]');
    var ul = summary.find('ul');
    ul.empty();
    summary.removeClass('validation-summary-errors').addClass('validation-summary-valid');
}

Наслаждайтесь!