set focus of textbox used in directive template - angularjs

I am using directive to display textbox based on data model. If data mode is in edit state then I display textbox. I want that textbox focus should be set when it is rendered. I tried however couldn't find anything. Please help. Following is an example for review.
var myModule = angular.module('myModule', []);
myModule.directive('textbox', function() {
return {
restrict: 'E',
replace: true,
template: '<div ng-if="data.mode==edit"> <input type="text" ng-model="data.value"/> </div>',
link: function (scope, element, attrs)
{
scope.data = {"mode":"edit","value":"This is text box"};
}
};
});
JSFiddle

This will do the trick.
scope.$watch('data.mode', function(newValue, oldValue) {
if (newValue == 'edit') {
element.find('input')[0].focus();
}
});
JSFiddle

Related

Angularjs directive to make form dirty without ng-model

I am using Angular 1.5.1. I have a checkbox on my form. I do not care about the truth/false indicator of the checkbox being checked/unchecked and so I do not want ng-model on it. What I care for is:
when checkbox is unchecked, I delete a specific array from my model
when checkbox is checked, I add an empty array back to my model
So I have created a directive that provides me with this functionality, very simple:
.directive('cbOnChecked', function() {
return {
restrict: 'A',
link: function(scope, element, attr) {
element.on('click', function(event) {
if(element[0].checked)
scope.$apply(attr.cbOnChecked);
});
}
};
})
.directive('cbOnUnchecked', function() {
return {
restrict: 'A',
link: function(scope, element, attr) {
element.on('click', function(event) {
if(!element[0].checked)
scope.$apply(attr.cbOnUnchecked);
});
}
};
})
Now I can do something like:
<input type="checkbox" cb-on-checked="counter = counter + 1" cb-on-unchecked="counter = counter - 1"/>
Or
<input type="checkbox" cb-on-checked="deleteUserList()" cb-on-unchecked="users = []"/> No users<br/>
The problem with this is - the form within which the checkbox is won't get marked as $dirty if there is no ng-model on the checkbox. Is there any way around this?
Here is an example js-fiddle. Thanks.
If you really want to go with your own directives you can just require parent form controller and mark it $dirty manually:
.directive('cbOnChecked', function() {
return {
require: '^form',
restrict: 'A',
link: function(scope, element, attr, ngFormController) {
element.on('click', function(event) {
ngFormController.$setDirty();
if(element[0].checked)
scope.$apply(attr.cbOnChecked);
});
}
};
})

AngularJs - Bootstrap Toggle not able to get check box values

I am using Bootstrap Toggle for my AngularJs project. I created angular directive for this plugin.
myApp.directive('iosToggle', function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
$(element).bootstrapToggle(scope.$eval(attrs.iosToggle));
}
};
});
and using directive in my view
<input type="checkbox" id="myInterview" data-ios-toggle="toggle" data-style="ios" data-onstyle="info" data-size="small" data-on="On" data-off="Off" ng-model="myData.myInterview">
I am getting same design and able to on or off, but When i submit the form, i am not getting check box values.
Yes, I have updated my directive with $watch on change and then updated the model. It works.
myApp.directive('iosToggle', function($timeout){
return {
restrict: 'A',
transclude: true,
replace: false,
require: 'ngModel',
link: function ($scope, $element, $attr, ngModel) {
// update model from Element
var updateModelFromElement = function() {
// If modified
var checked = $element.prop('checked');
if (checked !== ngModel.$viewValue) {
// Update ngModel
ngModel.$setViewValue(checked);
$scope.$apply();
}
};
// Update input from Model
var updateElementFromModel = function() {
$element.trigger('change');
};
// Observe: Element changes affect Model
$element.on('change', function() {
updateModelFromElement();
});
// Observe: ngModel for changes
$scope.$watch(function() {
return ngModel.$viewValue;
}, function() {
updateElementFromModel();
});
// Initialise BootstrapToggle
$timeout(function() {
$element.bootstrapToggle();
});
}
};
});

AngularJs tooltip initialization and fade out

