Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

What is the 'Angular way' to set focus on input field in AngularJS? (在AngularJS中将焦点设置在输入字段上的“角度方式”是什么?)

More specific requirements: (更具体的要求:)

  1. When a Modal is opened, set focus on a predefined <input> inside this Modal. (打开模态后 ,将焦点放在此模态内的预定义<input> 。)
  2. Everytime <input> becomes visible (eg by clicking some button), set focus on it. (每当<input>变为可见时(例如,通过单击某些按钮),请将焦点设置在它上面。)

I tried to achieve the first requirement with autofocus , but this works only when the Modal is opened for the first time, and only in certain browsers (eg in Firefox it doesn't work). (我试图通过autofocus 达到第一个要求 ,但这仅在首次打开Modal时有效,并且仅在某些浏览器中有效(例如,在Firefox中不起作用)。)

Any help will be appreciated. (任何帮助将不胜感激。)

  ask by Misha Moroshko translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
555 views
Welcome To Ask or Share your Answers For Others

1 Answer

  1. When a Modal is opened, set focus on a predefined <input> inside this Modal. (打开模态后,将焦点放在此模态内的预定义<input>上。)

Define a directive and have it $watch a property/trigger so it knows when to focus the element: (定义一个指令,并使其$ watch一个属性/触发器,以便它知道何时集中该元素:)

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 (柱塞)

The $timeout seems to be needed to give the modal time to render. ($ timeout似乎需要给定模态时间来渲染。)

'2.' ('2。) Everytime <input> becomes visible (eg by clicking some button), set focus on it. (每当<input>变为可见时(例如,通过单击某些按钮),请将焦点设置在它上面。)

Create a directive essentially like the one above. (创建一个基本上与上述指令相似的指令。) Watch some scope property, and when it becomes true (set it in your ng-click handler), execute element[0].focus() . (观察一些scope属性,当它变为true时(在ng-click处理程序中进行设置),执行element[0].focus() 。) Depending on your use case, you may or may not need a $timeout for this one: (根据您的用例,您可能需要也可能不需要$ timeout:)

<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 (柱塞)


Update 7/2013 : I've seen a few people use my original isolate scope directives and then have problems with embedded input fields (ie, an input field in the modal). (更新7/2013 :我已经看到一些人使用我原来的隔离范围指令,然后在嵌入的输入字段(即模态中的输入字段)方面遇到问题。) A directive with no new scope (or possibly a new child scope) should alleviate some of the pain. (没有新作用域(或可能新的子作用域)的指令应减轻某些痛苦。) So above I updated the answer to not use isolate scopes. (因此,以上我更新了不使用隔离范围的答案。) Below is the original answer: (以下是原始答案:)

Original answer for 1., using an isolate scope: (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(); 
          });
        }
      });
    }
  };
});

Plunker . (柱塞 。)

Original answer for 2., using an isolate scope: (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;
          //});
        }
      });
    }
  };
});

Plunker . (柱塞 。)

Since we need to reset the trigger/focusInput property in the directive, '=' is used for two-way databinding. (由于我们需要在指令中重置trigger / focusInput属性,因此“ =”用于双向数据绑定。) In the first directive, '@' was sufficient. (在第一个指令中,“ @”就足够了。) Also note that when using '@' we compare the trigger value to "true" since @ always results in a string. (还要注意,当使用“ @”时,我们将触发值与“ true”进行比较,因为@始终会产生字符串。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...