उपयोगकर्ता द्वारा फ़ील्ड छोड़ने के बाद फ़ील्ड को मान्य करें


92

AngularJS के साथ, मैं उपयोग कर सकता हूं ng-pristineया ng-dirtyयह पता लगाने के लिए कि उपयोगकर्ता ने क्षेत्र में प्रवेश किया है या नहीं । हालाँकि, मैं ग्राहक-क्षेत्र सत्यापन तभी करना चाहता हूँ जब उपयोगकर्ता ने क्षेत्र छोड़ दिया हो। ऐसा इसलिए है क्योंकि जब कोई उपयोगकर्ता ई-मेल या फोन की तरह किसी क्षेत्र में प्रवेश करता है, तो उन्हें हमेशा तब तक एक त्रुटि मिलेगी, जब तक कि उन्होंने अपना पूर्ण ई-मेल टाइप करना पूरा नहीं कर लिया हो, और यह एक इष्टतम उपयोगकर्ता अनुभव नहीं है।

उदाहरण


अपडेट करें:

कोणीय अब एक कस्टम कलंक घटना के साथ जहाज: https://docs.angularjs.org/api/ng/directive/ngBBur


3
मुझे लगता है कि यह कुछ एंगुलरज का समर्थन करना चाहिए था ...
सीएसजी

शायद। बिल्ट इन फॉर्म वेलिडेशन काफी अच्छी तरह से काम करता है कि मुझे नहीं पता कि मैं इसमें बिल्ट इन करना चाहूंगा। आखिरकार, सबसे ज्यादा ऐसे मामलों का उपयोग करता हूं, जो मैं चाहता हूं कि एंगुलर तुरंत मान्य हो जाए। यदि कोई नंबर फ़ील्ड में है, तो मैं चाहता हूं कि यदि उपयोगकर्ता पत्र लिखना शुरू कर देता है, तो मुझे तुरंत अमान्य करना होगा।
mcranston18

11
धुंधला होने पर सत्यापन 15 साल से आम है ...
ओलिवव

जवाबों:


75

कोणीय 1.3 में अब एनजी-मॉडल-विकल्प हैं, और आप { 'updateOn': 'blur'}उदाहरण के लिए विकल्प सेट कर सकते हैं , और आप बहस भी कर सकते हैं, जब उपयोग या तो बहुत तेजी से टाइप हो रहा है, या आप कुछ महंगे डोम संचालन (जैसे मॉडल लेखन) को सहेजना चाहते हैं कई डोम स्थानों के लिए और आप हर कुंजी पर एक $ पच चक्र घटित नहीं करना चाहते हैं)

https://docs.angularjs.org/guide/forms#custom-triggers और https://docs.angularjs.org/guide/forms#non-immediate-debulate-model-updates

डिफ़ॉल्ट रूप से, सामग्री में कोई भी परिवर्तन एक मॉडल अपडेट को ट्रिगर करेगा और सत्यापन का रूप देगा। आप केवल घटनाओं की निर्दिष्ट सूची में बाँधने के निर्देश के अनुसार इस व्यवहार को ओवरराइड कर सकते हैं। Ie एनजी-मॉडल-विकल्प = "{अपडेटऑन: 'ब्लर'}" नियंत्रण खो जाने के बाद ही अपडेट और मान्य होगा। आप एक स्थान सीमांकित सूची का उपयोग करके कई ईवेंट सेट कर सकते हैं। Ie एनजी-मॉडल-विकल्प = "{अपडेटऑन: 'मूसडाउन ब्लर'}"

और बहस करते हैं

आप ngModelOptions निर्देश के साथ डेबिट कुंजी का उपयोग करके मॉडल अद्यतन / सत्यापन में देरी कर सकते हैं। यह देरी $ गंदे या $ प्रिस्टाइन जैसे पार्सर्स, वैलिडेटर और मॉडल झंडे पर भी लागू होगी।

Ie एनजी-मॉडल-विकल्प = "{बहस: 500}" मॉडल अपडेट को ट्रिगर करने और सत्यापन को शुरू करने से पहले अंतिम सामग्री परिवर्तन के बाद से आधे सेकंड तक इंतजार करेगा।


2
ज्यादातर मामलों में यह समस्या को हल नहीं करता है, क्योंकि आप संभवतः ng-changeउपयोगकर्ता को फ़ील्ड छोड़ने से पहले इवेंट प्राप्त करना चाहते हैं । उदाहरण के लिए, मेरे मामले में मैं इनपुट फ़ील्ड के मान्य होते ही अपने एपीआई से नए डेटा का अनुरोध करता हूं, लेकिन मैं अमान्य होते ही त्रुटि संदेश नहीं दिखाना चाहता - मैं केवल यह तब करना चाहता हूं जब यह हो अमान्य और धब्बा घटना हुई।
टॉम

