-
Notifications
You must be signed in to change notification settings - Fork 27.4k
Provide a standard way to manage focus #2012
Comments
Some discussion regarding this in #1250 as well |
There has been quite some discussion around this topic, so a proper solution requires more effort no doubt, but I thought I'd share the following which has served me well so far. angular.module('cn')
.directive('cnFocusWhen', [function () {
return function postLink(scope, element, attrs) {
scope.$watch(attrs.cnFocusWhen, function( autofocus ) {
if ( autofocus )
setTimeout( function () {
element[0].focus()
}, 0)
})
}
}]) Sounds like my implementation is similar to that of @ewinslow's, the only real difference being syntax; "focus-model" to me implies it should only watch model properties, whereas I usually have a $scope.state object separate to my $scope.form model. |
I opted for "focus-when", but I suppose ng-autofocus might fit better with Angular's motto "HTML enhanced"; adding the attribute autofocus to the element when ng-autofocus evaluates to true, similar to how ng-required works.. // **Not tested!**
angular.module('cn')
.directive('cnAutofocus', [function () {
return function postLink(scope, element, attrs) {
scope.$watch(attrs.cnAutofocus, function( autofocus ) {
if ( autofocus ) element.attr('autofocus','true')
else element.removeAttr('autofocus')
})
}
}]) |
Since this is a large change set, I've started a discussion on the mailing list here about it: https://groups.google.com/forum/?hl=en#!topic/angular/EQSWV1chf0A The spirit of the addition, at this point, is that I'm implementing a new controller, similar to an NgModelController, but seperate, as it only worries about managing focus. More details can be found at the link. I'll have a pull request ready soon. |
I have the code ready, but I'm unable to build and run tests. I want to get this done and submit a pull request for your review, but currently I can't until I get this resolved #3648 |
The only way to go around this is by using event listeners, and |
I'm fairly new to angular, but coming from KnockoutJS, I tried to replicate the 'hasfocus' data binding (see http://knockoutjs.com/documentation/hasfocus-binding.html) which seems to achieve what you want. Here's my effort:
It's probably not the most efficient way to go, but like I said I'm new so go easy on me! I prefixed it 'db' simply because that matches the app I was working on at the time. |
Any progress on this? I've been racking my brain trying to get my directive to support the html5 "autofocus" boolean attribute, but angular seems determined not to allow me to do it. |
RoyceLithgo - as I understand it, the autofocus attribute in html5 is only relevant on page load and does not effect behaviour after that. Have you tried the directive I listed above? I used it successfully in a Chrome extension but have not cross browser tested it. I see no reason why it would fail though, unless I've misunderstood what you are trying to achieve. Let me know if it's of any use to you. |
Actually in the end I did something similar to get the autofocus supported in my directive. I added autofocus to my isolate scope and did this in the linking function: if(scope.autofocus === "true") In my case the element was nested in the directive template, hence the path above. It works, but it does need you to set a value on the autofocus attribute whereas the html5 autofocus attribute doesn't need one. My logic was a lot simpler than yours, mainly because it doesn't support 2-way binding (in my use case, I will always set autofocus to a static "true" value on the first element in the form). |
I think because the use cases for such a directive might differ, this is a good opportunity for 3rd party modules to implement different solutions. http://github.com/jgallen23/angular-focus looks like a good start. I'm going to close this as "not in core," but feel free to post solutions or links to modules here for others to find. Thanks! |
I'm not sure I disagree, or agree. Given that there is a method for managing element validity built into Angular, why would a method for managing element focus in a similar fashion not also be a core feature? It might be nice for use in more primitive directives, like a custom calendar control for example, or maybe a custom color picker. Something were more fine-grained focus control might prove useful. Honest question. Thanks for your time, @btford. |
honestly I think the form validation stuff should also be a separate module |
Fair enough. I think I can agree with that. |
Hahaha... my last comment reads funny. I'm sure you were just waiting around to see if I'd agree with you. ;) lol |
Listening for focus/blur events is nice, but it frequently comes up that I need to set the focus on a certain element. E.g. clicking an "add comment" button opens up text field and sets focus inside the textarea. Clicking submit/cancel closes the form and puts focus back on the "add comment" button.
Related: #903 and #1277.
My initial thought was ng-focus-model="some.model". Setting some.model to true in the controller would then move focus to the element. But after experimenting with this, I've found that to be pretty unintuitive. This is one of the few cases where reaching into the DOM and just calling element.focus() seems like the right thing to do. Perhaps angular could provide a way to access dom elements from controllers (heresy!!) but with a severly limited API (i.e. only supports focus())
The text was updated successfully, but these errors were encountered: