باستخدام JQuery التحقق من صحة البرنامج المساعد للتحقق من صحة حقول النماذج المتعددة بأسماء متطابقة

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

سؤال

لدي نموذج تم إنشاؤه ديناميكيا مع حقول الإدخال بنفس الاسم (على سبيل المثال: "الخريطة"). ليس لدي خيار تغيير أسماء الحقول أو إنشاء أسماء حقل فريدة لأن رمز معالج النموذج (PERL / CGI) مصمم للتعامل مع مجموعة من قيم الإدخال (في هذه الحالة @map).

كيف يمكنني استخدام jQuery التحقق من صحة البرنامج المساعد للتحقق من صحة نموذج في مثل هذا الموقف؟ على وجه التحديد، أود بالضبط عنصر واحد من الصفيف المقدم للحصول على قيمة ثابتة معينة. أنا حاليا باستخدام معالج أحداث مخصص يخلق كائن JSON مع serializeArray() ثم يعبره لضمان تلبية الحالة. ولكن نظرا لأنني استخدمت البرنامج المساعد للتحقق من الصحة في بقية التطبيق، كنت أتساءل عما إذا كان قد يتم التعامل مع مثل هذه الحالة باستخدام البرنامج المساعد نفسه هنا أيضا.

شكرا لكم على اهتمامكم.

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

المحلول

قضيت بعض الوقت في البحث ومحاولة أشياء مختلفة عندما حاولت أخيرا الطريقة الأكثر تافهة للقيام بالتحقق من الصحة على حقول متعددة. كل حقل وننساء يتشارك فئة فريدة لكل مجموعة. أنا فقط حلقت من خلال المدخلات مع تلك الفئة وأضاف قواعد التحقق من الصحة كالمعتاد. آمل أن يساعد هذا شخصا آخر.

    $("#submit").click(function(){
    $("input.years").each(function(){
        $(this).rules("add", {
            required: true,
            messages: {
                required: "Specify the years you worked"
            }
        } );            
    });

    $("input.employerName").each(function(){
        $(this).rules("add", {
            required: true,
            messages: {
                required: "Specify the employer name"
            }
        } );            
    }); 

    $("input.employerPhone").each(function(){
        $(this).rules("add", {
            required: true,
            minlength: 10,
            messages: {
                required: "Specify the employer phone number",
                minlength: "Not long enough"
            }
        } );            
    }); 

    $("input.position").each(function(){
        $(this).rules("add", {
            required: true,
            messages: {
                required: "Specify your position"
            }
        } );            
    });             

    $("input.referenceName").each(function(){
        $(this).rules("add", {
            required: true,
            messages: {
                required: "Specify the reference name"
            }
        } );            
    });         

    $("input.referencePhone").each(function(){
        $(this).rules("add", {
            required: true,
            minlength: 10,
            messages: {
                required: "Specify your reference phone number",
                minlength: "Not long enough"
            }
        } );            
    });

// Now do your normal validation here, but don't assign rules/messages for the fields we just set them for





});

نصائح أخرى

كما لا أستطيع التعليق على الإجابة Scampbell، أنا Dunno إذا كان حول نقاط السمعة أو لأن الخيط قد أغلقت للتو، لدي مساهمة في إجابته،

بدلا من تغيير ملف المصدر JQuery.Validation، يمكنك ببساطة تجاوز الوظيفة التي تحتاجها للتعديل فقط في الصفحات التي تتطلب ذلك.

مثال سيكون:

$.validator.prototype.checkForm = function() {
    //overriden in a specific page
    this.prepareForm();
    for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) {
        if (this.findByName(elements[i].name).length !== undefined && this.findByName(elements[i].name).length > 1) {
            for (var cnt = 0; cnt < this.findByName(elements[i].name).length; cnt++) {
                this.check(this.findByName(elements[i].name)[cnt]);
            }
        } else {
            this.check(elements[i]);
        }
    }
    return this.valid();
};

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

