- Cuando se abre un Modal, fije el foco en un <input> predefinido dentro de este Modal.
Defina una directiva y haga que $ vea una propiedad / disparador para que sepa cuándo enfocar el elemento:
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));
});
}
};
}]);
Saqueador
El tiempo de espera $ parece ser necesario para dar tiempo modal para renderizar.
'2.' Cada vez que <input> se hace visible (por ejemplo, haciendo clic en algún botón), establezca el foco en él.
Crea una directiva esencialmente como la de arriba. Observe algunas propiedades de alcance y, cuando se convierta en verdadero (configúrelo en su controlador ng-click), ejecute element[0].focus()
. Dependiendo de su caso de uso, puede necesitar o no un tiempo de espera de $ para este:
<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;
//});
}
});
}
};
});
Saqueador
Actualización 7/2013 : he visto a algunas personas usar mis directivas de alcance de aislamiento originales y luego tienen problemas con los campos de entrada incrustados (es decir, un campo de entrada en el modal). Una directiva sin un nuevo alcance (o posiblemente un nuevo alcance infantil) debería aliviar algo del dolor. Así que arriba actualicé la respuesta para no usar ámbitos de aislamiento. A continuación se muestra la respuesta original:
Respuesta original para 1., usando un alcance aislado:
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 .
Respuesta original para 2., usando un alcance aislado:
<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 .
Como necesitamos restablecer la propiedad trigger / focusInput en la directiva, '=' se usa para el enlace de datos bidireccional. En la primera directiva, '@' era suficiente. También tenga en cuenta que cuando se usa '@', comparamos el valor de activación con "verdadero" ya que @ siempre da como resultado una cadena.