jQuery मान्य - भरे जाने के लिए समूह में कम से कम एक फ़ील्ड की आवश्यकता होती है


98

मैं कुछ रूपों को मान्य करने के लिए उत्कृष्ट jQuery के मान्य प्लगइन का उपयोग कर रहा हूं । एक रूप में, मुझे यह सुनिश्चित करने की आवश्यकता है कि उपयोगकर्ता फ़ील्ड के कम से कम एक समूह में भरता है। मुझे लगता है कि मुझे बहुत अच्छा समाधान मिला है, और मैं इसे साझा करना चाहता हूं। कृपया कोई सुधार बताएं जो आप सोच सकते हैं।

ऐसा करने के लिए कोई अंतर्निहित तरीका नहीं खोजा, मैंने रेबेका मुरफे की कस्टम सत्यापन विधि की खोज की और पाया , जो बहुत मददगार था।

मैंने इसे तीन तरीकों से सुधारा:

  1. आपको खेतों के समूह के लिए एक चयनकर्ता में पास होने के लिए
  2. आपको यह बताने के लिए कि सत्यापन के लिए उस समूह में से कितने को भरना होगा
  3. समूह में सभी इनपुट दिखाने के लिए जैसे ही उनमें से एक सत्यापन पास होता है। ( अंत में निक क्रेवर के लिए चिल्लाओ-आउट देखें ।)

तो आप कह सकते हैं "कम से कम एक्स इनपुट जो कि चयनकर्ता वाई से मेल खाते हैं उन्हें भरना चाहिए।"

अंतिम परिणाम, इस तरह मार्कअप के साथ:

<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">

... इस तरह से नियमों का एक समूह है:

// Both these inputs input will validate if 
// at least 1 input with class 'productinfo' is filled
partnumber: {
   require_from_group: [1,".productinfo"]
  }
description: {
   require_from_group: [1,".productinfo"]
}

आइटम # 3 मानता है कि आप .checkedसफल सत्यापन पर अपनी त्रुटि संदेशों का एक वर्ग जोड़ रहे हैं । आप इसे निम्नानुसार कर सकते हैं, जैसा कि यहां दिखाया गया है

success: function(label) {  
        label.html(" ").addClass("checked"); 
}

जैसा कि ऊपर लिंक किए गए डेमो में, मैं प्रत्येक पृष्ठ span.errorको अपनी पृष्ठभूमि के रूप में एक एक्स छवि देने के लिए सीएसएस का उपयोग करता हूं , जब तक कि इसमें वर्ग न हो .checked, जिस स्थिति में इसे चेक मार्क छवि मिलती है।

यहाँ मेरा कोड अब तक है:

jQuery.validator.addMethod("require_from_group", function(value, element, options) {
    var numberRequired = options[0];
    var selector = options[1];
    //Look for our selector within the parent form
    var validOrNot = $(selector, element.form).filter(function() {
         // Each field is kept if it has a value
         return $(this).val();
         // Set to true if there are enough, else to false
      }).length >= numberRequired;

    // The elegent part - this element needs to check the others that match the
    // selector, but we don't want to set off a feedback loop where each element
    // has to check each other element. It would be like:
    // Element 1: "I might be valid if you're valid. Are you?"
    // Element 2: "Let's see. I might be valid if YOU'RE valid. Are you?"
    // Element 1: "Let's see. I might be valid if YOU'RE valid. Are you?"
    // ...etc, until we get a "too much recursion" error.
    //
    // So instead we
    //  1) Flag all matching elements as 'currently being validated'
    //  using jQuery's .data()
    //  2) Re-run validation on each of them. Since the others are now
    //     flagged as being in the process, they will skip this section,
    //     and therefore won't turn around and validate everything else
    //  3) Once that's done, we remove the 'currently being validated' flag
    //     from all the elements
    if(!$(element).data('being_validated')) {
    var fields = $(selector, element.form);
    fields.data('being_validated', true);
    // .valid() means "validate using all applicable rules" (which 
    // includes this one)
    fields.valid();
    fields.data('being_validated', false);
    }
    return validOrNot;
    // {0} below is the 0th item in the options field
    }, jQuery.format("Please fill out at least {0} of these fields."));

