Comment mettre l'accent sur le champ d'entrée?

Quelle est la 'manière angulaire' de mettre l'accent sur le champ d'entrée dans AngularJS?

exigences plus spécifiques:

  1. Lorsqu'un Modal est ouvert, mettre l'accent sur un prédéfini <input> à l'intérieur de ce Modal.
  2. Everytime <input> devient visible (par exemple en cliquant sur un bouton), Mettre l'accent sur elle.

exigence avec autofocus , mais cela ne fonctionne que lorsque le Modal est ouvert pour la première fois, et seulement dans certains navigateurs (par exemple dans Firefox, il ne fonctionne pas).

Toute aide sera appréciée.

718
demandé sur Blackhole 2013-02-12 17:08:52

30 réponses

  1. Lorsqu'un Modal est ouvert, mettez l'accent sur un prédéfini à l'intérieur de ce Modal.

définir une directive et la faire regarder $une propriété / trigger afin qu'elle sache quand focaliser l'élément:

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

L' $timeout semble être nécessaire pour donner à l'modal temps de calcul.

" 2.'Chaque fois que devient visible (par exemple en cliquant sur un bouton), mettez le focus dessus.

Créer une directive essentiellement comme ci-dessus. Observez une propriété scope, et quand elle devient true (définissez-la dans votre gestionnaire de clics ng), exécutez element[0].focus() . Selon votre cas d'utilisation, vous pouvez ou non avoir besoin d'un $ timeout pour celui-ci:

<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


mise à jour 7/2013 : j'ai vu quelques personnes utiliser mes directives originales isolate scope et ensuite avoir des problèmes avec les champs d'entrée intégrés (i.e., un champ d'entrée dans le modal). Une directive en l'absence de nouveau portée (ou éventuellement d'un nouvel enfant) devrait atténuer la douleur. Dessus j'ai mis à jour la réponse à ne pas utiliser d'isoler étendues. Ci-dessous la réponse originale:

réponse Originale à cette question pour 1., en utilisant une portée d'isolat:

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 .

réponse originale pour 2., en utilisant une portée d'isolat:

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

puisque nous avons besoin de réinitialiser la propriété trigger/focusInput la directive " = " est utilisée pour la saisie de données bidirectionnelle. Dans la première directive, '@' était suffisant. Notez également que lors de l'utilisation de '@', nous comparons la valeur de déclenchement de "vrai" depuis @ entraîne toujours une chaîne de caractères.

555
répondu Mark Rajcok 2016-08-01 09:29:05

(EDIT: j'ai ajouté une mise à jour de la solution en dessous de cette explication)

Mark Rajcok est l'homme... et sa réponse est une réponse valable, mais elle a avait un défaut (désolé point)...

...Essayez d'utiliser le booléen à se concentrer sur l'entrée, un effet de flou à l'entrée, puis essayez de l'utiliser pour concentrer l'entrée. Il ne fonctionnera pas à moins que vous réinitialisiez le booléen à false, puis $digest, puis réinitialiser à true. Même si vous utilisez un comparaison de chaîne de caractères dans votre expression, vous serez forcé de changer la chaîne de caractères en quelque chose d'autre, $digest, puis de la changer à nouveau. (ceci a été traité avec le gestionnaire d'événements flou.)

donc je propose cette solution alternative:

utilisez un événement, la caractéristique oubliée de L'angle.

JavaScript adore les événements après tout. Les événements sont intrinsèquement lâchement couplé, et encore mieux, vous évitez d'ajouter une autre montre $à votre $digérer.

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

donc maintenant vous pouvez l'utiliser comme ceci:

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

et n'importe où dans votre application...

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

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

C'est génial parce que vous pouvez faire toutes sortes de choses avec quelque chose comme ça. Par exemple, vous pourriez être lié à des événements qui existent déjà. Pour une autre chose, vous commencez à faire quelque chose de intelligent en ayant différentes parties de votre application publier des événements que d'autres parties de votre application peuvent souscrire.

quoi qu'il en soit, ce genre de chose crie "événement conduit" à moi. Je pense qu'en tant que développeurs angulaires nous essayons vraiment dur de marteler $scope forme des chevilles dans des trous de la forme de l'événement.

est - ce la meilleure solution? Je ne sais pas. C'est la solution a .


Mise À Jour De La Solution

après le commentaire de @ShimonRachlenko ci-dessous, j'ai légèrement changé de méthode. Maintenant, j'utilise un combinaison d'un service et d'une directive qui traite un événement "en coulisse":

à part cela, c'est le même principe décrit ci-dessus.

Voici une rapide démonstration Plunk

Utilisation

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

Source

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);
    });
  }
});
256
répondu Ben Lesh 2014-08-09 17:59:08