خيط قديم أعرفه لكني صادفته بحثا عن الإصلاح إلى نفس المشكلة.

تم نشر حل أكثر أناقة هنا:http://web-funda.blogspot.com/2009/05/jquery-validation-for-array-of-input.html.

يمكنك ببساطة تحرير jQuery.validate.js وتغيير تشخيص

    checkForm: function() {
    this.prepareForm();
    for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
        if (this.findByName( elements[i].name ).length != undefined && this.findByName( elements[i].name ).length > 1) {
            for (var cnt = 0; cnt < this.findByName( elements[i].name ).length; cnt++) {
                    this.check( this.findByName( elements[i].name )[cnt] );
            }
        } else {
            this.check( elements[i] );
        }
    }
    return this.valid();
}

لقد تعلمت للتو من البريد عن طريق مؤلف الإضافات، Jörn Zaefferer، أن التحقق من الصحة يتطلب أسماء الحقول أن تكون فريدة من نوعها باستثناء أزرار الراديو وخانات الاختيار.

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

في حالتي، لدي البرنامج المساعد للتحقق من الصحة النظر في الأسماء التي تنتهي ب [] مختلفة على الرغم من أنهم قد يكون لديهم أسماء حقل متطابقة. للقيام بذلك، قمت بالكتابة فوق هذه الطريقة الداخلية بعد JQuery.Validate.js.

$.validator.prototype.elements= function() {
var validator = this,
    rulesCache = {};

// select all valid inputs inside the form (no submit or reset buttons)
// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
return $([]).add(this.currentForm.elements)
.filter(":input")
.not(":submit, :reset, :image, [disabled]")
.not( this.settings.ignore )
.filter(function() {
    !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);

    // select only the first element for each name (EXCEPT elements that end in []), and only those with rules specified
    if ( (!this.name.match(/\[\]/gi) && this.name in rulesCache) || !validator.objectLength($(this).rules()) )
        return false;

    rulesCache[this.name] = true;
    return true;
});
};


$.validator.prototype.idOrName = function(element) {

// Special edit to get fields that end with [], since there are several [] we want to disambiguate them
// Make an id on the fly if the element doesnt have one
if(element.name.match(/\[\]/gi)) {
    if(element.id){
        return element.id;
    } else {
        var unique_id = new Date().getTime();

        element.id = new Date().getTime();

        return element.id;
    }
}

return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
};

ما عليك سوى استخدام سمة غير مستخدمة من المدخلات لتخزين الاسم الأصلي، ثم إعادة تسمية مؤشرها المرفق:

function addMultiInputNamingRules(form, field, rules){    
    $(form).find(field).each(function(index){
    $(this).attr('alt', $(this).attr('name'));
    $(this).attr('name', $(this).attr('name')+'-'+index);
    $(this).rules('add', rules);
});

}

function removeMultiInputNamingRules(form, field){    
    $(form).find(field).each(function(index){
    $(this).attr('name', $(this).attr('alt'));
    $(this).removeAttr('alt');
});

}

ثم بعد تعيين منصة التحقق:

addMultiInputNamingRules('#form-id', 'input[name="multifield[]"]', { required:true });

وعند الانتهاء من التحقق من الصحة، يعود مرة أخرى مثل:

removeMultiInputNamingRules('#form-id', 'input[alt="multifield[]"]');

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

وهنا كيف فعلت ذلك. أسهل قليلا من الأساليب المقترحة سابقا:

function validateTab(tab) {
    var valid = true;
    $(tab).find('input').each(function (index, elem) {
        var isElemValid = $("#registrationForm").validate().element(elem);
        if (isElemValid != null) { //this covers elements that have no validation rule
            valid = valid & isElemValid;
        }
    });

    return valid;
}

