Pergunta

Estou trabalhando com ASP.Net MVC3, a maneira mais fácil de usar a validação do cliente seria permitir o jquery.validate.unobtrusive. Tudo funciona bem, para coisas que estão certas do servidor.

Mas quando tento injetar algumas novas 'entradas' com JavaScript, e sabia que preciso ligar $.validator.unobtrusive.parse() para rebidar as validações. Mas ainda assim, todos esses campos injetados dinâmicos não estão funcionando.

Pior ainda, tento amarrar manualmente usando jquery.validate E também não está funcionando. Alguma ideia?

Foi útil?

Solução

Criei uma extensão para a biblioteca jQuery.validate.unobtrusive que resolveu esse problema para minha situação - pode ser de interesse.

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

Outras dicas

Eu tentei a abordagem de Xhalent, mas infelizmente não estava funcionando para mim. A abordagem de Robin funcionou e não funcionou. Funcionou muito bem para elementos adicionados dinamicamente, mas se você tentasse usar o JQuery para remover todos os atributos e vãos de validação do DOM, a biblioteca de validação ainda tentaria validá -los.

No entanto, se você remover os dados de "validação discreta" do formulário, além do "ValidationData", ele funcionou como um charme para adicionar e remover dinamicamente os elementos que você deseja validar ou não validados.

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

Na verdade, eu realmente gosto da simplicidade da solução @Viggity e @robins, então eu a transformei em um pequeno plugin rápido:

(function ($) {

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

        $.validator.unobtrusive.parse(form);

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

Exemplo de uso:

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

Estou tendo o mesmo problema. Descobri que não é possível chamar $ .Validator.unobtrusive.parse () na mesma forma duas vezes. Ao carregar o formulário inicialmente do servidor, o formulário é analisado automaticamente pela biblioteca discreta. Quando você adiciona um elemento de entrada dinamicamente ao formulário e chama $ .Validator.unobtrusive.parse () novamente, ele não funcionará. O mesmo vale para o parseelemento ().

A LIB discreta chama o método Validate do plug -in JQuery Validate para definir todas as regras e mensagens. O problema é que, quando chamado novamente, o plug -in não atualiza o novo conjunto de regras que é fornecido.

Encontrei uma solução bruta: antes de chamar o método Parse na Lib discreta, jogo fora o validador de formulário:

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

Agora, quando o método Validate é chamado pela LIB discreta, todas as regras e mensagens são recriadas, incluindo as entradas adicionadas dinamicamente.

Espero que isto ajude

estou usando MVC 4 e JQuery 1.8, Parece que a seguinte parte do código é necessária para permitir que o jQuery validação de conteúdo dinamicamente injetado via Ajax ou jQuery no DOM.

Eu fiz uma função modular que aceita o objeto jQuery do elemento recém -adicionado. Se você clonou uma nova tabela com identificação tblContacts Usando o jQuery no clique de um botão e inclua a função abaixo no seu arquivo 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.
}

e chame assim:

fnValidateDynamicContent("#tblContacts")

Recebendo da solução de Xhalent marcada como resposta acima, expandi -a um pouco.

$.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];
            }
        }
    }
}

Então, basicamente, ele ainda funciona da mesma forma que a solução do Xhalent acima, mas adicionei a capacidade de remover as regras para elementos que você remove do DOM. Portanto, quando você remove os elementos do DOM e deseja que essas regras de validação sejam removidas, também ligue:

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

Por que não usar a função das regras diretamente do documento de validação do jQuery. Assim:

$('#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');

Encontrei o script de código do @xhalent no meu código e ia excluí -lo porque não o estava usando, o que me levou a essa pergunta.

Este código é bastante limpo e simples:

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();
}

Então, para chamar essa extensão do jQuery, basta usar um seletor para agarrar seu formulário:

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

Viola!

Eu tentei a resposta de Viggity e, a princípio, tudo parecia funcionar. Mas depois de um tempo, notei que a validação se torna dolorosamente lenta, mais itens dinamicamente adicionei. O motivo foi que sua solução não desbaste os manipuladores de eventos, mas adiciona novos a cada vez. Portanto, se você adicionar 5 itens, a validação será executada 6 vezes em vez de apenas uma vez. Para corrigir isso, você precisa desativar os eventos adicionalmente às chamadas removidas.

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

Em caso de conteúdo dinâmico, você precisa atualizar validações discretas como abaixo e verificar se Form é válido durante o envio.

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');
    }
});

Estou brincando com isso há algum tempo, descartando soluções e tentando novamente mais tarde (quando tive algum tempo livre, acredite ou não).

Não tenho certeza se esse comportamento teria mudado em versões mais recentes do jQuery (estamos usando 1.7.2) desde que esse tópico foi criado ou comentado pela última vez, mas eu descobri que .parseElement(inputElement) Funciona bem quando tento adicionar elementos criados dinamicamente a um formulário que já possui um validador carregado. Isso já foi sugerido por @jamesfm (15 de fevereiro de 11) em um dos comentários acima, mas eu o ignorei nas primeiras vezes em que estava trabalhando nisso. Portanto, estou adicionando -o como uma resposta separada para torná -lo mais óbvio e porque acho que é uma boa solução e não requer tanta sobrecarga. Pode não ser relevante para todas as questões levantadas nas respostas subsequentes, mas acho que seria uma solução para a pergunta original. Veja como eu fiz o meu funcionando:

//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);

Em primeiro lugar, acho que a ligação deve ser para. Validador, não validar, então você precisa passar no ID da forma

$.validator.unobtrusive.parse("#id");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top