इनपुट क्षेत्र पर ध्यान कैसे सेट करें?


759

AngularJS में इनपुट क्षेत्र पर ध्यान केंद्रित करने के लिए 'कोणीय तरीका' क्या है?

अधिक विशिष्ट आवश्यकताओं:

  1. जब एक मोडल खोला जाता है, तो <input>इस मोडल के अंदर एक पूर्वनिर्धारित पर ध्यान केंद्रित करें।
  2. हर बार <input>दृश्यमान हो जाता है (जैसे कुछ बटन पर क्लिक करके), उस पर ध्यान केंद्रित करें।

मैं पहली आवश्यकता को प्राप्त करने की कोशिश की के साथ autofocus, लेकिन यह काम करता है केवल जब मॉडल पहली बार के लिए खोला जाता है, और केवल कुछ ब्राउज़र में (जैसे फ़ायरफ़ॉक्स में यह नहीं काम करता है)।

किसी भी तरह की सहायता को आभार समझेंगे।

जवाबों:


579
  1. जब एक मोडल खोला जाता है, तो इस मोडल के अंदर एक पूर्वनिर्धारित <इनपुट> पर ध्यान केंद्रित करें।

एक निर्देश को परिभाषित करें और इसके पास $ प्रॉपर्टी / ट्रिगर देखें ताकि यह पता चले कि तत्व को कब फोकस करना है:

Name: <input type="text" focus-me="shouldBeOpen">

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh's comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

Plunker

रेंडर करने के लिए मोडल समय देने के लिए $ टाइमआउट की आवश्यकता प्रतीत होती है।

'2.' हर बार <इनपुट> दृश्यमान हो जाता है (जैसे कुछ बटन पर क्लिक करके), उस पर ध्यान केंद्रित करें।

आवश्यक रूप से ऊपर दिए गए एक निर्देश को बनाएं। कुछ स्कोप प्रॉपर्टी देखें, और जब यह सच हो जाए (इसे अपने एनजी-क्लिक हैंडलर में सेट करें), निष्पादित करें element[0].focus()। आपके उपयोग के मामले के आधार पर, आपको इस के लिए $ $ समय की आवश्यकता हो सकती है या नहीं भी हो सकती है:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.focusMe, function(value) {
        if(value === true) { 
          console.log('value=',value);
          //$timeout(function() {
            element[0].focus();
            scope[attrs.focusMe] = false;
          //});
        }
      });
    }
  };
});

Plunker


अपडेट 7/2013 : मैंने देखा है कि कुछ लोग मेरे मूल अलग-अलग गुंजाइश निर्देशों का उपयोग करते हैं और फिर एम्बेडेड इनपुट फ़ील्ड (यानी, मोडल में एक इनपुट फ़ील्ड) के साथ समस्या है। कोई नया दायरा (या संभवत: एक नया बच्चा गुंजाइश) वाला निर्देश कुछ दर्द को कम कर सकता है। तो ऊपर मैंने अलग-अलग स्कैप्स का उपयोग न करने के उत्तर को अपडेट किया। नीचे मूल उत्तर है:

1. के लिए मूल जवाब, एक अलग गुंजाइश का उपयोग कर:

Name: <input type="text" focus-me="{{shouldBeOpen}}">

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '@focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === "true") { 
          $timeout(function() {
            element[0].focus(); 
          });
        }
      });
    }
  };
});

प्लंकर

2. के लिए मूल जवाब, एक अलग गुंजाइश का उपयोग कर:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

प्लंकर

चूँकि हमें निर्देशन में ट्रिगर / फ़ोकस इंपुट संपत्ति को रीसेट करने की आवश्यकता है, इसलिए '=' का उपयोग दो तरफ़ा डेटाबाइंडिंग के लिए किया जाता है। पहले निर्देशन में, '@' पर्याप्त था। यह भी ध्यान दें कि '@' का उपयोग करते समय हम ट्रिगर मूल्य की तुलना "सत्य" से करते हैं क्योंकि @ हमेशा एक स्ट्रिंग में परिणाम होता है।


1
@ जोश के "फोकस" निर्देश को भी देखें: stackoverflow.com/a/14859639/215945 उन्होंने अपने कार्यान्वयन में एक अलग दायरे का उपयोग नहीं किया।
मार्क राजकोक

2
@MarkRajcok इस बारे में उत्सुक है: यह संस्करण काम करता है लेकिन अगर मैं ng-modelइनपुट फ़ील्ड पर सेट करता हूं , तो जब मैं इस निर्देश w / आइसोलेटेड स्कोप का उपयोग करता हूं तो मॉडल मान खो जाता है। समस्या यह नहीं है अगर मैं जोश संस्करण w / अलग गुंजाइश की कोशिश करो। फिर भी एक नौसिखिया, और मैं अंतर समझना चाहूंगा। यहाँ एक प्लंकर है जो इसे दिखाता है।
सुनील डी।

1
मैंने पाया कि # 1 AngularJS 1.0.6 के साथ बहुत अच्छा काम करता है। हालांकि, जब एक डिबगर के नीचे चल रहा था, मैंने देखा कि हर बार जब मैंने खारिज कर दिया और अपने मॉडल को फिर से खोल दिया, तो मैं उस फ़ंक्शन को एक और अतिरिक्त कॉल देख रहा था जो समय से पहले ध्यान केंद्रित करता है। मैंने उस फ़ंक्शन को थोड़ा संशोधित किया जब घड़ी को अनबाइंड करने के लिए value != "true", और जो मेरे मुद्दे को संबोधित करने के लिए दिखाई दिया।
एंड्रयू ब्राउन