I use angular-ui tooltips (https://github.com/angular-ui/bootstrap/blob/master/src/tooltip/tooltip.js) or angular strap tooltip (http://mgcrea.github.io/angular-strap/#/tooltips#tooltips)
I need show tooltip on element, when the some event or expression.
Example below, we have the input. And i need to show tooltip, when data.model.count == 5. And then hide tooltip of beyond the 5 second. Help me please!
<input type="text" ng-model="data.model">
Write a directive! plunker
angular.module('ui.bootstrap.demo').directive('showTip', function($timeout){
return {
restrict: 'A',
scope: {
showTip: "="
},
link: function(scope, elm, attr){
var tooltip;
scope.$watch('showTip', function(newVal){
if(newVal == 5){
tooltip.css({visibility: 'visible'});
$timeout(function(){
tooltip.css({visibility: 'hidden'});
}, 5000)
}
})
elm.bind('DOMSubtreeModified', function(){
tooltip = elm.find('div');
tooltip.css({visibility: 'hidden'});
})
}
}
});

ng-bind span not updated on changing the object's property

In the following code, i change the object's property on clicking the 'tab' element, but the corresponding ngbind span is not getting updated. Do i have to call some function to update the view?
HTML:
<html ng-app="splx">
...
<body ng-controller="Application">
<span ng-bind="obj.val"></span>
<tabpanel selector="obj">
<div tab value="junk">junk</div>
<div tab value="super">super</div>
</tabpanel>
</body>
</html>
JS:
var cf = angular.module('splx', []);
function Application($scope) {
$scope.obj = {val: "something"};
}
cf.directive('tabpanel', function() {
return {
restrict: 'AE',
scope: {
selector: '='
},
controller: ['$scope', function($scope) {}]
};
});
cf.directive('tab', function() {
return {
require: '^tabpanel',
restrict: 'AE',
scope: true,
link: function(scope, elem, attrs) {
elem.bind('click', function() {
scope.$parent.selector.val = "newthing";
});
}
};
});
cf.directive('tab', function() {
return {
require: '^tabpanel',
restrict: 'AE',
scope: true,
link: function(scope, elem, attrs) {
elem.bind('click', function() {
scope.$apply(function () {
scope.$parent.selector.val = "newthing";
});
});
}
};
});
That works for me. Just missing a little scope.$apply in there.
Might want to have a look at https://coderwall.com/p/ngisma if you find yourself using/having trouble with '$apply already in progress'.
If you want to change the value to what you clicked on, I'd do something like this:
scope.$parent.selector.val = attrs.tab;
As opposed to:
scope.$parent.selector.val = "newthing";
And then you can change your markup to look like this:
<tabpanel selector="obj">
<div tab="junk">junk</div>
<div tab="super">super</div>
</tabpanel>
Hope that helps!
First problem: you are not binding your controller to your app.
You need cf.controller('Application', Application);.
Also you need ng-controller="Application" in HTML on a parent of that span and the tabpanel directive.
Second problem: after changing that scope variable in your click event you need to
scope.$apply() to let Angular know something changed and it needs to $digest it.
You can check out my version here.

Dialog does not get the focus after it opens (angularJS)

I am calling the following from a button:
var d = $dialog.dialog({dialogFade: false, modal:true, backdropClick: false});
d.open('html/xyz.html', 'xyzController');
All work fine except the dialog does not get the focus. it treats it as an element at the end of the page if we TAB.
is there a way to give the dialog the focus??? I tried all solution I can find but no success.
thanks
You can use a directive to setFocus on any element:
MyApp.directive('CustomSetFocus', [function () {
return {
restrict: 'A',
link: function (scope, element, attrs, controller) {
scope.$watch(attrs.customSetFocus, function (newValue, oldValue) {
if (newValue === true) {
element[0].focus();
}
});
}
};
}]);
Then you can trigger it like so:
<input type="text" id="whatever" custom-set-focus="true"/>
Or, you can set a scope variable in your controller that will trigger the focus, maybe in an intialize() function or something like that:
<input type="text" id="whatever" custom-set-focus="someScopeVariable"/>

Resources