j'ai trouvé que certaines des autres réponses étaient trop compliquées alors que tout ce dont vous avez vraiment besoin est ceci

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

utilisation

<input name="theInput" auto-focus>

nous utilisons le temps d'arrêt pour laisser les choses dans le DOM rendre, même si elle est zéro, il attend au moins que - de cette façon cela fonctionne dans les modèles et ce que trop

233
répondu ecancil 2014-08-17 13:24:54

HTML a un attribut autofocus .

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

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

85
répondu Rayron Victor 2015-09-29 12:43:52

vous pouvez également utiliser la fonctionnalité jqlite intégrée dans l'angle.

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

57
répondu JordanC 2013-12-11 08:35:10

cela fonctionne bien et une façon angulaire de focaliser le contrôle d'entrée

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

ce n'est bien sûr pas une façon purement angulaire de faire la tâche, mais la syntaxe suit le style angulaire. Jquery joue un rôle indirect et direct en accédant au DOM par L'Intermédiaire D'Angular (jQLite => jQuery Light).

si nécessaire, ce code peut facilement être placé dans une simple directive angulaire où l'élément est directement accessible.

50
répondu Sanjeev Singh 2016-07-28 09:06:06

Je ne pense pas que $timeout soit une bonne façon de concentrer l'élément sur la création. Voici une méthode utilisant la fonctionnalité angulaire intégrée, creusée à partir des profondeurs obscures des docs angulaires. Notez comment l'attribut" link "peut être divisé en" pre "et" post", pour les fonctions pre-link et post-link.

exemple pratique: 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 />

Full AngularJS Directive Docs: https://docs.angularjs.org/api/ng/service / $ compiler

30
répondu Cody Moniz 2014-05-28 19:07:48

voici ma solution originale:

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

et le HTML:

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

Ce qu'il fait:

il focalise l'entrée au fur et à mesure qu'elle devient visible avec ng-show. Pas d'utilisation de $regarder ou $sur ici.

17
répondu Edhowler 2016-02-04 20:52:15

j'ai écrit une directive de mise au point à double sens, comme model récemment.

vous utilisez la directive focus comme ceci:

<input focus="someFocusVariable">

si vous créez une variable scope vers n'importe où dans votre controller, input got focus. Et si vous "brouillez" votre entrée, someFocusVariable est défini à false. C'est comme la première réponse de Mark Rajcok, mais avec des liens dans les deux sens.

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

Utilisation:

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

voici le violon:

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

17
répondu Umut Benzer 2016-10-05 12:57:27

pour ceux qui utilisent Angular avec le plugin Bootstrap:

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

vous pouvez vous accrocher à la opened promesse de l'instance modale:

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

modalInstance.result.then(function ( etc...
10
répondu BPH 2015-03-03 15:32:25

au lieu de créer votre propre directive, il est possible d'utiliser simplement les fonctions javascript pour accomplir un focus.

voici un exemple.

dans le fichier html:

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

Dans un fichier javascript, dans un contrôleur, par exemple, lorsque vous voulez activer le focus:

document.getElementById("myInputId").focus();
7
répondu user3657103 2014-06-20 14:56:35

ne pas ressusciter un zombie ou brancher ma propre directive (ok c'est exactement ce que je fais):

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
        };
    }
})();
7
répondu Jon Hieb 2015-08-03 18:39:42

tout d'abord, une façon officielle de se concentrer est sur la feuille de route pour 1.1 . En attendant, vous pouvez écrire une directive pour mettre en œuvre la mise au point.

en Second lieu, pour définir le focus sur un élément, après qu'il est devenu visible exige actuellement une solution de contournement. Reportez simplement votre appel à element focus() avec un $timeout .

parce que le même problème de contrôleur-modifie-DOM existe pour focus, flou et select, je propose d'avoir un ng-target directive:

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

fil angulaire ici: http://goo.gl/ipsx4 , et plus de détails blogué ici: http://goo.gl/4rdZa

la directive suivante créera une fonction .focus() à l'intérieur de votre contrôleur comme spécifié par votre attribut ng-target . (Il crée un .blur() et un .select() .) Démo: http://jsfiddle.net/bseib/WUcQX /