1
इसलिए ... एक स्टेटफुल पेज पर मैंने एक ही बात की थी क्योंकि $ वॉच $ वॉच है और एंगुलर डेवलपर्स $ वॉच से प्यार करते हैं ... अच्छी तरह से मैं एक समस्या से टकराता हूं, मि @ मर्कराजकॉक, एक समस्या जिसका मैंने हल किया है (बेसिक) सॉल्यूशन I नीचे प्रस्तावित है।
बेन लेश

3
मेरे लिए hmm कोड काम करता है, जैसा कि मैं देख सकता हूं कि यह ठीक से निष्पादित हो रहा है और तत्व [0] सही नियंत्रण है। हालाँकि .focus () फोकस को ट्रिगर नहीं करता है। संभवतः बूटस्ट्रैप या कुछ और इसके साथ हस्तक्षेप कर रहा है?
सोनिक सोल

264

(संपादित करें: मैंने इस स्पष्टीकरण के नीचे एक अद्यतन समाधान जोड़ा है)

मार्क Rajcok आदमी है ... और उसके जवाब के लिए एक वैध जवाब है, लेकिन यह है एक दोष (खेद मार्क) था ...

... इनपुट पर ध्यान केंद्रित करने के लिए बूलियन का उपयोग करने का प्रयास करें, फिर इनपुट को धुंधला करें, फिर इनपुट का ध्यान केंद्रित करने के लिए इसका उपयोग करने का प्रयास करें। यह तब तक काम नहीं करेगा जब तक आप बूलियन को झूठे, $ पचाने के लिए रीसेट नहीं करते हैं, फिर इसे सही पर वापस सेट करें। यहां तक ​​कि अगर आप अपनी अभिव्यक्ति में एक स्ट्रिंग तुलना का उपयोग करते हैं, तो आपको स्ट्रिंग को कुछ और, $ डाइजेस्ट में बदलने के लिए मजबूर किया जाएगा, फिर इसे वापस बदल दें। (यह ब्लर इवेंट हैंडलर के साथ संबोधित किया गया है।)

इसलिए मैं इस वैकल्पिक समाधान का प्रस्ताव करता हूं:

एक घटना, एंगुलर की भूली हुई विशेषता का उपयोग करें।

जावास्क्रिप्ट सब के बाद की घटनाओं को प्यार करता है। घटनाएँ स्वाभाविक रूप से शिथिल होती हैं, और इससे भी बेहतर, आप अपने $ डाइजेस्ट में एक और $ घड़ी जोड़ने से बचते हैं।

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e) {
          elem[0].focus();
      });
   };
});

तो अब आप इसे इस तरह से उपयोग कर सकते हैं:

<input type="text" focus-on="newItemAdded" />

और फिर आपके ऐप में कहीं भी ...

$scope.addNewItem = function () {
    /* stuff here to add a new item... */

    $scope.$broadcast('newItemAdded');
};

यह बहुत बढ़िया है क्योंकि आप इस तरह की चीजों के साथ सभी प्रकार की चीजें कर सकते हैं। एक के लिए, आप पहले से मौजूद घटनाओं में बाँध सकते हैं। एक और चीज़ के लिए आप अपने ऐप के विभिन्न हिस्सों को प्रकाशित करके कुछ स्मार्ट करना शुरू करते हैं, जो आपके ऐप के अन्य हिस्सों की सदस्यता ले सकते हैं।

किसी भी तरह से, इस तरह की चीज मेरे लिए "घटना संचालित" चिल्लाती है। मुझे लगता है कि कोणीय डेवलपर्स के रूप में हम घटना आकार छेद में $ गुंजाइश आकार के खूंटे को हथौड़ा करने के लिए वास्तव में कठिन प्रयास करते हैं।

क्या यह सबसे अच्छा समाधान है? मुझे नही पता। यह एक समाधान है।


अद्यतन समाधान

नीचे @ ShimonRachlenko की टिप्पणी के बाद, मैंने इसे थोड़ा करने का अपना तरीका बदल दिया है। अब मैं एक सेवा और एक निर्देशन के संयोजन का उपयोग करता हूं जो एक घटना को "पर्दे के पीछे" संभालता है:

इसके अलावा, यह ऊपर उल्लिखित एक ही प्रिंसिपल है।

यहाँ एक त्वरित डेमो प्लंक है

प्रयोग

<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
    focus('focusMe');
});

स्रोत

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on('focusOn', function(e, name) {
        if(name === attr.focusOn) {
          elem[0].focus();
        }
      });
   };
});

app.factory('focus', function ($rootScope, $timeout) {
  return function(name) {
    $timeout(function (){
      $rootScope.$broadcast('focusOn', name);
    });
  }
});

3
आप करने के लिए कॉल रैप करने के लिए की जरूरत $broadcastके साथ $timeoutअगर आप नियंत्रक में प्रवेश पर काम करने के लिए इस चाहते हैं। अन्यथा अच्छा समाधान।
शिमोन रैचलेंको

@ShimonRachlenko - धन्यवाद। लेकिन मुझे यकीन नहीं है कि $ टाइमआउट से आपका क्या मतलब है। यदि मैं तब चाहता था जब नियंत्रक निर्माणकर्ता को संसाधित किया जा रहा था, मैं अभी प्रसारित करूंगा। एक टाइमआउट कुछ भी नहीं करेगा, लेकिन बाद में इवेंट लूप में प्रसारण को स्थगित कर देगा।
बेन लेश

