jquery.validate.unobtrouss не работает с динамическими инъецированными элементами

StackOverflow https://stackoverflow.com/questions/4406291

Вопрос

Я работаю с ASP.Net MVC3, более простой способ использовать проверку клиента, будет включать в себя jquery.validate.unobtrusive. Отказ Все работает нормально, для вещей, которые правы с сервера.

Но когда я пытаюсь ввести некоторые новые «входы» с JavaScript, и я знал, что мне нужно позвонить $.validator.unobtrusive.parse() переписывать проверки. Но все же все эти динамические инъекционные поля не функционируют.

Еще хуже, я пытаюсь вручную связать, используя jquery.validate И это тоже не работает. Есть предположения?

Это было полезно?

Решение

Я создал расширение для jQuery.validate.UnoBrobusbus, которая решила эту проблему для моей ситуации - это может представлять интерес.

http://xhalent.wordpress.com/2011/01/24/applying-unobtrouss-validation-to-dynamic-content/

Другие советы

Я попробовал подход Xhalent, но, к сожалению, это не работало для меня. Подход Робина работал и не работал. Он отлично подходит для динамически добавленных элементов, но если вы попытались использовать jQuery, чтобы удалить все атрибуты проверки и продвижения от DOM, библиотека проверки постарается проверять их.

Тем не менее, если вы удалите данные «ненавязчивые« ненаблюдаемость »в дополнение к« ValidationData », он работал как очарование для динамически добавления и удаления элементов, которые вы хотите проверить или не подтверждены.

$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

Я действительно очень люблю простоту решения @Viggity и @robins, поэтому я превратил его в быстрый маленький плагин:

(function ($) {

    $.fn.updateValidation = function () {
        var $this = $(this);
        var form = $this.closest("form")
            .removeData("validator")
            .removeData("unobtrusiveValidation");

        $.validator.unobtrusive.parse(form);

        return $this;
    };
})(jQuery);

Пример использования:

$("#DischargeOutcomeNumberOfVisits")
    .attr("data-val-range-min", this.checked ? "1" : "2")
    .updateValidation();

У меня такая же проблема. Я обнаружил, что невозможно звонить $ .Validator.UnoBtrouss. Shars () в той же форме дважды. При нагрузке формы изначально с сервера форма автоматически анализируется ненудимому библиотекой. Когда вы добавляете входную элемент динамически в форму и вызовите $ .Validator.UnoBtrouss. Shars () Опять не будет работать. То же самое касается парсеэлемента ().

Необриодиозирующие Lib вызывает метод проверки проверки jQuery Validate для установки всех правил и сообщений. Проблема в том, когда снова вызывается, плагин не обновляет новый набор правил его приведен.

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

$('yourForm').removeData("validator");

Теперь, когда метод проверки вызывается ненавязчивым lib, все правила и сообщения воссоздаются, включая динамически добавленные входы.

Надеюсь это поможет

я использую MVC 4 и jQuery 1.8, Похоже, что следующий кусок кода необходим для включения jQuery для проверки динамически введенного контента через AJAX или jQuery в DOM.

Я сделал модульную функцию, которая принимает объект jQuery из вновь добавленного элемента. Если вы клонировали новый стол с ID tblContacts Использование jQuery на кнопке нажатия кнопки, затем включите функцию ниже в вашем файле JS

function fnValidateDynamicContent(element) {
    var currForm = element.closest("form");
    currForm.removeData("validator");
    currForm.removeData("unobtrusiveValidation");
    $.validator.unobtrusive.parse(currForm);
    currForm.validate(); // This line is important and added for client side validation to trigger, without this it didn't fire client side errors.
}

И назовите это так:

fnValidateDynamicContent("#tblContacts")

Принимая из решения Xhalent, помеченного как ответ выше, я немного расширился на нем.

$.validator.unobtrusive.parseDynamicContent = function (selector) {
    var $selector = $(selector),
        $jqValUnob = $.validator.unobtrusive,
        selectorsDataValAttr = $selector.attr('data-val'),
        $validationInputs = $selector.find(':input[data-val=true]');

    if ((selectorsDataValAttr !== 'true') && 
        ($validationInputs.length === 0)) { 
        return; 
    }

    if (selectorsDataValAttr === 'true') {
        $jqValUnob.parseElement(selector, true);
    }

    $validationInputs.each(function () {
        $jqValUnob.parseElement(this, true);
    });

    //get the relevant form
    var $form = $selector.first().closest('form');

    $jqValUnob.syncValdators($form);
};

/* synchronizes the unobtrusive validation with jquery validator */
$.validator.unobtrusive.syncValdators = function ($form) {
    if ($.hasData($form[0])) {
        var unobtrusiveValidation = $form.data('unobtrusiveValidation'),
            validator = $form.validate();

        // add validation rules from unobtrusive to jquery
        $.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
            if (validator.settings.rules[elname] == undefined) {
                var args = {};
                $.extend(args, elrules);
                args.messages = unobtrusiveValidation.options.messages[elname];
                $("[name='" + elname + "']").rules("add", args);
            } else {
                $.each(elrules, function (rulename, data) {
                    if (validator.settings.rules[elname][rulename] == undefined) {
                        var args = {};
                        args[rulename] = data;
                        args.messages = unobtrusiveValidation.options.messages[elname][rulename];
                        $("[name='" + elname + "']").rules("add", args);
                    }
                });
            }
        });
        // remove all validation rules from jquery that arn't in unobtrusive
        $.each(validator.settings.rules, function (elname, elrules) {
            if (unobtrusiveValidation.options.rules[elname] === undefined) {
                delete validator.settings.rules[elname];
            } else {
                $.each(elrules, function (rulename, data) {
                    if (rulename !== "messages" && unobtrusiveValidation.options.rules[elname][rulename] === undefined) {
                        delete validator.settings.rules[elname][rulename];
                    }
                });
            }
        });
    }        
};