हुर्रे!

चिल्लाओ

अब उस चिल्लाहट के लिए - मूल रूप से, मेरे कोड ने नेत्रहीन संदेशों को फिर से सत्यापित करने के बजाय अन्य मेल खाने वाले फ़ील्ड पर छिपा दिया, जिसका अर्थ था कि यदि कोई अन्य समस्या थी (जैसे 'केवल संख्याओं की अनुमति है और आपने पत्र दर्ज किए हैं') , यह तब तक छिपा रहा जब तक उपयोगकर्ता ने सबमिट करने का प्रयास नहीं किया। ऐसा इसलिए था क्योंकि मुझे नहीं पता था कि उपरोक्त टिप्पणियों में उल्लिखित फीडबैक लूप से कैसे बचा जाए। मुझे पता था कि एक रास्ता होना चाहिए, इसलिए मैंने एक सवाल पूछा , और निक क्रेवर ने मुझे बताया। धन्यवाद, निक!

प्रश्न हल किया

यह मूल रूप से "मुझे इसे साझा करने और यह देखने के लिए कि क्या कोई भी सुधार का सुझाव दे सकता है"। हालांकि मैं अभी भी प्रतिक्रिया का स्वागत करता हूं, मुझे लगता है कि यह इस बिंदु पर बहुत पूर्ण है। (यह कम हो सकता है, लेकिन मैं चाहता हूं कि इसे पढ़ना आसान हो और जरूरी नहीं कि संक्षिप्त हो।) तो बस आनंद लें!

अद्यतन - अब jQuery सत्यापन का हिस्सा है

यह आधिकारिक तौर पर 4/3/2012 को jQuery सत्यापन में जोड़ा गया था ।


इसके अलावा, संबंधित नियम देखें - "या तो इन फ़ील्ड्स को छोड़ दें, या उनमें से कम से कम X भरें" - stackoverflow.com/questions/1888976/…
Nathan Long

यदि अन्य इनपुट भरे जाते हैं, तो एक मनमाना इनपुट जाँच के लिए जिम्मेदार क्यों होगा? इसका कोई मतलब नहीं है। शायद आप इसमें शामिल तत्वों के साथ थोड़ा मार्कअप कर सकते हैं?
montrealist

@ कदलब - मैंने उदाहरण को थोड़ा स्पष्ट किया। ऐसा नहीं है कि एक मनमाना इनपुट दूसरों की जाँच के लिए जिम्मेदार है; यह है कि एक समूह में प्रत्येक इनपुट अन्य सभी की जाँच के लिए जिम्मेदार है।
नाथन लॉन्ग

यही मैंने सोचा, बहुत बहुत धन्यवाद!
मोंट्रेलिस्ट

3
धन्यवाद, यह मेरे लिए काम करता है, लेकिन फॉर्म में अन्य आवश्यक फ़ील्ड अब तब तक जवाब नहीं देते हैं जब तक कि वे लाभ न लें और चेक के बाद ध्यान केंद्रित न करें। (किसी ने इसे आपके अन्य प्रश्न पर एक उत्तर के रूप में जोड़ा, लेकिन इसे ध्वजांकित करना पड़ा क्योंकि यह उत्तर नहीं है)।
mydoghasworms

जवाबों:


21

यह एक उत्कृष्ट समाधान है नाथन। बहुत बहुत धन्यवाद।

यहाँ उपरोक्त कोड काम करने का एक तरीका है, अगर किसी को इसे एकीकृत करने में परेशानी होती है, जैसे मैंने किया था:

अतिरिक्त-Method.js फ़ाइल के अंदर कोड :

jQuery.validator.addMethod("require_from_group", function(value, element, options) {
...// Nathan's code without any changes
}, jQuery.format("Please fill out at least {0} of these fields."));

// "filone" is the class we will use for the input elements at this example
jQuery.validator.addClassRules("fillone", {
    require_from_group: [1,".fillone"]
});

HTML फ़ाइल के अंदर कोड :

<input id="field1" class="fillone" type="text" value="" name="field1" />
<input id="field2" class="fillone" type="text" value="" name="field2" />
<input id="field3" class="fillone" type="text" value="" name="field3" />
<input id="field4" class="fillone" type="text" value="" name="field4" />