@ मैं परीक्षण कर रहा हूं 1.3.0 rc-3और यह changeतब तक फायर नहीं करता है blur, इसे देखें: plnkr.co/edit/RivVU3r7xfHO1hUybqMu?p=preview
Gill Bates

यह वास्तव में स्वीकृत, शीर्ष उत्तर होना चाहिए। एक निर्देश क्यों जोड़ें, जब आप एक एकल संपत्ति जोड़ सकते हैं?
डैन हॉल्टन

92

संस्करण 1.3.0 से यह आसानी से किया जा सकता है $touched, जो उपयोगकर्ता द्वारा क्षेत्र छोड़ने के बाद सच है।

<p ng-show="form.field.$touched && form.field.$invalid">Error</p>

https://docs.angularjs.org/api/ng/type/ngModel.NgModelController


1
क्या यह अभी भी प्रत्येक कुंजी-अप के बाद मान्यता को निष्पादित नहीं करेगा? ओपी ने कहा कि वह उपयोगकर्ता के क्षेत्र छोड़ने के बाद ही सत्यापन करना चाहता था।
कॉमकेम

@comecme हाँ यह होगा, डिफ़ॉल्ट एनजी-मॉडल-विकल्प, updateOn: 'default'जिसका अर्थ है, इनपुट के लिए, की-अप और चयन के लिए, परिवर्तन पर
pocesar

5
हालांकि, यहां बड़ी खामी यह है कि अगर आप वापस मैदान में आते हैं तो आपको वैसा ही अनुभव नहीं होगा। आप एक वर्ग में वापस आ गए हैं, जहां यह हर कीस्ट्रोके पर मान्य है, क्योंकि यह पहले से ही स्पर्श करने के लिए सेट है। मुझे आश्चर्य है कि यह बहुत सारे अपवित्र हैं।
ड्यूडेवड

3
@dudewad जो सही है, लेकिन मुझे लगता है कि यह वांछित व्यवहार UX वार है - यदि आप किसी अमान्य फ़ील्ड पर वापस आते हैं, तो त्रुटि संदेश तब तक जारी रहना चाहिए जब तक कि मूल्य मान्य न हो, तब तक जब तक आप पहला अक्षर टाइप नहीं करते।
दानबर्स

@dudewad क्या यह उपयोगकर्ता को प्रत्येक प्रेस पर मान्य करने में मदद नहीं करेगा, क्योंकि वे पहले से ही पहली बार भरे जाने के बाद किसी क्षेत्र को अमान्य मानते हैं? एक बार जब वे जानते हैं कि क्षेत्र अमान्य था, तो संभावना है कि वे जल्दी से जानना चाहेंगे कि क्षेत्र कब वैध है और प्रत्येक कुंजी प्रेस पर मान्य करने से उस प्रक्रिया में तेजी आएगी?
एलन डायनामिक

32

मैंने जो @jlmcdonald का सुझाव दिया था, उस पर विस्तार करके इसे हल किया। मैंने एक निर्देश बनाया जो स्वचालित रूप से सभी इनपुट और चयन तत्वों पर लागू होगा:

var blurFocusDirective = function () {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function (scope, elm, attr, ctrl) {
            if (!ctrl) {
                return;
            }

            elm.on('focus', function () {
                elm.addClass('has-focus');

                scope.$apply(function () {
                    ctrl.hasFocus = true;
                });
            });

            elm.on('blur', function () {
                elm.removeClass('has-focus');
                elm.addClass('has-visited');

                scope.$apply(function () {
                    ctrl.hasFocus = false;
                    ctrl.hasVisited = true;
                });
            });

            elm.closest('form').on('submit', function () {
                elm.addClass('has-visited');

                scope.$apply(function () {
                    ctrl.hasFocus = false;
                    ctrl.hasVisited = true;
                });
            });

        }
    };
};

app.directive('input', blurFocusDirective);
app.directive('select', blurFocusDirective);

यह विभिन्न तत्वों को जोड़ेगा has-focusऔर has-visitedकक्षाएं देगा क्योंकि उपयोगकर्ता तत्वों पर ध्यान केंद्रित करता है। सत्यापन त्रुटियों को दिखाने के लिए आप अपने CSS नियमों में इन वर्गों को जोड़ सकते हैं:

input.has-visited.ng-invalid:not(.has-focus) {
    background-color: #ffeeee;   
}