$.validator.unobtrusive.unparseContent = function (selector) {
    var $selector = $(selector);

    // if its  a text node, then exit
    if ($selector && $selector.length > 0 && $selector[0].nodeType === 3) {
        return;
    }

    var $form = $selector.first().closest('form'), 
        unobtrusiveValidation = $form.data('unobtrusiveValidation');

    $selector.find(":input[data-val=true]").each(function () {
        removeValidation($(this), unobtrusiveValidation);
    });
    if ($selector.attr('data-val') === 'true') {
        removeValidation($selector, unobtrusiveValidation);
    }
    $.validator.unobtrusive.syncValdators($form);
};

function removeValidation($element, unobtrusiveValidation) {
    var elname = $element.attr('name');
    if (elname !== undefined) {
        $element.rules('remove');
        if (unobtrusiveValidation) {
            if (unobtrusiveValidation.options.rules[elname]) {
                delete unobtrusiveValidation.options.rules[elname];
            }
            if (unobtrusiveValidation.options.messages[elname]) {
                delete unobtrusiveValidation.options.messages[elname];
            }
        }
    }
}

Таким образом, в основном это все еще работает так же, как решение Xhalent выше, но я добавил возможность удаления правил для элементов, которые вы удаляете из DOM. Итак, когда вы удалите элементы из DOM, и вы хотите, чтобы эти правила проверки удалены, а затем звоните:

$.validator.unobtrusive.unparseContent('input.something');

Почему бы не использовать Функция правил непосредственно от проверки jQuery doc. Так:

$('#newField0').rules('add', {
    required: true,
    minlength: 2
});
//use Html.ValidationMessage will renders a span element, unobtrusive need it to display errors
$('@Html.ValidationMessage("newField0")').insertAfter('#newField0');

Я нашел код кода Xhalent в моем коде и собирался удалить его, потому что я не использовал его, что приведет меня к этому вопросу.

Этот код довольно чистый и простой:

jQuery.fn.unobtrusiveValidationForceBind = function () {
    //If you try to parse a form that is already parsed it won't update
    var $form = this
       .removeData("validator") /* added by the raw jquery.validate plugin */
            .removeData("unobtrusiveValidation");  /* added by the jquery     unobtrusive plugin */

    $form.bindUnobtrusiveValidation();
}

Затем, чтобы вызвать это расширение jQuery, просто используйте селектор, чтобы схватить форму:

$('#formStart').unobtrusiveValidationForceBind();

Виола!

Я попробовал ответ Spirity и сначала все, казалось, работало. Но через некоторое время я заметил, что валидация становится болезненно медленными, чем добавляли более динамически элементы. Причина заключалась в том, что его решение не увидит обработчиков событий, но добавлять новые каждый раз. Поэтому, если вы добавите 5 элементов, проверка выполняется 6 раз, а не только один раз. Чтобы исправить это, вы должны дополнительно уничтожить события к вызовам Redwardata.

$("form").removeData("validator")
         .removeData("unobtrusiveValidation")
         .off("submit.validate click.validate focusin.validate focusout.validate keyup.validate invalid-form.validate");
$.validator.unobtrusive.parse("form");

В случае динамического содержимого необходимо обновить ненавязчивые валидации, как показано ниже, и проверьте, Form действительно при отправке.

function UpdateUnobtrusiveValidations(idForm) {
    $(idForm).removeData("validator").removeData("unobtrusiveValidation");
    $.validator.unobtrusive.parse($(idForm));
};


$('#idDivPage').on('click', '#idSave', function (e) {
    e.preventDefault();
    if (!$('#idForm').valid()) {
        // Form is invalid … so return
        return false;
    }
    else {
        // post data to server using ajax call
        // update Unobtrusive Validations again
        UpdateUnobtrusiveValidations('#idForm');
    }
});

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

Я не уверен, что это поведение изменилось бы в более новые версии jQuery (мы используем 1.7.2), так как эта нить была создана или прокомментирована, но я обнаружил, что .parseElement(inputElement) Работает нормально, когда я пытаюсь добавить динамически созданные элементы в форму, которая уже загружается валидатор. Это уже было предложено @jamesfm (15 февраля '11) в одном из комментариев выше, но я пропустил его в первые несколько раз, когда я работал над этим. Поэтому я добавляю его как отдельный ответ, чтобы сделать его более очевидным и потому что я думаю, что это хорошее решение и не требует столько накладных расходов. Это может быть не актуально для всех проблем, поднятых в последующих ответах, но я думаю, что это будет решение первоначального вопроса. Вот как я получил мой работать:

//row & textarea created dynamically by an async ajax call further up in the code
var row = ...; //row reference from somewhere
var textarea = row.find("textarea");
textarea.val("[someValue]");

//add max length rule to the text area
textarea.rules('add', {
    maxlength: 2000
});
//parse the element to enable the validation on the dynamically added element
$.validator.unobtrusive.parseElement(textarea);

Во-первых, я думаю, что вызов должен быть в .Validator, не проверяют, то вам нужно пройти в ID формы

$.validator.unobtrusive.parse("#id");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top