6
répondu broc.seib 2013-02-14 18:26:18

j'ai trouvé utile d'utiliser une expression générale. De cette façon, vous pouvez faire des choses comme Déplacer automatiquement la mise au point lorsque le texte d'entrée est valide

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

ou se concentrer automatiquement lorsque l'utilisateur remplit un champ de longueur fixe

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

Et bien sûr, se concentrer après charge

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

le code de la directive:

.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
                        }
                    }
                });
            }
        }
    };
});
6
répondu winry 2015-04-30 09:15:27

si vous vouliez juste une mise au point simple qui était contrôlée par un ng-click.

Html:

<input ut-focus="focusTigger">

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

Directive:

'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
répondu TOBlender 2014-02-17 18:06:26

un simple qui fonctionne bien avec les modèles:

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

        link: function (scope, element, attrs)
        {


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



        }
    };
}])

exemple

<input ng-model="your.value" focus-me-now />
4
répondu Shawn Dotey 2016-01-13 15:35:47

vous pourriez juste créer une directive qui oblige à se concentrer sur l'élément décoré sur la liaison postale:

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

puis dans votre html:

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

cela fonctionnerait pour les modaux et les éléments ng-if toggled, pas pour les éléments ng-show car postLinking se produit seulement sur le traitement HTML.

3
répondu ibaixas 2013-12-26 16:25:20

Mark et Blesh ont de bonnes réponses; cependant, Mark a un défaut que Blesh souligne (en plus d'être complexe à mettre en œuvre), et je pense que la réponse de Blesh a une erreur sémantique dans la création d'un service qui est spécifiquement sur l'envoi de la demande de mise au point à l'interface alors que tout ce dont il avait besoin était un moyen de retarder l'événement jusqu'à ce que toutes les directives étaient à l'écoute.

voici Donc ce que j'ai fait qui vole beaucoup de Blesh réponse, mais conserve la sémantique de l'Événement du contrôleur et le service "after load" sont séparés.

cela permet à l'événement controller d'être facilement accroché pour des choses autres que la mise au point d'un élément spécifique et permet également d'engager la fonction" after load " uniquement si elle est nécessaire, ce qui peut ne pas être le cas dans de nombreux cas.

Utilisation

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

  afterLoad(notifyControllerEvent);
});

Source

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);
  }
});
3
répondu joshperry 2014-02-18 23:14:30

il est également possible d'utiliser ngModelController . Travailler avec 1.6+ (ne sait pas avec les versions plus anciennes).

HTML

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

JS

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

--

N.B.: selon le contexte, vous devrez peut-être intégrer une fonction de temporisation.

N.B. 2: Lorsqu'on utilise controllerAs , c'est presque la même chose. Il suffit de remplacer name="myForm" avec name="vm.myForm" et dans JS, vm.myForm.myText.$$element.focus(); .

3
répondu Ludovic Guillaume 2017-02-21 13:59:46

probablement, la solution la plus simple à L'âge ES6.

L'ajout de la directive liner suivante rend L'attribut HTML 'autofocus' efficace sur angulaire.js.

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

Maintenant, vous pouvez juste utiliser la syntaxe d'autofocus HTML5 comme:

<input type="text" autofocus>
3
répondu Tsuneo Yoshioka 2017-06-15 07:58:19

juste un internaute novice ici, mais j'étais capable de le faire fonctionner dans un ui.bootstrap.modal avec cette directive:

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

et dans le $modal.la méthode ouverte I a utilisé la formule suivante pour indiquer l'élément où le foyer doit être placé:

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

sur le modèle, j'ai ceci:

<input id="myInputId" focus />
2
répondu pitervergara 2014-02-14 12:57:05

j'édite la directive 'Mark Rajcok' focusMe pour travailler avec plusieurs focus dans un seul élément.

HTML:

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

dans le contrôleur AngularJs:

$scope.myInputFocus= true;

Directive AngulaJS:

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);
                }
            });
        }
    };
});
2
répondu Mohamad Khani 2014-07-22 05:57:23

La directive suivante a fait l'affaire pour moi. Utilisez le même attribut HTML autofocus pour la saisie.

.directive('autofocus', [function () {
    return {
        require : 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.focus();
        }
    };
}])
2
répondu Kishore Relangi 2015-08-06 03:41:17

