jquery.validate.unobtrusive가 동적 주입 요소와 함께 작동하지 않습니다.


99

내가 함께 일하고 ASP.Net MVC3수있게 될 것이다 클라이언트 유효성 검사를 사용하는 쉬운 방법, jquery.validate.unobtrusive. 모든 것이 서버에서 제대로 작동합니다.

하지만 자바 스크립트로 새로운 '입력'을 주입하려고 할 때 $.validator.unobtrusive.parse()유효성 검사를 다시 바인딩 하기 위해 호출해야한다는 것을 알았습니다 . 그러나 여전히 모든 동적 주입 필드가 작동하지 않습니다.

더 나쁜 것은 사용하여 수동으로 바인딩하려고 시도 jquery.validate했지만 작동하지 않습니다. 이견있는 사람?


1
Google에서 여기에 온 경우 대규모 upvoted 다른 사람들이 오래되었으므로 @Sundara Prabu의 답변을 찾고있을 것입니다.
The Muffin Man

답변:


65

내 상황에 대해이 문제를 해결 한 jquery.validate.unobtrusive 라이브러리에 대한 확장을 만들었습니다. 관심이있을 수 있습니다.

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


나는 당신의 대답을 옳은 것으로 투표해야한다고 생각합니다. BTW, 라이브러리가 최신 MVC RC에서 작동합니까? 아니면 그냥 고쳤나요?
xandy

1
위에 링크 된 코드를 사용하는 경우 주석에 코드를 포함하도록 업데이트해야합니다. 그렇지 않으면 손상 될 수 있습니다. 특히, 두 개의 선택기 행을 변경하여 ID를 큰 따옴표로 묶으십시오.
Ryan O'Neill

1
마침내 디버깅 후 내 시나리오에서이 작업을 수행 할 수있었습니다. 입력 선택기를 전달해서는 안되지만 입력의 부모 또는 양식은 $.validator.unobtrusive.parse(). 또한 새 규칙 만 추가하고 기존 규칙에 대한 업데이트를 선택하지 않는 것 같습니다.
lambinator

5
이 답변에는 적어도 블로그 게시물의 곰 뼈가 포함되어야합니다. 링크 전용 답변은 일반적으로 SO에 대한 주제
Liam

8
이 답변은 3 년 이상이지만 여기,이 사이트에 답변의 필수 부분을 게시 할 수 있거나 게시물이 삭제 될 위험이있는 경우 매우 유용 할 것입니다. '링크 이상인 답변이 언급 된 FAQ를 참조하세요. '. 원하는 경우 링크를 계속 포함 할 수 있지만 '참조'로만 사용할 수 있습니다. 대답은 링크가 필요없이 그 자체로 있어야합니다.
Taryn

159

나는 Xhalent의 접근 방식을 시도했지만 불행히도 그것은 나를 위해 작동하지 않았습니다. Robin의 접근 방식은 효과가 있었지만 효과가 없었습니다. 동적으로 추가 된 요소에 대해서는 훌륭하게 작동했지만 JQuery를 사용하여 DOM에서 모든 유효성 검사 속성과 범위를 제거하려고하면 유효성 검사 라이브러리가 여전히 유효성 검사를 시도합니다.

그러나 "validationData"와 함께 양식의 "unobtrusiveValidation"데이터를 제거하면 유효성을 검사하거나 유효성을 검사하지 않을 요소를 동적으로 추가하고 제거하는 매력처럼 작동했습니다.

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

2
Xhalent는 처음에는 저에게도 작동하지 않았습니다. 그런 다음 parse가 요소 자체가 아닌 새 요소에 대한 컨테이너를 전달해야한다는 것을 알았습니다. 빠른 수정은 요소 대신 전체 양식을 전달하는 것입니다. 매력처럼 작동했습니다.
Per Hornshøj-Schierbeck

1
validator정의되지 않은 이유 는 무엇입니까? 유효성 검사와 유효성 검사가 모두 참조되었습니다. 유효성 검사는이 코드를 호출 할 때까지 작동합니다
Shawn Mclean 2011 년

