774 Stimmen

Wie setzt man den Fokus auf ein Eingabefeld?

Was ist der 'Angular Way', um den Fokus auf ein Eingabefeld in AngularJS zu setzen?

Weitere spezifische Anforderungen:

  1. Wenn ein Modal geöffnet wird, den Fokus auf ein vordefiniertes innerhalb dieses Modals setzen.
  2. Jedes Mal, wenn ein sichtbar wird (z. B. durch Klicken auf eine Schaltfläche), den Fokus darauf setzen.

Ich habe versucht, die erste Anforderung zu erreichen mit autofocus, aber das funktioniert nur, wenn das Modal zum ersten Mal geöffnet wird, und nur in bestimmten Browsern (z. B. in Firefox funktioniert es nicht).

2voto

pitervergara Punkte 86

Nur ein Neuling hier, aber ich konnte es in einem ui.bootstrap.modal mit dieser Direktive zum Laufen bringen:

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

und in der $modal.open Methode habe ich das folgende verwendet, um das Element anzugeben, auf das der Fokus gelegt werden soll:

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

Auf dem Template habe ich dies:

1voto

xiaoma Punkte 11

Ich möchte zu dieser Diskussion beitragen, nachdem ich nach einer besseren Lösung gesucht und sie nicht gefunden habe, stattdessen habe ich sie erstellt.

Kriterien: 1. Die Lösung sollte unabhängig vom Elterncontrollerbereich sein, um die Wiederverwendbarkeit zu erhöhen. 2. Vermeiden Sie die Verwendung von $watch zur Überwachung bestimmter Bedingungen; dies ist sowohl langsam, erhöht die Größe der Digest-Schleife und erschwert das Testen. 3. Vermeiden Sie $timeout oder $scope.$apply(), um eine Digest-Schleife auszulösen. 4. Ein Eingabeelement befindet sich innerhalb des Elements, in dem die Direktive geöffnet ist.

Dies ist die Lösung, die mir am besten gefallen hat:

Direktive:

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

Html:

Ich hoffe, dass dies jemandem da draußen helfen wird!

0voto

pejman Punkte 650

Sie können die folgende Direktive verwenden, die einen boolschen Wert in einem HTML-Input erhält, um den Fokus darauf zu setzen...

//JS-Datei
angular.module("appName").directive("ngFocus", function () {
       return function (scope, elem, attrs, ctrl) {
             if (attrs.ngFocus === "true") {
                 $(elem).focus();
             }
             if (!ctrl) {
                 return;
             }
       elem.on("focus", function () {
            elem.addClass("has-focus");
            scope.$apply(function () {
                ctrl.hasFocus = true;
            });
        });
    };
});

Sie können sogar eine Funktion in Ihrem Controller für den ngFocus-Direktivwert setzen achten Sie auf den folgenden Code...

//Controller-Datei
$scope.myFunc=function(){
      if(condition){
          return true;
      }else{
          return false;
      }
}

Diese Direktive soll passieren, wenn die HTML-Seite gerendert wird.

0voto

Alex Punkte 2098

Nicht sicher, ob es eine gute Idee ist, sich auf das Timeout zu verlassen, aber das funktioniert für ng-repeat, weil dieser Code NACH der Aktualisierung des DOM durch Angularjs ausgeführt wird, so dass Sie sicherstellen, dass alle Objekte dort sind:

myApp.directive('onLastRepeat', [function () {
        return function (scope, element, attrs) {
            if (scope.$last) setTimeout(function () {
                scope.$emit('onRepeatLast', element, attrs);
            }, 1);
        };
    }]);
    //Controller für Raster
    myApp.controller('SimpleController', ['$scope', '$timeout', '$http', function ($scope, $timeout, $http)
    {
        var newItemRemoved = false;
        var requiredAlert = false;
        //Dieses Ereignis wird ausgelöst, wenn Angular das DOM für das letzte Element aktualisiert
        //Es wird beobachtet, also hier stoppen wir die Fortschrittsanzeige
        $scope.$on('onRepeatLast', function (scope, element, attrs) {
            //$scope.complete();
            console.log('fertig!');
            $("#txtFirstName").focus();
        });
    }]);

0voto

johans Punkte 1664

Ich denke, die Direktive ist unnötig. Verwenden Sie HTML-ID und Klassenattribute, um das erforderliche Element auszuwählen, und lassen Sie den Service document.getElementById oder document.querySelector verwenden, um den Fokus anzuwenden (oder jQuery-Äquivalente).

Markup ist standardmäßiges HTML/Angular-Direktiven mit hinzugefügten ID/Klassen zur Auswahl

Controller sendet Ereignis

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

Im UI-Service wird querySelector verwendet - wenn es mehrere Treffer gibt (zum Beispiel aufgrund von Klassen), wird nur der erste zurückgegeben

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

Sie können $timeout() verwenden, um einen Digest-Zyklus zu erzwingen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X