- Quando um Modal é aberto, defina o foco em uma <entrada> predefinida dentro deste Modal.
Defina uma diretiva e faça com que $ watch uma propriedade / gatilho saiba para quando focar o 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));
});
}
};
}]);
Plunker
O $ timeout parece ser necessário para fornecer o tempo modal para renderização.
'2.' Sempre que <entrada> ficar visível (por exemplo, clicando em algum botão), defina o foco.
Crie uma diretiva essencialmente como a acima. Observe alguma propriedade do escopo e, quando ela se tornar verdadeira (configure-a no manipulador de ng-click), execute element[0].focus()
. Dependendo do seu caso de uso, você pode ou não precisar de um tempo limite 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;
//});
}
});
}
};
});
Plunker
Atualização 7/2013 : vi algumas pessoas usarem minhas diretivas originais de escopo isolado e, em seguida, ter problemas com campos de entrada incorporados (ou seja, um campo de entrada no modal). Uma diretiva sem novo escopo (ou possivelmente um novo escopo filho) deve aliviar parte da dor. Portanto, atualizei a resposta para não usar escopos isolados. Abaixo está a resposta original:
Resposta original para 1., usando um escopo isolado:
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 .
Resposta original para 2., usando um escopo isolado:
<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 precisamos redefinir a propriedade trigger / focusInput na diretiva, '=' é usado para a ligação de dados bidirecional. Na primeira diretiva, '@' era suficiente. Observe também que, ao usar '@', comparamos o valor do acionador como "true", pois @ sempre resulta em uma string.