1
हां, और यह निर्देश को आरंभ करने के लिए पर्याप्त है। निर्देश को सुनने के लिए शुरू होने से पहले घटना को प्रसारित किया जाता है .. फिर, यह केवल तब आवश्यक है जब आप पृष्ठ में प्रवेश करते समय अपने निर्देश को ट्रिगर करना चाहते हैं।
शिमोन रैचलेंको

2
तुम सही हो। मुझे लगता है कि मैंने लोड पर ध्यान केंद्रित करने के लिए इसका इस्तेमाल नहीं किया था। मैं उत्तर को कुछ और मजबूत के साथ अपडेट करूंगा।
बेन लेश

1
यह अब तक, सबसे सुरुचिपूर्ण, "कोणीय तरीका" समाधान है। हालांकि मैं ज्यादातर कोड की नकल करता था जब मैं पहली बार इस समस्या में भाग जाता था, मुझे खुशी है कि आपने इसके लिए एक मॉड्यूल बनाया! मुझे ईमानदारी से लगता है कि यह कोर कोणीय में लाने के प्रयास के लायक हो सकता है।
Randolpho

241

मुझे कुछ अन्य उत्तर अति जटिल लगे हैं जब आपको वास्तव में इसकी आवश्यकता होती है

app.directive('autoFocus', function($timeout) {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            $timeout(function(){
                _element[0].focus();
            }, 0);
        }
    };
});

उपयोग है

<input name="theInput" auto-focus>

हम टाइमआउट का उपयोग डोम रेंडर में चीजों को करने के लिए करते हैं, भले ही यह शून्य हो, यह कम से कम इंतजार करता है - इस तरह से यह मोडल में काम करता है और व्हाट्सएप भी


1
ऐसा करने के लिए कई तरीके होंगे, एक संभव तरीका जो वास्तव में सीधा आगे है और आसान है जो गुंजाइश (नियंत्रक यहां) पर होगा उस आइटम की आईडी सेट करें जिसे आप बटन क्लिक करने पर ध्यान केंद्रित करना चाहते हैं, फिर निर्देश बस यह सुनो। इस मामले में आपको निर्देश को विशेष रूप से कहीं भी नहीं रखना होगा, बस उस पृष्ठ के भीतर कहीं (मैंने अतीत में सफलता के साथ इस तरह के द्रष्टा निर्देशों का उपयोग किया है, विशेष रूप से चीजों को केंद्रित करने और चीजों को स्क्रॉल करने के साथ) - फिर अगर आप ' jquery का उपयोग करके (इस सरल बना देगा) बस उस तत्व आईडी को ढूंढें और उस पर ध्यान केंद्रित करें
ecancil

14
यदि इनपुट पॉपअप मोडल में स्थित है, तो शून्य टाइमआउट के साथ समाधान मेरे लिए काम नहीं करता है। लेकिन यहां तक ​​कि 10 एमएस ने इस मुद्दे को ठीक किया
यूजीन फिदेलिन

@ecancil: मुझे आपका दृष्टिकोण पसंद है क्योंकि यह सबसे सरल है, लेकिन आपको IE में ~ 500ms को मध्यांतर सेट करने की आवश्यकता है क्योंकि मोडल उपस्थिति का एनीमेशन इनपुट के बाहर एक निमिष कर्सर में परिणाम करता है। मुझे एनीमेशन के समाप्त होने पर ऐसा होने का एक अच्छा तरीका नहीं पता है, इसलिए मैं इसे 500ms के साथ बाध्य करता हूं।
देवका

काम नहीं करेगा, अगर आपको डेटाबेस से अधिक डेटा खींचना है, तो नियंत्रक को पुलिंग डेटा को पूरा करने की प्रतीक्षा करनी होगी, इसलिए 0 की जगह पर्याप्त समय जोड़ें
अली एड्रावी

1
@Ade जैसे लोगों के लिए जो इसे एक सरल के साथ उपयोग करना चाहते हैं ng-click: मान लें कि ng-click="showInput = !showInputआपके इनपुट पर एक बटन पर क्लिक करना है । फिर, अपने वास्तविक इनपुट पर, जोड़ें ng-if="showInput"। बटन को टॉगल करने से डायरेक्टिव हर बार री-रन करेगा। मैं इस के साथ एक समस्या थी क्योंकि मैं उपयोग कर रहा था ng-showजो गलत दृष्टिकोण है।
JVG

91

HTML में एक विशेषता है autofocus

<input type="text" name="fname" autofocus>

http://www.w3schools.com/tags/att_input_autofocus.asp


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

62

आप कोणीय में निर्मित jqlite कार्यक्षमता का भी उपयोग कर सकते हैं।

angular.element('.selector').trigger('focus');


2
बिना jquery लोड किए: angular.forEach (document.querySelectorAll ('selector'), function (elem) {elem.focus ();});
दान बेनामी

29
यह एक नियंत्रक में डाल करने के लिए एक बुरा अभ्यास नहीं है?
विटाली

2
यदि इस jqlite लाइन को एक कंट्रोलर के अंदर रखना बुरा व्यवहार है, तो क्या इस jqlite लाइन को एक निर्देश के अंदर रखना बेहतर नहीं होगा?
खेल

3
मुझे यह मिलता है:Looking up elements via selectors is not supported by jqLite!
मारिया इनेस पर्निसारी

