Input autofocus attribute

后端 未结 10 1519
Happy的楠姐
Happy的楠姐 2020-11-30 04:47

I have places in my code where I have this:


I would like to be able to use it like

相关标签:
10条回答
  • 2020-11-30 05:12

    Update: AngularJS now has an ngFocus directive that evaluates an expression on focus, but I mention it here for the sake of completeness.


    The current version of AngularJS doesn't have a focus directive, but it's in the roadmap. Coincidentally, we were talking about this on the mailing list yesterday, and I came up with this:

    angular.module('ng').directive('ngFocus', function($timeout) {
        return {
            link: function ( scope, element, attrs ) {
                scope.$watch( attrs.ngFocus, function ( val ) {
                    if ( angular.isDefined( val ) && val ) {
                        $timeout( function () { element[0].focus(); } );
                    }
                }, true);
    
                element.bind('blur', function () {
                    if ( angular.isDefined( attrs.ngFocusLost ) ) {
                        scope.$apply( attrs.ngFocusLost );
    
                    }
                });
            }
        };
    });
    

    Which works off a scope variable as you requested:

    <input type="text" ng-focus="isFocused" ng-focus-lost="loseFocus()">
    

    Here's a fiddle: http://jsfiddle.net/ANfJZ/39/

    0 讨论(0)
  • 2020-11-30 05:13
    <!DOCTYPE html>
    <html>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    <body>
    
    <div ng-app="myApp" ng-controller="namesCtrl"> 
      <div ng-repeat="x in names">
         <input ng-attr-focus={{$first}} value="{{x.name + ', ' + x.country }}" />
      </div>
    </div>
    
    <script>
    
            var myApp = angular.module('myApp', []);
            myApp.controller('namesCtrl', function($scope) {
        $scope.names = [
            {name:'x1',country:'y1'},
            {name:'x2',country:'y2'},
            {name:'x3',country:'y3'}
        ];
    });
    
            myApp.directive("focus", function(){
                return {
                    restrict: "A",
                    link: function link(scope, element, attrs) {
    
                          if(JSON.parse(attrs.focus)){
                              element[0].focus();
                          }
                    }
                };
            });
    </script>
    </body>
    </html>
    

    had created above custom directive for one of my use case.

    • always focusses on first input element.
    • works for ajax data, browser back/forward buttons.
    • Tested on chrome and firefox(default autofocus is not supported here)

    JSON.parse is used to parse string "true" returned from html to boolean true in JS.
    another way to use attrs.focus === "true" for if condition.

    0 讨论(0)
  • 2020-11-30 05:20

    Create a directive like this

    .directive('autoFocus', ['$timeout', function ($timeout) {
            return {
                restrict: 'A',
                link: function ($scope, $element) {
                    $timeout(function () {
                        $element[0].focus();
                    });
                }
            }
    
    
    
    <input type="text" auto-focus class="form-control msd-elastic" placeholder="">
    
    0 讨论(0)
  • 2020-11-30 05:21

    I did it with two custom directives, something like this:

    (function(angular) {
      'use strict';
    
      /* @ngInject */
      function myAutoFocus($timeout) {
        return {
          restrict: 'A',
          link: function(scope, element) {
            $timeout(function() {
              element[0].focus();
            }, 300);
          }
        };
      }
    
      function myFocusable() {
        return {
          restrict: 'A',
          link: function(scope, element, attrs) {
            var focusMethodName = attrs.myFocusable;
            scope[focusMethodName] = function() {
              element[0].focus();
            };
          }
        };
      }
    
      angular
        .module('myFocusUtils', [])
        .directive('myAutoFocus', myAutoFocus)
        .directive('myFocusable', myFocusable);
    
    }(angular));
    

    If you add attribute my-auto-focus to an element, it will receive focus after 300ms. I set the value to 300 instead of 0 to let other async components to load before setting the focus.

    The attribute my-focusable will create a function in the current scope. This function will set focus to the element when called. As it creates something in the scope, be cautious to avoid overriding something.

    This way you don't need to add something to Angular's digest cycle (watch) and can do it entirely in the view:

    <input my-focusable="focusOnInput"></input>        
    <button ng-click="focusOnInput()">Click to focus</button>
    

    I created a JSFiddle to show the myFocusable directive: http://jsfiddle.net/8shLj3jc/

    For some reason I don't know, the myAutoFocus directive does not work in JSFiddle, but it works in my page.

    0 讨论(0)
  • 2020-11-30 05:22
    scope.doFocus = function () {
                    $timeout(function () {
                            document.getElementById('you_input_id').focus();
                        });
                };
    
    0 讨论(0)
  • 2020-11-30 05:25

    You can do this with the built-in ngAttr attribute bindings.

    <input ng-attr-autofocus="{{SOME_SCOPE_VARIABLE}}">
    

    The autofocus attribute will be added if SOME_SCOPE_VARIABLE is defined (even if it's false), and will be removed if it's undefined. So I force falsy values to be undefined.

    $scope.SOME_SCOPE_VARIABLE = someVar || undefined;
    
    0 讨论(0)
提交回复
热议问题