سؤال

أنا أعمل مع ASP.Net MVC3, ، الطريقة الأسهل لاستخدام التحقق من صحة العميل هي تمكين jquery.validate.unobtrusive. كل شيء يعمل بشكل جيد ، للأشياء التي هي مباشرة من الخادم.

لكن عندما أحاول ضخ بعض "المدخلات" الجديدة مع JavaScript ، وكنت أعلم أنني بحاجة إلى الاتصال $.validator.unobtrusive.parse() لإعادة صحة. ولكن ومع ذلك ، فإن كل تلك الحقول الحقن الديناميكية لا تعمل.

والأسوأ من ذلك ، أحاول ربط استخدام يدوي jquery.validate وهو لا يعمل أيضًا. أي أفكار؟

هل كانت مفيدة؟

المحلول

لقد أنشأت امتدادًا لمكتبة jQuery.validate.Unobtrusion التي حلت هذه المشكلة لموقفي - قد يكون من المهم.

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

نصائح أخرى

جربت نهج Xhalent لكن لسوء الحظ لم يكن يعمل بالنسبة لي. نهج روبن لم ينجح ولم ينجح. لقد عملت بشكل رائع للعناصر المضافة ديناميكيًا ، ولكن إذا حاولت استخدام jQuery لإزالة جميع سمات التحقق من الصحة والامتدادات من DOM ، فلا تزال مكتبة التحقق من الصحة تحاول التحقق منها.

ومع ذلك ، إذا قمت بإزالة بيانات النموذج "غير المزعجة" بالإضافة إلى "التحقق من الصحة" ، فقد عملت مثل سحر لإضافة وإزالة العناصر التي تريد صحتها أو غير التحقق منها بشكل ديناميكي.

$("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.unobtrusion.parse () على نفس النموذج مرتين. عند تحميل النموذج في البداية من الخادم ، يتم تحليل النموذج تلقائيًا بواسطة المكتبة غير المزعجة. عند إضافة عنصر إدخال ديناميكيًا إلى النموذج واتصل $ .validator.unobtrusion.parse () مرة أخرى ، لن يعمل. الشيء نفسه ينطبق على الحاجز ().

يستدعي LIB غير مزعج طريقة التحقق من صحة المكون الإضافي JQUery لتحديد جميع القواعد والرسائل. المشكلة ، عند استدعاء مرة أخرى ، لا يقوم المكون الإضافي بتحديث المجموعة الجديدة من القواعد المقدمة.

لقد وجدت حلًا خامًا واحدًا: قبل استدعاء طريقة التحليل على LIB غير العادي ، أرمي جهاز التحقق من النموذج:

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

الآن ، عندما يتم استدعاء طريقة التحقق من صحة LIB غير مزعجة ، يتم إعادة إنشاء جميع القواعد والرسائل بما في ذلك المدخلات المضافة ديناميكيًا.

أتمنى أن يساعدك هذا

انا استخدم MVC 4 و JQuery 1.8 ، يبدو أن هناك حاجة إلى قطعة التعليمات البرمجية التالية لتمكين jQuery من التحقق من المحتوى الذي تم حقنه ديناميكيًا عبر Ajax ، أو jQuery في DOM.

لقد صنعت وظيفة معيارية تقبل كائن jQuery للعنصر المضافة حديثًا. إذا كنت قد استنسخت جدولًا جديدًا بالمعرف 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. مثله:

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

فيولا!

حاولت إجابة Viggity وفي البداية بدا أن كل شيء يعمل. ولكن بعد فترة من الوقت لاحظت أن التحقق من الصحة يصبح بطيئًا بشكل مؤلم ، كل ما أضفته العناصر الأكثر ديناميكية. والسبب هو أن حله لا يفصل عن معالجات الأحداث ، ولكن أضف مساحات جديدة في كل مرة. لذلك إذا قمت بإضافة 5 عناصر ، يتم تنفيذ التحقق من الصحة 6 مرات بدلاً من مرة واحدة فقط. لإصلاح هذا ، عليك إلغاء ربط الأحداث بالإضافة إلى مكالمات readoveTa.

$("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.unobtrusive.parse("#id");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top