1
@VitalyB मेरे पास एक ऐसा मामला था जहाँ मुझे ajax कॉल के बाद एक तत्व को धुंधला करने की आवश्यकता थी। मैं नियंत्रक के अंदर कॉलबैक में शुद्ध जेएस की सिर्फ एक पंक्ति जोड़ सकता हूं, या उस इनपुट के धुंधलेपन के लिए विशेष रूप से संपूर्ण निर्देश का निर्माण कर सकता हूं। मुझे लगा कि यह बहुत परेशानी वाला है, इसलिए मैं पहले विकल्प के लिए गया।
सेबेस्टियनब

55

यह अच्छी तरह से काम करता है और इनपुट नियंत्रण पर ध्यान केंद्रित करने के लिए कोणीय तरीका है

angular.element('#elementId').focus()

यह हालांकि कार्य करने का एक शुद्ध कोणीय तरीका नहीं है, फिर भी वाक्यविन्यास कोणीय शैली का अनुसरण करता है। Jquery अप्रत्यक्ष रूप से भूमिका निभाता है और सीधे Angular (jQLite => JQuery लाइट) का उपयोग करके DOM तक पहुँचता है।

यदि आवश्यक हो, तो यह कोड आसानी से एक सरल कोणीय निर्देश के अंदर रखा जा सकता है जहां तत्व सीधे पहुंच योग्य है।


मुझे यकीन नहीं है कि यह ViewModel-apps के लिए एक महान दृष्टिकोण है। कोणीय में इसे निर्देशों के माध्यम से किया जाना चाहिए।
अगत

जैसे अगर कोई टेक्सबॉक्स ए बदलता है और आपको दूसरे टेक्स्ट बॉक्स पर पॉप अप दिखाने और फोकस सेट करने की आवश्यकता होती है
संजीव सिंह

1
इसका उपयोग करते समय मुझे यह त्रुटि हो रही है:Looking up elements via selectors is not supported by jqLite!
JVG

6
जहां तक ​​मैं बता सकता हूं कि आपको पहले निर्भरता के रूप में jQuery लोड करने की आवश्यकता होगी, जिस स्थिति के angular.elementलिए एक आवरण बन जाता है $() / jQuery()। तो इसके बिना यह काम नहीं करेगा, और आप मूल रूप से वैसे भी jQuery का उपयोग कर रहे हैं (लेकिन मुझे गलत होने पर सही करें)
JVG

@Jascination: jqLite को jQuery निर्भरता को हटाने के लिए विकसित किया गया है DOM में किसी तत्व तक पहुंचने के लिए आपको पूरे jQuery की आवश्यकता नहीं है। लेकिन अगर आपने jQuery स्थापित किया है, तो कोणीय jQuery को संदर्भित करेगा। इसे देखें: docs.angularjs.org/api/angular.element
संजीव सिंह

31

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

काम करने का उदाहरण: http://plnkr.co/edit/Fj59GB

// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
    return {
        link: {
            pre: function preLink(scope, element, attr) {
                console.debug('prelink called');
                // this fails since the element hasn't rendered
                //element[0].focus();
            },
            post: function postLink(scope, element, attr) {
                console.debug('postlink called');
                // this succeeds since the element has been rendered
                element[0].focus();
            }
        }
    }
});
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />

पूर्ण कोणीयजेएस निर्देश डॉक्स: https://docs.angularjs.org/api/ng/service/$compile


2
तत्व को लपेटने के लिए था [0] .focus () $ timeout में मेरे लिए यह काम करने के लिए।
कोडिन

@bbodenmiller मेरे मॉडल में एक फीका-आउट चीज़ लगाई गई है, जब तत्व का निर्माण होता है तो यह अदृश्य (100% पारदर्शी) होता है, इसलिए ब्राउज़र ब्लॉक चुपचाप आमंत्रण पर ध्यान केंद्रित करता है। जाहिरा तौर पर कुछ मिलीसेकंड पारित लगभग पारदर्शी लेकिन दृश्यमान इनपुट / बटन पर ध्यान केंद्रित करने की अनुमति देते हैं।
बर्फीली हवा

1
डॉक्स के अनुसार, "लिंक" फ़ंक्शन डिफ़ॉल्ट रूप से "पोस्टलिंक" हैं। यह भी देखें: bennadel.com/blog/…
jody tate

17

यहाँ मेरा मूल समाधान है:

plunker

var app = angular.module('plunker', []);
app.directive('autoFocus', function($timeout) {
    return {
        link: function (scope, element, attrs) {
            attrs.$observe("autoFocus", function(newValue){
                if (newValue === "true")
                    $timeout(function(){element[0].focus()});
            });
        }
    };
});

और HTML:

<button ng-click="isVisible = !isVisible">Toggle input</button>
<input ng-show="isVisible" auto-focus="{{ isVisible }}" value="auto-focus on" />

यह क्या करता है:

यह इनपुट को केंद्रित करता है क्योंकि यह एनजी-शो के साथ दिखाई देता है। यहाँ पर $ घड़ी या $ का कोई उपयोग नहीं है।


वास्तव में मेरा मानना ​​है कि {{isV अदृश्य}} वैसे भी एक घड़ी बना रहा है, इसलिए "$ घड़ी का उपयोग नहीं" बयान गलत है।
मैसिम्पलो

हां, मुझे लगता है कि आप सही हैं। लेकिन यह अभी भी इसे करने का एक आसान तरीका है।
एडब्लर

17

मैंने हाल ही में मॉडल की तरह एक दो-तरफ़ा बाध्यकारी फ़ोकस निर्देशन लिखा है।

आप इस तरह फोकस निर्देश का उपयोग कर सकते हैं:

<input focus="someFocusVariable">