अतिरिक्त-Method.js फ़ाइल को शामिल करना न भूलें!


खुशी है कि यह आपके लिए उपयोगी है, और जानकारी में छिल के लिए धन्यवाद। हालांकि, मैं AddClassRules विधि करने के बजाय, प्रत्येक व्यक्तिगत रूप पर नियमों की एक सरणी का उपयोग करना पसंद करता हूं। यदि आप इस पृष्ठ ( jquery.bassistance.de/validate/demo/milk ) पर जाते हैं और "इस पृष्ठ पर उपयोग की जाने वाली स्क्रिप्ट दिखाएं" पर क्लिक करें तो आपको एक उदाहरण दिखाई देगा। मैं इसे एक कदम आगे बढ़ाता हूं: मैं एक सरणी घोषित करता हूं जिसे "नियम" कहा जाता है, फिर अलग-अलग, मैं उन्हें var validator = $ ('# formtovalidate') के साथ उपयोग करता हूं।
नाथन लॉन्ग

एक और विचार: 'फिलोन' वर्ग जो आप यहाँ दिखाते हैं, वह समस्याग्रस्त हो सकता है। क्या होगा अगर, उसी रूप में, आपको कम से कम एक भाग संख्या, और कम से कम एक संपर्क नाम की आवश्यकता है? आपका नियम 0 संपर्क नामों को तब तक अनुमति देगा जब तक कि कम से कम एक भाग संख्या न हो। मुझे लगता है कि नियमों को सेट करना require_from_group: [1,".partnumber"]और ...[1,".contactname"]यह सुनिश्चित करना बेहतर है कि आप सही चीजों को मान्य कर रहे हैं।
नाथन लॉन्ग

6

अच्छा समाधान है। हालाँकि, मुझे काम नहीं करने वाले अन्य आवश्यक नियमों की समस्या थी। निष्पादन .valid () फ़ॉर्म के विरुद्ध मेरे लिए यह समस्या निर्धारित की गई।

if(!$(element).data('being_validated')) {
  var fields = $(selector, element.form);
  fields.data('being_validated', true); 
  $(element.form).valid();
  fields.data('being_validated', false);
}

1
धन्यवाद शॉन, मुझे भी यह समस्या हो रही थी। इस समाधान के साथ एक समस्या है, हालांकि, जब उपयोगकर्ता पहली बार फॉर्म में जाता है - जैसे ही वह पहली आवश्यकता-से-समूह फ़ील्ड भरता है, अन्य सभी फॉर्म फ़ील्ड को मान्य किया जाएगा और इस प्रकार दोषपूर्ण के रूप में चिह्नित किया जाएगा। जिस तरह से मैंने इसे हल किया वह वैद्यक का एक उदाहरण बनाने से पहले एक form.submit () हैंडलर जोड़ना था, जिसमें मैंने एक ध्वज सेट किया था validator.formSubmit = true। आवश्यकता-से-समूह विधि में मैं फिर उस झंडे की जाँच करता हूँ; अगर यह वहां है तो मैं करूंगा $(element.form).valid();, नहीं तो मैं करूंगा fields.valid();
क्रिस्टोफ

क्या कोई समझा सकता है कि वास्तव में यहाँ क्या ख़ुशी है? मेरे पास एक समान नियम है, जिसने काम किया है लेकिन जिसमें हमने पुनर्वितरण समस्या को संबोधित नहीं किया था (समूह में अन्य फ़ील्ड अभी भी अमान्य के रूप में चिह्नित हैं)। लेकिन अब मैं अनुभव कर रहा हूं कि फॉर्म अमान्य होने पर भी सबमिट होता है। यदि समूहीकृत फ़ील्ड मान्य हैं, तो यह सबमिटहैंडलर में प्रवेश नहीं करता है और यदि अमान्य है तो यह अमान्यहैंडलर में प्रवेश करता है, लेकिन फिर भी सबमिट करता है! मैं कहूंगा कि यह सत्यापन प्लगइन में एक काफी गंभीर बग है? जो नियम वैध है वह केवल उस नियम पर लागू होता है (पूरे क्षेत्र में भी नहीं) तो एक अमान्य फॉर्म क्यों प्रस्तुत किया जा रहा है?
एडम