في حالتي، لدي معالج (3 خطوات) تبين أنه أكثر تعقيدا كما لا أريد التحقق من صحة جميع الحقول في وقت واحد. أنا أساسا وضع المكونات في علامات التبويب وإذا كانت علامة التبويب الأولى صالحة، فأنتقل إلى التالي، حتى أصلت إلى آخر واحد، وبعد ذلك أقدم كل البيانات. وهكذا tab المعلمة هناك عنصر علامة التبويب الفعلية (وهو div). ثم حلقة من خلال جميع الأطفال عناصر الإدخال إلى علامة التبويب بلدي وتحقق منها مقابل الصلاحية.

كل شيء آخر هو المعيار.


فقط للاكتمال هنا هو بقية الرمز: كيف يتم تقديم النموذج وكيف يبدو مهني:

<a href="javascript:moveToNextTab(1)" class="button next">Submit</a>

وهنا وظيفة JS تسمى:

function moveToNextTab(currentTab) {
    var tabs = document.getElementsByClassName("tab");
    //loop through tabs and validate the current one.
    //If valid, hide current tab and make next one visible.
}

أنا أستخدم قواعد التحقق هذه (التي قمت بإنشائها على JQuery.Ready):

$("#registrationForm").validate({
    rules: {
        birthdate: {
            required: true,
            date: true
        },
        name: "required",
        surname: "required",
        address: "required",
        postalCode: "required",
        city: "required",
        country: "required",
        email: {
            required: true,
            email: true
        }
    }
});

أنا أستخدم "محكم التحقق من صحة مسج 1.7".

المشكلة لماذا العديد من العناصر "$ (: الإدخال)" تقاسم نفس الاسم لا يتم التحقق من صحة

هي طريقة $ .validator.element:

elements: function() {
        var validator = this,
            rulesCache = {};

        // select all valid inputs inside the form (no submit or reset buttons)
        // workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
        return $([]).add(this.currentForm.elements)
        .filter(":input")
        .not(":submit, :reset, :image, [disabled]")
        .not( this.settings.ignore )
        .filter(function() {
            !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);

            // select only the first element for each name, and only those with rules specified
            if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
                return false;

            rulesCache[this.name] = true;
            return true;
        });
    },

الحالة