यदि आप कुछ फ़ोकस वियरेबल स्कोप वैरिएबल बनाते हैं true अपने नियंत्रक में कहीं भी कुछ , तो इनपुट केंद्रित हो जाता है। और अगर आप अपने इनपुट को "ब्लर" करना चाहते हैं, तो कुछ फेकवॉरेबल को गलत पर सेट किया जा सकता है। यह मार्क राजकॉक के पहले जवाब की तरह है लेकिन दो-तरफा बाध्यकारी है।

यहाँ निर्देश है:

function Ctrl($scope) {
  $scope.model = "ahaha"
  $scope.someFocusVariable = true; // If you want to focus initially, set this to true. Else you don't need to define this at all.
}

angular.module('experiement', [])
  .directive('focus', function($timeout, $parse) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
          scope.$watch(attrs.focus, function(newValue, oldValue) {
              if (newValue) { element[0].focus(); }
          });
          element.bind("blur", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=false"); 
              }, 0);
          });
          element.bind("focus", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=true");
              }, 0);
          })
      }
    }
  });

उपयोग:

<div ng-app="experiement">
  <div ng-controller="Ctrl">
    An Input: <input ng-model="model" focus="someFocusVariable">
    <hr>
        <div ng-click="someFocusVariable=true">Focus!</div>  
        <pre>someFocusVariable: {{ someFocusVariable }}</pre>
        <pre>content: {{ model }}</pre>
  </div>
</div>

यहाँ बेला है:

http://fiddle.jshell.net/ubenzer/9FSL4/8/


यह सही उत्तर होना चाहिए। इसमें सभी उपयोग के मामले शामिल हैं।
कुणाल

11

जो लोग बूटस्ट्रैप प्लगइन के साथ कोणीय का उपयोग करते हैं:

http://angular-ui.github.io/bootstrap/#/modal

आप openedमोडल उदाहरण के वादे में हुक कर सकते हैं :

modalInstance.opened.then(function() {
        $timeout(function() {
            angular.element('#title_input').trigger('focus');
        });
    });