मैंने आगे की जांच की है और यह समूह से पहले के क्षेत्र हैं जो भविष्य में मान्य नहीं हैं। मैंने इसे एक अलग प्रश्न के रूप में पूछा है (आंशिक वर्कअराउंड के साथ मैंने डिसोएवर किया है): stackoverflow.com/questions/12690898/…
एडम 12

4

धन्यवाद शॉन इस मुद्दे को मैंने अन्य नियमों की अनदेखी करने वाले कोड के साथ तय किया।

मैंने कुछ बदलाव भी किए हैं ताकि 'कृपया कम से कम 1 फ़ील्ड भरें ..' संदेश हर क्षेत्र के बाद एक अलग div में दिखाता है।

मान्य स्क्रिप्ट के रूप में डाल दिया

showErrors: function(errorMap, errorList){
            $("#form_error").html("Please fill out at least 1 field before submitting.");
            this.defaultShowErrors();
        },

इसे पृष्ठ में कहीं जोड़ें

<div class="error" id="form_error"></div>

आवश्यकता में जोड़ें_फ्रॉम_ग्रुप विधि ऐडमैथ फंक्शन

 if(validOrNot){
    $("#form_error").hide();
}else{
    $("#form_error").show();
}
......
}, jQuery.format(" &nbsp;(!)"));

4

