Reputation: 718
I have this directive:
(function () {
'use strict';
var app = angular.module('myAppName');
app.directive('smFocus', [ '$timeout', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element) {
scope.$on('sm:focus', function () {
$timeout(function() {
element[0].focus();
}, 10);
});
}
};
}]);
})();
I also have these two controls:
<input type="text"
name="nickname"
id="nickname"
ng-model="currentDynamicRule.nickname"
class="form-control"
ng-disabled="!isNew"
placeholder="Nickname"
required
ng-maxlength="10"
sm-focus />
and another one
<input type="text" name="descrip" id="descrip" ng-model="currentDynamicRule.descrip" class="form-control"
placeholder="Description" required ng-maxlength="30"
sm-focus />
So, two controls where the first one is only enabled when it's a new row (disabled in Edit mode). I want to have the first control focused when it's a new record and the second control focused when it's in edit mode.
I am using ASP.NET MVC. Right now in both edit and new modes I have the second control focused. I am not sure how to make this focus conditional.
Upvotes: 0
Views: 2011
Reputation: 718
Here is my current implementation that seems to be working! Need to test more:
app.directive('smFocus', [ '$timeout', function ($timeout) {
return {
restrict: 'A',
scope: {
noFocus: "=?"
},
link: function (scope, element) {
var noFocus = angular.isDefined(scope.noFocus) ? scope.noFocus : false;
// console.log('noFocus=' + noFocus)
if (!noFocus) {
scope.$on('sm:focus', function () {
$timeout(function () {
element[0].focus();
}, 10);
});
}
}
};
And my form controls are:
<input type="text"
name="nickname"
id="nickname"
ng-model="currentDynamicRule.nickname"
class="form-control"
ng-disabled="!isNew"
placeholder="Nickname"
required
ng-maxlength="10"
no-focus="!isNew"
sm-focus />
And similar for description:
<input type="text" name="descrip" id="descrip" ng-model="currentDynamicRule.descrip" class="form-control"
placeholder="Description" required ng-maxlength="30"
no-focus="isNew"
sm-focus />
The form works as I want it. I am going to test few more forms to make sure this change didn't break anything.
Upvotes: 0
Reputation: 30088
hmm I had written a directive before wherein it accepts an event and an element id to focus when that event has been triggered.
It's something like this(Plunker DEMO):
JAVASCRIPT
.directive('eventFocus', function($timeout) {
return function(scope, elem, attr) {
elem.on(attr.eventFocus, function() {
// timeout makes sure that is invoked after any other event has been triggered.
// e.g. click events that need to run before the focus or
// inputs elements that are in a disabled state but are enabled when those events
// are triggered.
$timeout(function() {
var element = document.getElementById(attr.eventFocusId);
if(element)
element.focus();
});
});
scope.$on('$destroy', function() {
element.off(attr.eventFocus);
});
};
})
HTML (Possible implementation)
<input type="text" id="pet-desc" ng-model="pet.desc">
<button type="button" event-focus="click" event-focus-id="pet-desc">Edit</button
When Edit Button is clicked, input with id="pet-desc" is focused.
UPDATE:
To identify between which sm-focus
element is the target for the sm:focus
event, you can add an argument(the id of the element to focus to) within your $rootScope.$broadcast()
. See this PLUNKER.
e.g.
Controller
$rotoScope.$broadcast('sm:focus', 'pet-id');
Directive
directive('smFocus', function($timeout) {
return function(scope, elem, attr) {
scope.$on('sm:focus', function(event, id) {
$timeout(function() {
if(attr.id == id)
elem[0].focus();
});
});
};
})
Upvotes: 1