How to set the focus on the input field?

This article was translated from: How to set focus on input field?

What is the 'Angular way' to set focus on input field in AngularJS? What is the "angle way" to set focus on the input field in AngularJS ?

More specific requirements: More specific requirements:

  1. When a Modal is opened, set focus on a predefined <input>inside this Modal. After opening a modality , focus on the predefined within this modality <input>.
  2. Everytime <input>becomes visible (eg by clicking some button), set focus on it. Whenever it becomes visible (for example, by clicking some buttons), set the 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). I tried to autofocus achieve the first requirement by , but this Only works when Modal is opened for the first time, and only works in some browsers (for example, does not work in Firefox).

Any help will be appreciated. Any help will be appreciated .


#1st Floor

Reference: https://stackoom.com/question/10EpC/ How to set the focus on input fields


#2nd Floor

  1. When a Modal is opened, set focus on a predefined <input> inside this Modal. After opening a modality, focus on the predefined <input> within this modality.

Define a directive and have it $ watch a property / trigger so it knows when to focus the element: define a directive and make it $ watch a property / trigger so that it knows when to focus the element :

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 plunger

The $ timeout seems to be needed to give the modal time to render. $ Timeout seems to require the given modal time to render.

'2.' '2. Everytime <input> becomes visible (eg by clicking some button), set focus on it. Whenever <input> becomes visible (for example, by clicking some button), set the focus on it .

Create a directive essentially like the one above. Create a directive that is basically similar to the one above . Some scope Property Watch, and IT Becomes When true (IT SET in your ng-click Handler), Execute element[0].focus(). Observe some scope attribute, when it becomes true (set in the ng-click handler) is executed element[0].focus(). Depending on your use case, you may or may not need a $ timeout for this one: Depending on your use case, you may or may not need $ 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 plunger


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). Update 7/2013 : I have seen some people use me The original isolation range instruction then encountered problems with the embedded input field (ie the input field in the modal). A directive with no new scope (or possibly a new child scope) should alleviate some of the pain. An instruction without a new scope (or possibly a new child scope) should alleviate some pain. So above I updated the answer to not use isolate scopes. So, above, I updated the answer to not use isolate scopes . Below is the original answer: The following is the original answer:

Original answer for 1., using an isolate scope: 1. Original answer for using an isolate scope :

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 . Plunger .

Original answer for 2., using an isolate scope: 2. Original answer for using an isolate scope :

<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 . Plunger .

Since we need to reset the trigger / focusInput property in the directive, '=' is used for two-way databinding. Since we need to reset the trigger / focusInput property in the directive, "=" is used for two-way data binding. In the first directive, '@' was sufficient. In the first directive, "@" is sufficient. Also note that when using '@' we compare the trigger value to "true" since @ always results in a string. Also note that when using "@", we compare the trigger value with "true" because @always Will produce a string.


#3rd floor

First, AN Official Way to do IS ON Focus at The Roadmap for 1.1 . First of all, the official focus method is 1.1 of the roadmap . Meanwhile, you can write a directive to implement setting focus. At the same time, you can write a directive to achieve setting focus.

Second, to set focus on an item after it has become visible currently requires a workaround. Second, to set focus on the currently visible item, a solution is needed. Just delay your call to element focus () with a $timeout. Just use $timeoutdelay to call the element focus ().

Because the same controller-modifies-DOM problem exists for focus, blur and select, I propose having an ng-targetdirective: Because there is the same controller-modified-DOM problem in focus, blur and select, I suggest using the ng-targetdirective:

<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>

The Thread here Wallpaper Angular: http://goo.gl/ipsx4 , the Details blogged here Wallpaper and More: http://goo.gl/4rdZa here thread angle: HTTP : //goo.gl/ipsx4 , more details in Published here : http://goo.gl/4rdZa