यह उन तत्वों में अच्छी तरह से काम करता है जो अभी भी $ अवैध संपत्ति आदि प्राप्त करते हैं, लेकिन उपयोगकर्ता को बेहतर अनुभव देने के लिए CSS का उपयोग किया जा सकता है।


2
केवल 'ngModel' के बजाय '? NgModel' की आवश्यकता क्यों है? मैं समझता हूं कि एनजीमॉडल की आवश्यकता है, लेकिन प्रश्न चिह्न क्यों?
नोरेमैक

2
विचार के लिए धन्यवाद। यह इंगित करना चाहिए कि इसे jQuery की आवश्यकता है (मुझे लगता है - jql में एक .closest () नहीं देख सका)।
ianनडॉटकेली

1
सभी <input> तत्व ngModel (जैसे इनपुट प्रकार = सबमिट) द्वारा समर्थित नहीं हैं। ? केवल एनमॉडल की आवश्यकता होती है जो इसका समर्थन करने वाले तत्वों पर करें।
22

5
ईमानदार होने के लिए, आपको इनपुट फ़ील्ड राज्यों की तरह कोणीय तरीके से विचलन नहीं करना चाहिए formName.inputName.$dirty। मैं एक समान बूलियन लिखने के निर्देश को संपादित करने का सुझाव दूंगा formName.inputName.$focused, बजाय सत्यापन के लिए धब्बा और बूलियन के लिए वर्ग नामों का उपयोग करने के बजाय।
टॉम

17

मैं सीएसएस के एक बहुत ही सरल बिट के साथ ऐसा करने में कामयाब रहा। इसके लिए आवश्यक है कि त्रुटि संदेश उन इनपुट के भाई-बहन हों, जिनसे वे संबंधित हैं, और जिनके पास उनका वर्ग है error

:focus ~ .error {
    display:none;
}

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


2
आह। यह जाने का एक स्मार्ट तरीका है। मैं इसे करने के लिए जावास्क्रिप्ट लिखने पर बहुत पसंद करता हूं।
डेक

5
इस दृष्टिकोण का नकारात्मक पक्ष यह है कि जब कोई त्रुटि को सुधार रहा है तो त्रुटि अब दिखाई नहीं दे रही है जो आदर्श नहीं है। आदर्श यह होगा कि त्रुटि तब तक दिखाई न दे जब तक धुंधला न हो जाए लेकिन तब तक गायब न हो जब तक इसे ठीक नहीं किया जाता।
क्रिस निकोला

4

यह कोणीय के नए संस्करणों में मानक के रूप में लागू किया गया लगता है।

उपयोगकर्ता द्वारा पहले और बाद में वर्ग -अछूता और गैर-छुआ हुआ वर्ग क्रमशः सेट किया गया है और एक मान्य तत्व पर ध्यान केंद्रित किया गया है।

सीएसएस

input.ng-touched.ng-invalid {
   border-color: red;
}

4

@ लैम्बिनेटर के समाधान के बारे में ... मुझे कोणीय में निम्नलिखित त्रुटि मिल रही थी। 1.2 1.2:

त्रुटि: [$ rootScope: inprog] $ पहले से ही प्रगति में है

मुझे यकीन नहीं है कि मैंने कुछ गलत किया है या अगर यह कोणीय में बदलाव है, लेकिन scope.$applyबयानों को हटाने से समस्या हल हो गई और कक्षाएं / राज्य अभी भी अपडेट हो रहे हैं।

यदि आप भी इस त्रुटि को देख रहे हैं, तो निम्नलिखित प्रयास करें:

var blurFocusDirective = function () {
  return {
    restrict: 'E',
    require: '?ngModel',
    link: function (scope, elm, attr, ctrl) {
      if (!ctrl) {
        return;
      }
      elm.on('focus', function () {
        elm.addClass('has-focus');
        ctrl.$hasFocus = true;
      });

      elm.on('blur', function () {
        elm.removeClass('has-focus');
        elm.addClass('has-visited');
        ctrl.$hasFocus = false;
        ctrl.$hasVisited = true;
      });

      elm.closest('form').on('submit', function () {
        elm.addClass('has-visited');

        scope.$apply(function () {
          ctrl.hasFocus = false;
          ctrl.hasVisited = true;
        });
      });
    }
  };
};
app.directive('input', blurFocusDirective);
app.directive('select', blurFocusDirective);

2