4
감사. AJAX 호출을 통해 추가 된 ASP.MVC 부분보기의 페이지에 추가 된 콘텐츠에 대해 작동합니다.
Maksym Kozlenko 2012-07-09

감사합니다. 하지만 페이지에서 아코디언을 사용하고 있고 아코디언이 접혀 있으면 유효성 검사가 실행되지 않는 문제가 있습니다. 이 문제를 어떻게 해결할 수 있습니까? MVC3 대신 일반 jquery 유효성 검사 플러그인을 눈에 띄지 않게 $('#form').validate({ignore: ""})
했는지

1
그것은 PHP에서 나를 위해 일했습니다. 모든 주석이 .NET MVC를 가리 키기 때문에이 정보를 추가하는 것뿐입니다. : P
finnTheHumin

42

실제로 @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.unobtrusive.parse ( "#"+ form.attr ( "id")); $ .validator.unobtrusive.parse (form);
Softlion 2011

.first ()를 안전하게 제거 할 수 있습니다.
Softlion 2011

니스, 나는이 간단한 방법 등
닉슨

모두 추가 및 제거 데이터를-발 속성에 대한 아름다운 작품
줄리안 Dormon

33

나는 같은 문제가 있습니다. 동일한 형식으로 $ .validator.unobtrusive.parse ()를 두 번 호출 할 수 없다는 것을 발견했습니다. 서버에서 처음으로 양식을로드 할 때 양식은 눈에 잘 띄지 않는 라이브러리에 의해 자동으로 구문 분석됩니다. 양식에 동적으로 입력 요소를 추가하고 $ .validator.unobtrusive.parse ()를 다시 호출하면 작동하지 않습니다. parseElement ()도 마찬가지입니다.

눈에 거슬리지 않는 lib는 jquery validate 플러그인의 validate 메소드를 호출하여 모든 규칙과 메시지를 설정합니다. 문제는 다시 호출 될 때 플러그인이 주어진 새 규칙 세트를 업데이트하지 않는다는 것입니다.

한 가지 조잡한 해결책을 찾았습니다. 눈에 거슬리지 않는 lib에서 parse 메서드를 호출하기 전에 양식 유효성 검사기를 버립니다.

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

이제는 눈에 띄지 않는 lib에서 validate 메소드를 호출하면 동적으로 추가 된 입력을 포함하여 모든 규칙과 메시지가 다시 생성됩니다.

도움이 되었기를 바랍니다


A는 한 가치가 - 당신이 자신을 말했듯이 그것이 원액하지만 꽤 그것이 무엇을하고 무엇을 나중에 남아있는 상태 분명
당 Hornshøj-Schierbeck

2
Brad Wilsons 블로그에서 : "jQuery.validator.unobtrusive.parseElement () 함수를 호출하여 단일 HTML 요소를 구문 분석 할 수도 있습니다." 도움이 필요하세요?
jamesfm

@Per Hornshøj-Schierbeck : @Robin van der Knaap : 나는 이것을 알아 내기 위해 지난 2-3 시간을 보냈다 !! 어쨌든-이것은 훌륭하게 작동했습니다. Crude는 내가 그것을 사용하지 말아야한다고 느끼게합니다. 왜 이것을하고 싶지 않습니까?
KTF

2
동적으로 추가 된 유효성 검사기를 포함하여 모든 유효성 검사기가 제거되고 다시 복원되기 때문에 솔루션은 약간 조잡합니다. 동적으로 추가 된 유효성 검사기 만 업데이트하면 더 좋을 것입니다. @Xhalent는 그의 대답에 더 깨끗한 솔루션을 제공하지만 기본적으로 MS의 눈에 띄지 않는 라이브러리는이 시나리오에 맞게 업데이트되어야합니다.
Robin van der Knaap

9

내가 사용하고 MVC 4 JQuery와 1.8, 다음 코드 조각 같은 외모는 DOM에 아약스 또는 jQuery를 통해 검증 동적으로 주입 내용에 jQuery를 가능하게하기 위해 필요합니다.

