- Quando viene aperto un modale, focalizzare l'attenzione su un <input> predefinito all'interno di questo modale.
Definisci una direttiva e falla $ guardare una proprietà / trigger in modo che sappia quando focalizzare l'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
Il timeout $ sembra essere necessario per dare il tempo modale per il rendering.
'2.' Ogni volta che <input> diventa visibile (ad esempio facendo clic su un pulsante), impostare lo stato attivo su di esso.
Crea una direttiva essenzialmente come quella sopra. Guarda alcune proprietà dell'ambito e quando diventa vero (impostalo nel tuo gestore ng-click), esegui element[0].focus()
. A seconda del caso d'uso, potrebbe essere necessario o meno un timeout di $ per questo:
<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
Aggiornamento 7/2013 : ho visto alcune persone usare le mie direttive originali dell'ambito di isolamento e quindi avere problemi con i campi di input incorporati (ovvero un campo di input nel modale). Una direttiva senza un nuovo campo di applicazione (o forse un nuovo campo di applicazione per i minori) dovrebbe alleviare parte del dolore. Quindi sopra ho aggiornato la risposta per non usare gli ambiti isolati. Di seguito è la risposta originale:
Risposta originale per 1., utilizzando un ambito isolato:
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 .
Risposta originale per 2., usando un ambito isolato:
<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 .
Poiché è necessario reimpostare la proprietà trigger / focusInput nella direttiva, '=' viene utilizzato per il database bidirezionale. Nella prima direttiva, "@" era sufficiente. Si noti inoltre che quando si utilizza '@' si confronta il valore di trigger con "true" poiché @ risulta sempre in una stringa.