मैंने एक पैच प्रस्तुत किया है जो उन मुद्दों से ग्रस्त नहीं है जो वर्तमान संस्करण करता है (जिससे "आवश्यक" विकल्प अन्य क्षेत्रों पर ठीक से काम करना बंद कर देता है, वर्तमान संस्करण के साथ समस्याओं की चर्चा जीथब पर है

पर उदाहरण http://jsfiddle.net/f887W/10/

jQuery.validator.addMethod("require_from_group", function (value, element, options) {
var validator = this;
var minRequired = options[0];
var selector = options[1];
var validOrNot = jQuery(selector, element.form).filter(function () {
    return validator.elementValue(this);
}).length >= minRequired;

// remove all events in namespace require_from_group
jQuery(selector, element.form).off('.require_from_group');

//add the required events to trigger revalidation if setting is enabled in the validator
if (this.settings.onkeyup) {
    jQuery(selector, element.form).on({
        'keyup.require_from_group': function (e) {
            jQuery(selector, element.form).valid();
        }
    });
}

if (this.settings.onfocusin) {
    jQuery(selector, element.form).on({
        'focusin.require_from_group': function (e) {
            jQuery(selector, element.form).valid();
        }
    });
}

if (this.settings.click) {
    jQuery(selector, element.form).on({
        'click.require_from_group': function (e) {
            jQuery(selector, element.form).valid();
        }
    });
}

if (this.settings.onfocusout) {
    jQuery(selector, element.form).on({
        'focusout.require_from_group': function (e) {
            jQuery(selector, element.form).valid();
        }
    });
}

return validOrNot;
}, jQuery.format("Please fill at least {0} of these fields."));

3

PHP में $ के साथ एक चर नाम शुरू करना आवश्यक है, लेकिन जावास्क्रिप्ट में बहुत अजीब (IMHO)। इसके अलावा, मेरा मानना ​​है कि आप इसे दो बार "$ मॉड्यूल" और एक बार "मॉड्यूल" के रूप में संदर्भित करते हैं, है ना? ऐसा लगता है कि इस कोड को काम नहीं करना चाहिए।

इसके अलावा, मुझे यकीन नहीं है कि यह सामान्य jQuery प्लगइन सिंटैक्स है, लेकिन मैं आपके AddMethod कॉल के ऊपर टिप्पणी जोड़ सकता हूं, यह समझाते हुए कि आप क्या पूरा करते हैं। ऊपर दिए गए अपने पाठ विवरण के साथ भी, कोड का पालन करना कठिन है, क्योंकि मैं किस क्षेत्र से परिचित नहीं हूं: भरा हुआ, मूल्य, तत्व या चयनकर्ता। शायद यह सबसे अधिक मान्य प्लगइन से परिचित किसी व्यक्ति के लिए स्पष्ट है, इसलिए सही मात्रा में स्पष्टीकरण के बारे में निर्णय का उपयोग करें।

शायद आप कोड को स्व-दस्तावेज करने के लिए कुछ संस्करणों को तोड़ सकते हैं; पसंद,

var atLeastOneFilled = module.find(...).length > 0;
if (atLeastOneFilled) {
  var stillMarkedWithErrors = module.find(...).next(...).not(...);
  stillMarkedWithErrors.text("").addClass(...)

(यह मानते हुए कि मैंने आपके कोड के इन अंशों का अर्थ समझ लिया है! :))

मुझे बिल्कुल यकीन नहीं है कि "मॉड्यूल" का क्या मतलब है, वास्तव में - क्या कोई और विशिष्ट नाम है जो आप इस चर को दे सकते हैं?

अच्छा कोड, कुल मिलाकर!


सुझावों के लिए धन्यवाद - मैंने चर नामों को स्पष्ट किया है और कोड को थोड़ा और पठनीय होने के लिए तोड़ दिया है।
नेथन लॉन्ग

2

क्योंकि मैं जिस फॉर्म पर काम कर रहा हूं, उसमें इन जैसे समूहीकृत इनपुट वाले कई क्लोन क्षेत्र हैं, मैंने आवश्यकता के लिए एक अतिरिक्त तर्क पास किया_प्रो_ग्रुप कंस्ट्रक्टर, जो आपके ऐडमेथोड फ़ंक्शन की बिल्कुल एक पंक्ति को बदल रहा है:

var commonParent = $(element).parents(options[2]);

और इस तरह एक चयनकर्ता, आईडी या तत्व का नाम एक बार पारित किया जा सकता है:

jQuery.validator.addClassRules("reqgrp", {require_from_group: [1, ".reqgrp", 'fieldset']});

और सत्यापनकर्ता उस फ़ील्ड के तत्वों के सत्यापन को केवल प्रत्येक फ़ील्डसेट के अंदर प्रतिबंधित करेगा, न कि प्रपत्र में सभी .regrgrp श्रेणी के तत्वों को गिनने का प्रयास करेगा।


2

रॉकेट हज़मत के जवाब में मेरी दरार यहाँ है, अन्य परिभाषित क्षेत्रों के मुद्दे को हल करने की कोशिश को भी मान्य करने की आवश्यकता है, लेकिन एक के सफल भरने पर सभी क्षेत्रों को मान्य के रूप में चिह्नित करना।

jQuery.validator.addMethod("require_from_group", function(value, element, options){
    var numberRequired = options[0],
    selector = options[1],
    $fields = $(selector, element.form),
    validOrNot = $fields.filter(function() {
        return $(this).val();
    }).length >= numberRequired,
    validator = this;
    if(!$(element).data('being_validated')) {
        $fields.data('being_validated', true).each(function(){
            validator.valid(this);
        }).data('being_validated', false);
    }
    if (validOrNot) {
    $(selector).each(function() {
            $(this).removeClass('error');
            $('label.error[for='+$(this).attr('id')+']').remove();
        });
    }
    return validOrNot;
}, jQuery.format("Please fill out at least {0} of these fields."));

इसके साथ एकमात्र शेष मुद्दा अब किनारे का मामला है जहां फ़ील्ड खाली है, फिर भरा हुआ है, फिर खाली है ... जिस स्थिति में त्रुटि एकल फ़ील्ड पर लागू होगी समूह नहीं। लेकिन ऐसा लगता है कि किसी भी आवृत्ति के साथ होने की संभावना नहीं है और यह अभी भी तकनीकी रूप से उस मामले में काम करता है।


इस उत्तर में कोई मतलब नहीं है क्योंकि यह विधि / नियम अप्रैल 2012 में वापस प्लगइन में एकीकृत किया गया था।
स्पार्की

मेरे पास एक ही मुद्दा है कि रॉकेट हज़मत के पास विधि है जो अब सत्यापनकर्ता के साथ जहाज करती है। यह पुष्टि करता है कि खेतों का एक समूह, लेकिन अन्य तरीकों का उपयोग करने वाले कोई अन्य क्षेत्र मान्य नहीं हैं। यह उत्तर उस मुद्दे को हल करने का एक प्रयास है। यदि आपके पास एक बेहतर समाधान है तो कृपया मुझे बताएं।
स्क्वायरकैंडी

: तक डेवलपर स्थायी रूप से इस मुद्दे के बजाय किसी भी भ्रम को जोड़ने ठीक करता है, मैं बस की सलाह देते हैं जो कुछ अस्थायी समाधान यहाँ का समर्थन किया जा रहा है github.com/jzaefferer/jquery-validation/issues/412
स्पार्की

1

मुझे इसके साथ संयोजन में अन्य नियमों की जाँच नहीं करने की समस्या थी, इसलिए मैं बदल गया:

fields.valid();

इसके लिए:

var validator = this;
fields.each(function(){
   validator.valid(this);
});

मैंने कुछ (व्यक्तिगत) सुधार भी किए, और यह वह संस्करण है जिसका मैं उपयोग कर रहा हूं:

jQuery.validator.addMethod("require_from_group", function(value, element, options){
    var numberRequired = options[0],
    selector = options[1],
    $fields = $(selector, element.form),
    validOrNot = $fields.filter(function() {
        return $(this).val();
    }).length >= numberRequired,
    validator = this;
    if(!$(element).data('being_validated')) {
        $fields.data('being_validated', true).each(function(){
            validator.valid(this);
        }).data('being_validated', false);
    }
    return validOrNot;
}, jQuery.format("Please fill out at least {0} of these fields."));

अन्य फ़ील्ड्स को फिर से मान्य बनाने का काम करता है, लेकिन अब, जब किसी समूह के सभी फ़ील्ड अमान्य के रूप में चिह्नित किए जाते हैं और आप एक को भरते हैं, तो केवल वह ही मान्य होता है। कम से कम मेरे लिए?
क्रिस्टोफ

@ क्रिस - मेरा नया जवाब देखें जो इस पर बनाता है और इसे संबोधित करता है।
स्क्वायरकैंडी

0

धन्यवाद, नाथन। आपने मुझे एक टन बचाया।

हालाँकि, मुझे ध्यान देना चाहिए कि यह नियम jQuery.noConflict () तैयार नहीं है। तो, एक को jQuery के साथ सभी $ को प्रतिस्थापित करना चाहिए,var $j = jQuery.noConflict()

और मेरा सवाल है: मैं इसे बिल्ट-इन रूल की तरह कैसे बनाऊंगा? उदाहरण के लिए, यदि मैं ईमेल दर्ज करता हूं, तो संदेश "कृपया मान्य ईमेल दर्ज करें" स्वचालित रूप से गायब हो जाता है, लेकिन अगर मैं किसी एक समूह फ़ील्ड को भरता हूं तो त्रुटि संदेश रहता है।


आप ठीक कह रहे हैं - मैंने नोकझोंक की स्थिति पर विचार नहीं किया। मैं भविष्य में इसे अपडेट कर सकता हूं, लेकिन यदि आप चाहें तो आसानी से एक खोज-और-जगह कर सकते हैं। आपके दूसरे प्रश्न के लिए, मुझे वही समस्या दिखाई नहीं दे रही है। एक त्वरित परीक्षण के साथ, यदि किसी समूह के एक क्षेत्र की आवश्यकता होती है, जैसे ही मैं कुछ भी टाइप करता हूं, पूरा समूह उस नियम को पारित कर देता है। यदि एक से अधिक की आवश्यकता है, जैसे ही अंतिम आवश्यक एक भर जाता है और फोकस खो देता है, पूरा समूह गुजरता है। यह है कि आप क्या देख रहे हैं?
नाथन लांग

हम्म किसी कारणवश खराब हो गया और मुझे इसे ठीक करने में कोई सफलता नहीं मिली
रिनैट

रिनट - क्या आप समस्या को सरल और संकीर्ण कर सकते हैं? एक सरल रूप में मेरे कोड का उपयोग करने का प्रयास करें, जिसे noconflict परिवर्तनों की आवश्यकता नहीं है। सबसे सरल रूप करें जिसे आप संभवतः उस पर परीक्षण कर सकते हैं, और पहले काम कर सकते हैं।
नाथन लॉन्ग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.