Will Create A following Directive of The .focus()function AS Controller Inside your specified by your ng-targetattribute. The following instructions will ng-targetcreate an internal controller properties specified .focus()functions. (It Creates A .blur()and A .select(). TOO) Demo: http://jsfiddle.net/bseib/WUcQX/ (it .blur()creates a .blur()and a .select().) Demo: HTTP : //jsfiddle.net/bseib/WUcQX/


#4th floor

I've written a two-way binding focus directive, just like model recently. I wrote a two-way binding focus directive, just like the most recent model.

You can use the focus directive like this: You can use the focus directive like this :

<input focus="someFocusVariable">

If you make someFocusVariable scope variable truein anywhere in your controller, the input get focused. If you make someFocusVariable scope variable in any position in the controller true, the input will become the focus. And if you want to "blur" your input then, someFocusVariable can be set to false. And, if you want to "blur" the input, you can set someFocusVariable to false. It's like Mark Rajcok's first answer but with two-way binding. This is like Mark Rajcok's first answer, but with two-way binding .

Here is the directive: This is the directive:

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);
          })
      }
    }
  });

Usage: Usage:

<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>

Here is the fiddle: This is the fiddle:

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


#5th Floor

(EDIT: I've added an updated solution below this explanation) (EDIT: I added an updated solution below this explanation )

Mark Rajcok is the man ... and his answer is a valid answer, but it has had a defect (sorry Mark) ... Mark Rajcok is this person ... his answer is valid the answer, but there are flaws (sorry Mark) ...

... Try using the boolean to focus on the input, then blur the input, then try using it to focus the input again. ... Try using Boolean to focus on the input, then blur the input, then try to use it Focus the input again. It won't work unless you reset the boolean to false, then $ digest, then reset it back to true. It will not work unless you reset the boolean to false and then reset $ digest to true. Even if you use a string comparison in your expression, you'll be forced to change the string to something else, $ digest, then change it back. Even if you use string comparison in the expression, you will have to change the string To $ digest, and then change it. (This has been addressed with the blur event handler.) (This has been addressed with the blur event handler .)

So I propose this alternate solution: Therefore, I propose this alternative solution :

Use an event, the forgotten feature of Angular. Use an event, the forgotten feature of Angular .

JavaScript loves events after all. JavaScript loves events after all . Events are inherently loosely coupled, and even better, you avoid adding another $ watch to your $ digest. Events are inherently loosely coupled, and even better, you avoid adding another $ watch in $ digest.

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

So now you could use it like this: So now you can use it like this :

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

and then anywhere in your app ... and then anywhere in your app ...

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

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

This is awesome because you can do all sorts of things with something like this. This is great because you can do all kinds of things with such things. For one, you could tie into events that already exist. First, you can tie into events that already exist . For another thing you start doing something smart by having different parts of your app publish events that other parts of your app can subscribe to. On the other hand, you can let other parts of the app publish events so that other parts of the app can Subscribe to start doing smart things.

Anyhow, this type of thing screams "event driven" to me. Anyway, this kind of thing is "event driven" scream for me. I think as Angular developers we try really hard to hammer $ scope shaped pegs into event shape holes. I think, as Angular developers, we work very hard to hammer $ scope-shaped nails into event-shaped holes.

Is it the best solution? Is it the best solution ? I dunno. I don't know. It's a solution. This is a solution.


Updated Solution update solution

After @ ShimonRachlenko's comment below, I've changed my method of doing this slightly. After @ShimonRachlenko commented below, I have slightly changed the method of doing this . Now I use a combination of a service and a directive that handles an event "behind the scenes": Now, I use a combination of a service and a directive to handle "behind the scenes":

Other than that, it's the same principal outlined above. Other than that, it's the same principal outlined above .

Here is a quick demo Plunk

Usage Usage

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

Source resources

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);
    });
  }
});

#6th floor

You can also use angular's built-in jqlite function.

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

Published 0 original articles · praised 75 · 560,000 views +

Guess you like

Origin blog.csdn.net/w36680130/article/details/105447386