modalInstance.result.then(function ( etc...

अच्छा! हालांकि मेरे मामले में, $timeoutके 50msबजाय की जरूरत है 0
lk_vc

8

मुझे सामान्य अभिव्यक्ति का उपयोग करना उपयोगी लगा। इस तरह से आप इनपुट टेक्स्ट के मान्य होने पर स्वचालित रूप से फ़ोकस जैसे सामान ले जा सकते हैं

<button type="button" moo-focus-expression="form.phone.$valid">

या जब उपयोगकर्ता एक निश्चित लंबाई के क्षेत्र को पूरा करता है तो स्वचालित रूप से ध्यान केंद्रित करता है

<button type="submit" moo-focus-expression="smsconfirm.length == 6">

और निश्चित रूप से लोड के बाद ध्यान केंद्रित

<input type="text" moo-focus-expression="true">

निर्देश के लिए कोड:

.directive('mooFocusExpression', function ($timeout) {
    return {
        restrict: 'A',
        link: {
            post: function postLink(scope, element, attrs) {
                scope.$watch(attrs.mooFocusExpression, function (value) {

                    if (attrs.mooFocusExpression) {
                        if (scope.$eval(attrs.mooFocusExpression)) {
                            $timeout(function () {
                                element[0].focus();
                            }, 100); //need some delay to work with ng-disabled
                        }
                    }
                });
            }
        }
    };
});

7

एक ज़ोंबी को पुनर्जीवित करने या अपने स्वयं के निर्देश को प्लग करने के लिए नहीं (ठीक है कि मैं क्या कर रहा हूं):

https://github.com/hiebj/ng-focus-if

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

<input focus-if />

(function() {
    'use strict';
    angular
        .module('focus-if', [])
        .directive('focusIf', focusIf);

    function focusIf($timeout) {
        function link($scope, $element, $attrs) {
            var dom = $element[0];
            if ($attrs.focusIf) {
                $scope.$watch($attrs.focusIf, focus);
            } else {
                focus(true);
            }
            function focus(condition) {
                if (condition) {
                    $timeout(function() {
                        dom.focus();
                    }, $scope.$eval($attrs.focusDelay) || 0);
                }
            }
        }
        return {
            restrict: 'A',
            link: link
        };
    }
})();

मैं अब इस निर्देश का उपयोग कर रहा हूं और यह बहुत अच्छा काम करता है, सामान्य समस्या को हल करता है, और अत्यधिक जटिल नहीं है। $ समय-मुक्त समाधान की तलाश में जुट गए। यह कहते हुए टिप्पणियों को ध्यान में रखें कि कोणीय 1.1 और 1.2 के लिए "रोडमैप पर ध्यान केंद्रित है", लेकिन मैं 2.x का उपयोग कर रहा हूं और अभी भी कोई फोकस प्रबंधन नहीं है। हे।
टेकहेड

6

सबसे पहले, फोकस करने का एक आधिकारिक तरीका 1.1 के लिए रोडमैप पर है । इस बीच, आप सेटिंग फ़ोकस को लागू करने के लिए एक निर्देश लिख सकते हैं।

दूसरा, एक आइटम पर ध्यान केंद्रित करने के लिए सेट होने के बाद जो वर्तमान में दिखाई देता है उसे वर्कअराउंड की आवश्यकता होती है। बस अपने कॉल को एलिमेंट फ़ोकस करने में देरी करें () a के साथ $timeout

क्योंकि फोकस, ब्लर और सेलेक्ट के लिए एक ही कंट्रोलर-मॉडिफ़ाइड-डोम समस्या मौजूद है, मैं एक ng-targetनिर्देश होने का प्रस्ताव देता हूं :

<input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget">
<button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>

कोणीय धागा यहाँ: http://goo.gl/ipsx4 , और अधिक विवरण यहाँ ब्लॉग: http://goo.gl/4rdZa

निम्न निर्देश .focus()आपकी ng-targetविशेषता के अनुसार आपके नियंत्रक के अंदर एक फ़ंक्शन बनाएगा । (यह एक .blur()और .select()भी बनाता है।) डेमो: http://jsfiddle.net/bseib/WUcQX/


रोडमैप संदर्भ के लिए +1। वास्तव में मैंने इसे अभी भी 1.2 के प्रलेखन में देखा था जिसे अभी भी अस्थिर माना जाता है ( docs.angularjs.org/api/ng.directive:ngFocus )
एडविन दलेरजो

27
@EdwinDalorzo ngFocusको संभालने के लिए एक तरह से प्रतीत होता है focusके लिए एक रास्ता घटनाओं, नहीं सेट एक तत्व पर ध्यान केंद्रित।
टेलीकमाइबर

6

अपना स्वयं का निर्देश बनाने के बजाय, फ़ोकस को पूरा करने के लिए बस जावास्क्रिप्ट कार्यों का उपयोग करना संभव है।

यहाँ एक उदाहरण है।

HTML फ़ाइल में:

<input type="text" id="myInputId" />

एक फाइल जावास्क्रिप्ट में, उदाहरण के लिए एक नियंत्रक में, जहां आप फोकस सक्रिय करना चाहते हैं:

document.getElementById("myInputId").focus();

9
यह एक 'कोणीय तरीका' नहीं है और लोगों को अपने नियंत्रकों में DOM को छूने की सलाह नहीं देते हैं।
smajl

कोणीय में वेनिला का उपयोग नहीं करने के लिए सबसे अच्छा है, क्योंकि कोणीय इसे ट्रैक नहीं कर सकता है और न ही इसे बाकी सब के साथ सिंक में रख सकता है।
एडगर क्विंटो

4

यदि आप बस एक साधारण फोकस चाहते थे जो एनजी-क्लिक द्वारा नियंत्रित किया गया था।

एचटीएमएल:

<input ut-focus="focusTigger">

<button ng-click="focusTrigger=!focusTrigger" ng-init="focusTrigger=false"></button>

निर्देशक:

'use strict'

angular.module('focus',['ng'])
.directive('utFocus',function($timeout){
    return {
        link:function(scope,elem,attr){
            var focusTarget = attr['utFocus'];
            scope.$watch(focusTarget,function(value){
                $timeout(function(){
                    elem[0].focus();
                });
            });
        }
    }
});

4

एक सरल तरीका जो अच्छी तरह से काम करता है:

.directive('focusMeNow', ['$timeout', function ($timeout)
{
    return {
        restrict: 'A',

        link: function (scope, element, attrs)
        {


            $timeout(function ()
            {
                element[0].focus();
            });



        }
    };
}])

उदाहरण

<input ng-model="your.value" focus-me-now />

मेरे लिए सही है। धन्यवाद
अलेक्जेंडर

3

आप सिर्फ एक निर्देश बना सकते हैं कि बलों को पोस्टलिंकिंग पर सजाए गए तत्व पर केंद्रित करें:

angular.module('directives')
.directive('autoFocus', function() {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            _element[0].focus();
        }
    };
});

फिर अपने HTML में:

<input type="text" name="first" auto-focus/> <!-- this will get the focus -->
<input type="text" name="second"/>

यह मॉडल्स और एनजी-इफ-टोल्ड तत्वों के लिए काम करेगा, एनजी-शो के लिए नहीं क्योंकि पोस्टलिंकिंग केवल HTML प्रसंस्करण पर होता है।


3

मार्क और बॉल्स के पास शानदार जवाब हैं; हालाँकि, मार्क का एक दोष है कि Blesh इंगित करता है (लागू करने के लिए जटिल होने के अलावा), और मुझे लगता है कि Blesh के उत्तर में एक सेवा बनाने में त्रुटि है, जो विशेष रूप से फ़्रंट को फ़ोकस रिक्वेस्ट भेजने के बारे में है, जब वास्तव में उसकी ज़रूरत थी। सभी निर्देशों को सुन रहे थे जब तक घटना में देरी।

तो यहाँ मैंने वही किया है जो बलेश के जवाब से बहुत कुछ चुराता है, लेकिन नियंत्रक घटना और "लोड के बाद" सेवा के शब्दार्थ को अलग रखता है।

यह नियंत्रक घटना को केवल एक विशिष्ट तत्व पर ध्यान केंद्रित करने के अलावा अन्य चीजों के लिए आसानी से झुका सकता है और "ओवर लोड" कार्यक्षमता के ओवरहेड को उकसाने की अनुमति देता है केवल अगर यह आवश्यक है, जो कि कई मामलों में नहीं हो सकता है।

प्रयोग

<input type="text" focus-on="controllerEvent"/>
app.controller('MyCtrl', function($scope, afterLoad) {
  function notifyControllerEvent() {
      $scope.$broadcast('controllerEvent');
  }

  afterLoad(notifyControllerEvent);
});

स्रोत

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e, name) {
        elem[0].focus();
      });
   };
});

app.factory('afterLoad', function ($rootScope, $timeout) {
  return function(func) {
    $timeout(func);
  }
});