यह आपके लिए एक कस्टम निर्देश लिखने के लिए काम कर सकता है जो जावास्क्रिप्ट ब्लर () विधि को लपेटता है (और ट्रिगर होने पर एक सत्यापन फ़ंक्शन चलाता है); वहाँ एक कोणीय मुद्दा है जिसमें एक नमूना है (साथ ही एक सामान्य निर्देश है जो अन्य घटनाओं के लिए बाध्य कर सकता है जो मूल रूप से कोणीय द्वारा समर्थित नहीं है):

https://github.com/angular/angular.js/issues/1277

यदि आप उस मार्ग पर नहीं जाना चाहते हैं, तो आपका दूसरा विकल्प क्षेत्र में $ घड़ी स्थापित करना होगा, फिर से फ़ील्ड भरते समय मान्यता को ट्रिगर करना।


2

दिए गए उत्तरों पर और अधिक जानकारी प्राप्त करने के लिए, आप CSS3 छद्म वर्गों का उपयोग करके इनपुट टैगिंग को सरल बना सकते हैं और केवल एक कक्षा के साथ विज़िट किए गए फ़ील्ड को चिह्नित कर सकते हैं ताकि सत्यापन त्रुटियों को प्रदर्शित करने में देरी हो सके जब तक उपयोगकर्ता फ़ील्ड पर ध्यान केंद्रित न कर ले:

(उदाहरण के लिए jQuery की आवश्यकता है)

जावास्क्रिप्ट

module = angular.module('app.directives', []);
module.directive('lateValidateForm', function () {
    return {
        restrict: 'AC',
        link: function (scope, element, attrs) {
            $inputs = element.find('input, select, textarea');

            $inputs.on('blur', function () {
                $(this).addClass('has-visited');
            });

            element.on('submit', function () {
                $inputs.addClass('has-visited');
            });
        }
    };
});

सीएसएस

input.has-visited:not(:focus):required:invalid,
textarea.has-visited:not(:focus):required:invalid,
select.has-visited:not(:focus):required:invalid {
  color: #b94a48;
  border-color: #ee5f5b;
}

एचटीएमएल

<form late-validate-form name="userForm">
  <input type="email" name="email" required />
</form>

2

@nicolas उत्तर के आधार पर .. शुद्ध CSS को ट्रिक चाहिए, यह केवल धब्बा पर त्रुटि संदेश दिखाएगा

<input type="email" id="input-email" required
               placeholder="Email address" class="form-control" name="email"
               ng-model="userData.email">
        <p ng-show="form.email.$error.email" class="bg-danger">This is not a valid email.</p>

सीएसएस

.ng-invalid:focus ~ .bg-danger {
     display:none;
}

यह अच्छा है, लेकिन उपयोगकर्ता द्वारा फ़ील्ड में वापस क्लिक करने पर त्रुटि संदेश गायब हो जाएगा, जो आदर्श नहीं है।
बेनेट मैकलेवे

2

यहां एनजी-संदेश (कोणीय 1.3 में उपलब्ध) और एक कस्टम निर्देश का उपयोग करके एक उदाहरण दिया गया है।

पहली बार उपयोगकर्ता द्वारा इनपुट फ़ील्ड छोड़ने पर सत्यापन संदेश धब्बा पर प्रदर्शित किया जाता है, लेकिन जब वह मान को सही करता है, तो सत्यापन संदेश तुरंत हटा दिया जाता है (अब धब्बा पर नहीं)।

जावास्क्रिप्ट

myApp.directive("validateOnBlur", [function() {
    var ddo = {
        restrict: "A",
        require: "ngModel",
        scope: {},
        link: function(scope, element, attrs, modelCtrl) {
            element.on('blur', function () {
                modelCtrl.$showValidationMessage = modelCtrl.$dirty;
                scope.$apply();
            });
        }
    };
    return ddo;
}]);

एचटीएमएल

<form name="person">
    <input type="text" ng-model="item.firstName" name="firstName" 
        ng-minlength="3" ng-maxlength="20" validate-on-blur required />
    <div ng-show="person.firstName.$showValidationMessage" ng-messages="person.firstName.$error">
        <span ng-message="required">name is required</span>
        <span ng-message="minlength">name is too short</span>
        <span ng-message="maxlength">name is too long</span>
    </div>
</form>

पुनश्च। अपने मॉड्यूल में ngMessages को डाउनलोड और शामिल करना न भूलें:

var myApp = angular.module('myApp', ['ngMessages']);

1

एनजीएलआरजेएस 1.3 में एनजी-मॉडल-विकल्प (इस लेखन के रूप में बीटा) को {अपडेटऑन: 'ब्लर'} का समर्थन करने के लिए प्रलेखित किया गया है। पहले के संस्करणों के लिए, मेरे लिए निम्नलिखित जैसे कुछ काम किया:

myApp.directive('myForm', function() {
  return {
    require: 'form',
    link: function(scope, element, attrs, formController) {
      scope.validate = function(name) {
        formController[name].isInvalid
            = formController[name].$invalid;
      };
    }
  };
});

इस तरह से एक टेम्पलेट के साथ:

<form name="myForm" novalidate="novalidate" data-my-form="">
<input type="email" name="eMail" required="required" ng-blur="validate('eMail')" />
<span ng-show="myForm.eMail.isInvalid">Please enter a valid e-mail address.</span>
<button type="submit">Submit Form</button>
</form>

1

फ़ील्ड का उपयोग करें $ छुआ हुआ क्षेत्र इसके लिए स्पर्श किया गया है जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है।

<div ng-show="formName.firstName.$touched && formName.firstName.$error.required">
    You must enter a value
</div>

0

आप गैर-वर्ग और संबद्ध नियंत्रक के दायरे पर एक संपत्ति का उपयोग करके गतिशील रूप से सीएसएस वर्ग (मान लें कि आप बूटस्ट्रैप का उपयोग कर रहे हैं) सेट कर सकते हैं:

plunkr: http://plnkr.co/edit/HYDlaTNThZE02VqXrUCH?p=info

HTML:

<div ng-class="{'has-error': badEmailAddress}">
    <input type="email" class="form-control" id="email" name="email"
        ng-model="email" 
        ng-blur="emailBlurred(email.$valid)">
</div>

नियंत्रक:

$scope.badEmailAddress = false;

$scope.emailBlurred = function (isValid) {
    $scope.badEmailAddress = !isValid;
};

0

यदि आप बूटस्ट्रैप 3 और उससे कम का उपयोग करते हैं, तो आप निम्न स्निपेट के साथ धब्बा सत्यापन को सक्षम कर सकते हैं:

:focus ~ .form-control-feedback.glyphicon-ok {
  display:none;
}

:focus ~ .form-control-feedback.glyphicon-remove {
  display:none;
}

.has-feedback > :focus {
  & {
    .form-control-focus();
  }
}

0

outI ने एक निर्देश का उपयोग किया। यहाँ कोड है:

app.directive('onBlurVal', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs, controller) {

            element.on('focus', function () {
                element.next().removeClass('has-visited');
                element.next().addClass('has-focus');
            });

            element.on('blur', function () {

                element.next().removeClass('has-focus');
                element.next().addClass('has-visited');
            });
        }
    }
})

मेरे सभी इनपुट नियंत्रण में अगले तत्व के रूप में एक स्पैन तत्व होता है, जो कि मेरा सत्यापन संदेश प्रदर्शित होता है और इसलिए प्रत्येक इनपुट नियंत्रण में एक विशेषता के रूप में निर्देश जोड़ा जाता है।

मेरे पास (वैकल्पिक) .has- फ़ोकस और मेरी सीएसएस फ़ाइल में सीएसएस क्लास है, जिसे आप निर्देश में संदर्भित होते हुए देखते हैं।

नोट: एपोस्ट्रोफिस के बिना अपने इनपुट नियंत्रण के लिए इस तरह से 'ऑन-ब्लर-वैल' को जोड़ना याद रखें


0

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

<input type="text" class="form-control" name="inputPhone" ng-model="demo.phoneNumber" required ng-focus> <div ng-show="demoForm.inputPhone.$dirty && demoForm.inputPhone.$invalid && !demoForm.inputPhone.$focused"></div>


0

हम onfocus और onblur फ़ंक्शन का उपयोग कर सकते हैं। सरल और सबसे अच्छा होगा।

<body ng-app="formExample">
  <div ng-controller="ExampleController">
  <form novalidate class="css-form">
    Name: <input type="text" ng-model="user.name" ng-focus="onFocusName='focusOn'" ng-blur="onFocusName=''" ng-class="onFocusName" required /><br />
    E-mail: <input type="email" ng-model="user.email" ng-focus="onFocusEmail='focusOn'" ng-blur="onFocusEmail=''" ng-class="onFocusEmail" required /><br />
  </form>
</div>

<style type="text/css">
 .css-form input.ng-invalid.ng-touched {
    border: 1px solid #FF0000;
    background:#FF0000;
   }
 .css-form input.focusOn.ng-invalid {
    border: 1px solid #000000;
    background:#FFFFFF;
 }
</style>

यहाँ कोशिश करें:

http://plnkr.co/edit/NKCmyru3knQiShFZ96tp?p=preview

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.