새로 추가 된 요소의 Jquery 객체를 받아들이는 모듈 함수를 만들었습니다. tblContacts버튼 클릭으로 Jquery를 사용하여 id로 새 테이블을 복제 한 경우 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")

currform.validate (); 실제로 currForm.validate (); (오식). 공유해 주셔서 감사합니다. 이것은 저에게
John Mc

1
@JohnMc가 오타를 수정했습니다
Sundara Prabu

이 날 (MVC 4 JQuery와 1.10)에 근무 유일
머핀 맨

4

jquery 유효성 검사 문서에서 직접 규칙 함수를 사용하지 않는 이유는 무엇입니까? 이렇게 :

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

2

위의 답변으로 표시된 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');

1

내 코드에서 @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();

비올라!


1

나는 viggity의 대답을 시도했고 처음에는 모든 것이 작동하는 것처럼 보였습니다. 그러나 잠시 후 내가 추가 한 동적 항목이 많을수록 유효성 검사가 고통스럽게 느려진다는 것을 알았습니다. 그 이유는 그의 솔루션이 이벤트 핸들러의 바인딩을 해제하지 않고 매번 새 핸들러를 추가하기 때문입니다. 따라서 5 개 항목을 추가하면 유효성 검사가 한 번만 실행되는 대신 6 번 실행됩니다. 이 문제를 해결하려면 removeData 호출에 추가로 이벤트 바인딩을 해제해야합니다.

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

1

동적 콘텐츠의 경우 아래와 같이 Unobtrusive Validations를 업데이트 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');
    }
});

0

나는 잠시 동안 이것으로 장난을 치며 솔루션을 폐기하고 나중에 다시 시도했습니다 (여유 시간이있을 때 믿거 나 말거나).

이 스레드가 마지막으로 생성되거나 주석이 추가 된 이후 jquery의 최신 버전 (1.7.2 사용 중)에서이 동작이 변경되었는지 확실하지 않지만 .parseElement(inputElement)동적으로 생성 된 요소를 양식에 추가하려고하면 제대로 작동 함을 발견했습니다. 이미 유효성 검사기가로드되어 있습니다. 이것은 이미 위의 주석 중 하나에서 @jamesfm (Feb 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);

0

첫째, 호출은 유효성 검사가 아니라 .validator 여야한다고 생각합니다. 그러면 양식의 ID를 전달해야합니다.

$.validator.unobtrusive.parse("#id");

jquery.validate 및 jquery.validate.unobtrusive 스크립트를 모두로드하고 Html.EnableClientValidation () 및 Html.EnableUnobtrusiveJavaScript () 메서드를 호출했다고 가정합니다. 기본 페이지와 동적으로로드 된 양식에 대한 코드 샘플을 게시 할 수 있습니까?
Chris Allmark 2010

0

일부 오류가 이미 표시 될 가능성이있는 항목을 추가하고 제거해야하는 경우 이것이 제가 함께 제공 한 것입니다. 주로이 질문 페이지의 다른 아이디어를 기반으로합니다. destroy()JQuery 유효성 검사를 위해 데이터 속성을 제거하는 대신 기본 제공을 사용합니다 .

function resetValidator($form: JQuery) {
    $form.validate().destroy();

    //reset unobtrusive validation summary, if it exists
    $form.find("[data-valmsg-summary=true]")
        .removeClass("validation-summary-errors")
        .addClass("validation-summary-valid")
        .find("ul").empty();

    //reset unobtrusive field level, if it exists
    $form.find("[data-valmsg-replace]")
        .removeClass("field-validation-error")
        .addClass("field-validation-valid")
        .empty();

    $form.removeData("unobtrusiveValidation");
}

양식의 입력을 동적으로 수정하기 전에 호출합니다. 그런 다음 유효성 검사를 다시 초기화합니다.

resetValidator($form);
//add or remove inputs here ...
$.validator.unobtrusive.parse($form);

참고 : 일부 또는 모든 입력이 검증되고 오류가있는 경우 해당 오류는 재설정되지만 다음 검증시 올바르게 다시 나타납니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.