si vous utilisez modalInstance et que vous avez l'objet, vous pouvez utiliser" then " pour faire des actions après l'ouverture du modal. Si vous n'utilisez pas le modalInstance, et codé dur pour ouvrir le modal, vous pouvez utiliser l'événement. Le $ timeout n'est pas une bonne solution.

Vous pouvez le faire (Bootstrap3):

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

à modalInstance vous pouvez regarder la bibliothèque pour savoir comment exécuter le code après open modal.

N'utilisez pas $timeout comme ceci, le $timeout peut être 0, 1, 10, 30, 50, 200 ou plus cela dépend de l'ordinateur client, et le processus d'ouverture de modal.

de Ne pas utiliser $timeout laissez la méthode dites-vous quand vous pouvez vous concentrer ;)

j'espère que cette aide! :)

2
répondu Filipe Cotrim Melo 2015-09-21 14:35:14

toute la réponse précédente ne fonctionne pas si l'élément focus désiré est injecté dans un modèle de directive. La directive suivante convient à la fois à l'élément simple ou à l'élément injecté (Je l'ai écrit dans dactylographié ). il accepte le sélecteur pour l'élément focalisable interne. si vous avez juste besoin de focaliser l'élément self - n'envoyez aucun paramètre de sélecteur à la directive:

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

}

exemple d'utilisation pour simple élément:

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

exemple d'utilisation pour l'élément intérieur (généralement pour la directive dynamic injected element like avec template):

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

vous pouvez utiliser n'importe quel sélecteur jQuery à la place de" input "

2
répondu Ofir Meguri 2016-03-09 09:26:08

c'est facile.. essayez

html

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

javascript

document.getElementById("ddl00").focus();
2
répondu isanka thalagala 2017-07-28 08:20:08

je veux contribuer à cette discussion après avoir cherché une meilleure solution et ne pas la trouver, ayant à la créer à la place.

critères: 1. La Solution doit être indépendante de la portée du contrôleur parent pour augmenter la réutilisabilité. 2. Évitez l'utilisation de $ watch pour surveiller certaines conditions, c'est à la fois lent, augmente la taille de la boucle digest et rend les tests plus difficiles. 3. Évitez $timeout ou $scope.$apply() pour déclencher un recueil de la boucle. 4. Un élément d'entrée est présent dans l'élément où la Directive est utilisée ouvert.

C'est la solution qui m'a le plus plu:

Directive:

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

Html:

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

j'espère que cela aidera quelqu'un là-bas!

1
répondu xiaoma 2015-02-18 13:10:00

je pense que la directive est inutile. Utilisez L'id HTML et les attributs de classe pour sélectionner l'élément requis et avoir le document d'utilisation du service.getElementById ou document.sélecteur de question à appliquer focus (ou équivalents jQuery).

Balisage HTML standard/angulaire des directives ajouté id/classes pour la sélection

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

Contrôleur des émissions de l'événement

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

dans le service D'assurance-chômage utilise querySelector - s'il y a des correspondances multiples (disons en raison de la classe), il ne retour au premier

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

Vous pouvez utiliser $timeout() pour forcer un condensé du cycle

0
répondu johans 2014-03-30 23:37:48

je rajoute du café.

app.directive 'ngAltFocus', ->
    restrict: 'A'
    scope: ngAltFocus: '='
    link: (scope, el, attrs) ->
        scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv
0
répondu Talasan Nicholson 2014-06-10 22:16:38

Je ne suis pas sûr que de compter sur le timeout soit une bonne idée, mais cela fonctionne pour ng-repeat parce que ce code court après angularjs met à jour le DOM, donc vous vous assurez que tous les objets sont là:

myApp.directive('onLastRepeat', [function () {
        return function (scope, element, attrs) {
            if (scope.$last) setTimeout(function () {
                scope.$emit('onRepeatLast', element, attrs);
            }, 1);
        };
    }]);
    //controller for grid
    myApp.controller('SimpleController', ['$scope', '$timeout', '$http', function ($scope, $timeout, $http)
    {
        var newItemRemoved = false;
        var requiredAlert = false;
        //this event fires up when angular updates the dom for the last item
        //it's observed, so here, we stop the progress bar
        $scope.$on('onRepeatLast', function (scope, element, attrs) {
            //$scope.complete();
            console.log('done done!');
            $("#txtFirstName").focus();
        });
    }]);
0
répondu Alex 2015-02-06 20:40:40