एक और केवल उत्तर, जिसे मैं (एक पूर्ण शुरुआत) समझ सकता था। "AfterLoad (InformControllerEvent);" के बजाय, मैं "InformControllerEvent ()" का उपयोग करता था। अन्यथा, यह कुछ त्रुटियों के साथ समाप्त हो गया।
वेल मुरुगन एस

3

यह भी उपयोग करना संभव है ngModelController। 1.6+ (पुराने संस्करणों के साथ पता नहीं) के साथ काम करना।

एचटीएमएल

<form name="myForm">
    <input type="text" name="myText" ng-model="myText">
</form>

जे एस

$scope.myForm.myText.$$element.focus();

-

एनबी: संदर्भ के आधार पर, आपको शायद टाइमआउट फ़ंक्शन में लपेटना होगा।

NB: उपयोग करते समय controllerAs, यह लगभग समान है। बस के name="myForm"साथ name="vm.myForm"और जेएस में बदलें vm.myForm.myText.$$element.focus();


3

शायद, ईएस 6 उम्र पर सबसे सरल समाधान।

निम्नलिखित एक लाइनर निर्देशन को जोड़ने से HTML 'ऑटोफोकस' विशेषता Angular.js पर प्रभावी हो जाती है।

.directive('autofocus', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())}))

अब, आप HTML5 ऑटोफोकस सिंटैक्स का उपयोग कर सकते हैं जैसे:

<input type="text" autofocus>

@ स्टेफ़ेन हाँ, तो फिर यह बन जाता है.directive('autofocus', ['$timeout', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())})])
माइकल प्लात्ज़

2

बस यहाँ एक नौसिखिया है, लेकिन मैं इस निर्देश के साथ एक ui.bootstrap.modal में काम करने के लिए चिंतित था :

directives.directive('focus', function($timeout) {
    return {
        link : function(scope, element) {
            scope.$watch('idToFocus', function(value) {
                if (value === element[0].id) {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});

और $ modal.open विधि में मैंने फ़ॉउलिंग का उपयोग उस तत्व को इंगित करने के लिए किया है जहाँ फ़ोकस डाला जाना चाहिए:

var d = $modal.open({
        controller : function($scope, $modalInstance) {
            ...
            $scope.idToFocus = "cancelaAteste";
    }
        ...
    });

टेम्पलेट पर मेरे पास यह है:

<input id="myInputId" focus />

2

निम्नलिखित निर्देश ने मेरे लिए चाल चली। इनपुट के लिए एक ही ऑटोफोकस html विशेषता का उपयोग करें।

.directive('autofocus', [function () {
    return {
        require : 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.focus();
        }
    };
}])

1
जब तक jQuery शामिल नहीं किया जाता है, तब आपको इसे चलाने में एक त्रुटि मिलेगी, यह तत्व [0] .focus ()
रयान एम

2

यदि आप modalInstance का उपयोग कर रहे हैं और आपके पास ऑब्जेक्ट है तो आप "ओपन" का उपयोग कर सकते हैं। यदि आप modalInstance का उपयोग नहीं कर रहे हैं, और आप जिस मोड का उपयोग कर सकते हैं, उसे खोलने के लिए हार्ड कोडित है। $ टाइमआउट एक अच्छा समाधान नहीं है।

आप (Bootstrap3) कर सकते हैं:

$("#" + modalId).on("shown.bs.modal", function() {
    angular.element("[name='name']").focus();
});

ModalInstance में आप लाइब्रेरी को देख सकते हैं कि ओपन मोडल के बाद कोड को कैसे निष्पादित करें।

इस तरह $ टाइमआउट का उपयोग न करें, $ टाइमआउट 0, 1, 10, 30, 50, 200 या अधिक हो सकता है यह क्लाइंट कंप्यूटर पर निर्भर करेगा, और मोडल खोलने की प्रक्रिया।

$ टाइमआउट का उपयोग न करें जब आप ध्यान केंद्रित कर सकते हैं तो विधि आपको बताएगी;)

मुझे आशा है कि यह मदद! :)


2

यदि वांछित फ़ोकस तत्व को निर्देश टेम्पलेट में इंजेक्ट किया जाता है, तो पिछले उत्तर के सभी काम नहीं करते हैं। निम्नलिखित निर्देश सरल तत्व या निर्देशक इंजेक्शन तत्व दोनों के लिए उपयुक्त है (मैंने इसे टाइपस्क्रिप्ट में लिखा था )। यह आंतरिक ध्यान देने योग्य तत्व के लिए चयनकर्ता को स्वीकार करता है। अगर आपको केवल आत्म तत्व पर ध्यान केंद्रित करने की आवश्यकता है - किसी भी चयनकर्ता पैरामीटर को निर्देश पर न भेजें:

module APP.Directives {

export class FocusOnLoadDirective implements ng.IDirective {
    priority = 0;
    restrict = 'A';

    constructor(private $interval:any, private $timeout:any) {

    }

    link = (scope:ng.IScope, element:JQuery, attrs:any) => {
        var _self = this;
        var intervalId:number = 0;


        var clearInterval = function () {
            if (intervalId != 0) {
                _self.$interval.cancel(intervalId);
                intervalId = 0;
            }
        };

        _self.$timeout(function(){

                intervalId = _self.$interval(function () {
                    let focusableElement = null;
                    if (attrs.focusOnLoad != '') {
                        focusableElement = element.find(attrs.focusOnLoad);
                    }
                    else {
                        focusableElement = element;
                    }
                    console.debug('focusOnLoad directive: trying to focus');
                    focusableElement.focus();
                    if (document.activeElement === focusableElement[0]) {
                        clearInterval();
                    }
                }, 100);

                scope.$on('$destroy', function () {
                    // Make sure that the interval is destroyed too
                    clearInterval();
                });

        });
    };

    public static factory = ():ng.IDirectiveFactory => {
        let directive = ($interval:any, $timeout:any) => new FocusOnLoadDirective($interval, $timeout);
        directive.$inject = ['$interval', '$timeout'];
        return directive;
    };
}

angular.module('common').directive('focusOnLoad', FocusOnLoadDirective.factory());

}

सरल तत्व के लिए उपयोग उदाहरण:

<button tabindex="0" focus-on-load />

आंतरिक तत्व के लिए उपयोग उदाहरण (आमतौर पर डायनामिक इंजेक्शन जैसे तत्व टेम्पलेट के साथ निर्देश के लिए):

<my-directive focus-on-load="input" />

आप "इनपुट" के बजाय किसी भी jQuery चयनकर्ता का उपयोग कर सकते हैं


2

मैं एक तत्व में कई फोकस के लिए काम करने के लिए मार्क रजोक का ध्यान केंद्रित करने के निर्देश को संपादित करता हूं।

HTML:

<input  focus-me="myInputFocus"  type="text">

AngularJs नियंत्रक में:

$scope.myInputFocus= true;

अंगुलाज निर्देश:

app.directive('focusMe', function ($timeout, $parse) {
    return {
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                if (value === true) {
                    $timeout(function () {
                        scope.$apply(model.assign(scope, false));
                        element[0].focus();
                    }, 30);
                }
            });
        }
    };
});

