Reputation: 29538
I have a directive that implements in-place editing. In its link
function I have a watch that is supposed to set focus on the text box when editing is switched on:
$scope.$watch('view.enabled', function(value) {
if (value) {
var element = $element.find('input') || $element.find('textarea');
var input = element && element[0];
if (input) {
$timeout(function() {
input.focus()
});
}
}
});
the directive can instantiate either an input
element, or a textarea
depending on the parameters. The problem is that invoking focus()
on the textarea
element does not set focus to it. For input
elements it does set the focus though.
Here is plnkr. Please help.
EDIT: using autofocus
attribute on the textarea
in HTML makes it get the focus, but I still do not understand why I cannot do it programmatically.
Upvotes: 2
Views: 7712
Reputation: 5065
I don't think $timeout is a good way to focus the element on creation. You can split the "link" attribute can be split into "pre" and "post", for pre-link and post-link functions.
Working Example: 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/$compile
Upvotes: 2
Reputation: 3856
You do not set focus to the textarea. Try this:
if (input) {
$timeout(function() {
console.log(input);
input.focus();
});
}
It will give you this:
<input ng-show="editableType !== 'multi-line'"
ng-model="view.value"
class="ng-pristine ng-valid ng-hide">
and not the textarea. Quick fix (for textarea only) could be:
var element = $element.find('textarea');
Depending on order of things, I'm not sure if this would help:
var element = $element.find('textarea') || $element.find('input');
have to look closer at it ...
Upvotes: 1