إذا (هذا .Name في RIDESCACHE || .....

يقيم العناصر الثانية والكم التالية تقاسم نفس الاسم صحيحا ....

سيكون الحل الشرط:

(this.ID || اسم) في RIDESCACHE

إسمح لي، js puritans، أن هذا (this.id ||.name) ليس عند 100٪ ...

بالطبع،

RIDECCACHTE [اسمه .name] = صحيح؛

يجب تغيير الخط بشكل مناسب أيضا.

حتى $ .validator.prototineype.elements سوف تكون:

$(function () {
if ($.validator) {
    //fix: when several input elements shares the same name, but has different id-ies....
    $.validator.prototype.elements = function () {

        var validator = this,
            rulesCache = {};

        // select all valid inputs inside the form (no submit or reset buttons)
        // workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
        return $([]).add(this.currentForm.elements)
        .filter(":input")
        .not(":submit, :reset, :image, [disabled]")
        .not(this.settings.ignore)
        .filter(function () {
            var elementIdentification = this.id || this.name;

            !elementIdentification && validator.settings.debug && window.console && console.error("%o has no id nor name assigned", this);

            // select only the first element for each name, and only those with rules specified
            if (elementIdentification in rulesCache || !validator.objectLength($(this).rules()))
                return false;

            rulesCache[elementIdentification] = true;
            return true;
        });
    };
}

});

ربما أفتقد النقطة، ولكن نظرا لأن المصدق لا يعمل مع أسماء متعددة (مجربة ... فشلت!) لقد غيرت النموذج الخاص بي لتغيير الأسماء بشكل حيوي، قم بتعيين القواعد، ثم قم بإلغاء تحديد الأسماء في إرسال.

طريقتان (تجاهل الأشياء WLOG، إنه فقط نواتج إلى وحدة التحكم):

// convert the field names into generated ones to allow fields with the same names 
// to be validated individually. The original names are stored as data against the
// elements, ready to be replaced. The name is replaced with
// "multivalidate-<name>-<id>", e.g. original => 'multivalidate-original-1'

function setGeneratedNamesWithValidationRules(form, fields, rules) {

    var length = fields.length;

    for (var i=0; i < length; ++i ){
        var name = fields[i];

        var idCounter = 0;  
        // we match either the already converted generator names or the original
        $("form [name^='multivalidate-" + name + "'], form [name='" + name + "']").each(function() {
            // identify the real name, either from the stored value, or the actual name attribute
            var realName = $(this).data('realName');
            if (realName == undefined) {
                realName = $(this).attr("name");
                $(this).data('realName', realName);
            }

            wlog("Name: " + realName + " (actual: " + $(this).attr("name") + "), val: " + $(this).val() + ". Rules: " + rules[realName]);
            $(this).attr("name", "multivalidate-" + realName + "-" + idCounter);
            if (rules[realName]) {
                $(this).rules("add", rules[realName]);
            }
            idCounter++;
        });
    }
}

function revertGeneratedNames(form, fields) {

    var length = fields.length;

    for (var i=0; i < length; ++i ){
        var name = fields[i];
        wlog("look for fields names [" + name + "]");

        $("form [name^='multivalidate-" + name + "']").each(function() {
            var realName = $(this).data('realName');
            if (realName == undefined) {
                wlog("Error: field named [" + $(this).attr("name") + "] does not have a stored real name");
            } else {
                wlog("Convert [" + $(this).attr("name") + "] back to [" + realName + "]");
                $(this).attr("name", realName);
            }
        });
    }
}

على تحميل النموذج، وكلما قمت بإضافة صف آخر ديناميكيا، اتصلت بطريقة المجموعة، على سبيل المثال

setGeneratedNamesWithValidationRules($("#my-dynamic-form"), ['amounts'], { 'amounts': 'required'} );

هذا يغير الأسماء للسماح بالتحقق من الصحة الفردية.

في الغموض: Thingumy بعد التحقق من الصحة، اتصلت بالعودة، أي

revertGeneratedNames(form, ['amounts']);

الذي يقوم بتحويل الأسماء إلى النسخ الأصلية قبل نشر البيانات.

أعتقد أنك أسيء فهم أعمال أشكال HTML. يحتاج عنصر كل عنصر إلى الحصول على اسم فريد، باستثناء خانات الاختيار والأزرار المتعددة التي تتيح لك اختيار خيارات واحدة / متعددة لحقل بيانات واحد.

في حالتك، لا يفشل التحقق من صحة JQuery فقط، ولكن أيضا التحقق من Validator Form من جانب الخادم، لأنه لا يمكن تعيين المدخلات في حقول البيانات. لنفترض أنك تريد أن يدخل المستخدم في برينام، اسم العائلة، عنوان البريد الإلكتروني، الفاكس (اختياري) وجميع حقول الإدخال لديك name="map"

ثم ستتلقى هذه القوائم في إرسال:

map = ['Joe','Doe','joe.doeAThotmail.com','++22 20182238'] //All fields completed
map = ['Joe','Doe','joe.doeAThotmail.com'] //OK, all mandatory fields completed 
map = ['Doe', 'joe.doeAThotmail.com','++22 20182238']//user forgot prename, should yield error

ترى أنه من المستحيل التحقق من صحة هذا النموذج بشكل موثوق.

أوصي بإعادة النظر في وثائق معالج نموذج PERL أو تكييفه إذا كتبت بمفردك بنفسك.

بالنسبة لي تم حل هذا بسهولة شديدة عن طريق تعطيل التصحيح

 $("#_form").validate({
    debug:false,
    //debug: true,
    ...
    });

هناك حل بسيط:

$(document).ready(function() {
   $(".form").each(function() {
      $(this).validate({
         ...
         ,errorContainer: $(".status_mess",this) // use "this" as reference to that instance of form.
         ...
      });
   });
});
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top