1

मैं इस चर्चा में योगदान देना चाहता हूं ताकि बेहतर समाधान खोजा जा सके और इसे न पाकर इसके बजाय इसे बनाया।

मानदंड: 1. समाधान पुनः प्रयोज्य बढ़ाने के लिए मूल नियंत्रक नियंत्रक से स्वतंत्र होना चाहिए। 2. कुछ स्थिति की निगरानी के लिए $ घड़ी के उपयोग से बचें, यह दोनों धीमी है, डाइजेस्ट लूप के आकार को बढ़ाता है और कठिन परीक्षण करता है। 3. डाइजेस्ट लूप को ट्रिगर करने के लिए $ टाइमआउट या $ स्कोप से बचें। $ लागू करें ()। 4. एक इनपुट तत्व उस तत्व के भीतर मौजूद होता है, जहां डायरेक्टिव का उपयोग किया जाता है।

यही वह उपाय है जो मुझे सबसे ज्यादा पसंद है:

निर्देशक:

.directive('focusInput', [ function () {
    return {
        scope: {},
        restrict: 'A',
        compile: function(elem, attr) {
            elem.bind('click', function() {
                elem.find('input').focus();                
            });
        }        
    };
}]);

एचटीएमएल:

 <div focus-input>
     <input/>
 </div>

मुझे आशा है कि यह किसी को वहाँ से बाहर निकालने में मदद करेगा!


आपने बस html "लेबल" को फिर से बनाया है, आप बस "div focus-input" को "लेबल" से बदल सकते हैं और निर्देश से छुटकारा पा सकते हैं।
frst

1

यह आसान है .. यह कोशिश करो

एचटीएमएल

<select id="ddl00">  
 <option>"test 01"</option>  
</select>

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

document.getElementById("ddl00").focus();

संदर्भ से बाहर सही है, लेकिन चीजों को करने का AngularJS तरीका नहीं है
CodeMonkey

1

यदि आप विशेष तत्व पर ध्यान केंद्रित करना चाहते हैं, तो आप नीचे दिए गए दृष्टिकोण का उपयोग कर सकते हैं।

  1. एक सेवा बुलाया बनाएं focus

    angular.module('application')
    .factory('focus', function ($timeout, $window) {
        return function (id) {
            $timeout(function () {
                var element = $window.document.getElementById(id);
                if (element)
                    element.focus();
            });
        };
    });
  2. इसे कंट्रोलर में इंजेक्ट करें जहाँ से आप कॉल करना चाहते हैं।

  3. इस सेवा को कॉल करें।


0

मुझे लगता है कि निर्देश अनावश्यक है। आवश्यक तत्व का चयन करने के लिए HTML आईडी और वर्ग विशेषताओं का उपयोग करें और फोकस (या jQuery समकक्ष) लागू करने के लिए सेवा का उपयोग document.getElementById या document.querySelector करें।

मार्कअप मानक HTML / कोणीय निर्देश है जिसमें चयन के लिए अतिरिक्त आईडी / कक्षाएं हैं

<input id="myInput" type="text" ng-model="myInputModel" />

नियंत्रक प्रसारण घटना

$scope.$emit('ui:focus', '#myInput');

यूआई सेवा में क्वेरीसेलेक्टर का उपयोग किया जाता है - यदि कई मैच हैं (वर्ग के कारण कहते हैं) तो यह केवल पहले वापसी करेगा

$rootScope.$on('ui:focus', function($event, selector){
  var elem = document.querySelector(selector);
  if (elem) {
    elem.focus();
  }
});

आप एक पाचन चक्र को मजबूर करने के लिए $ टाइमआउट () का उपयोग करना चाह सकते हैं


0

बस कुछ कॉफ़ी में फेंक दिया।

app.directive 'ngAltFocus', ->
    restrict: 'A'
    scope: ngAltFocus: '='
    link: (scope, el, attrs) ->
        scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.