Why auto focus directive does not work - angularjs

Auto focus directive is not working look at my code
i think there is some problem
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {});
app.directive('autoFocus', ['$timeout', function ($timeout) {
return {
restrict: 'AC',
link: function (scope, element, attrs, ctrl) {
setTimeout(function () {
if ($(element)) {// if value is already filled
if (attrs.focusNext) { // if next Field provided then put focus on next field
var target = angular.element('#' + attrs.focusNext);
target.focus();
}
else element.focus();
}
else element.focus(); //setting current value focus
}, 600);
}
};
}])

I think you need to put index in element like this
app.directive('autoFocus', ['$timeout', function ($timeout) {
return {
restrict: 'AC',
link: function (scope, element, attrs, ctrl) {
setTimeout(function () {
if ($(element[0]).val()) {// if value is already filled
if (attrs.focusNext) { // if next Field provided then put focus on next field
var target = angular.element('#' + attrs.focusNext);
target[0].focus();
}
else element[0].focus();
}
else element[0].focus(); //setting current value focus
}, 600);
}
};
}])
hope it will help you

As #hope said you have to use index to access to DOM elements but you also need to use element[0].value to access to the element value.
And finally you need to use angular.element(document.getElementById(attrs.focusNext)) to find an element by id, like this :
var app = angular.module('plunker', []);
app.directive('autoFocus', ['$timeout', function($timeout) {
return {
restrict: 'AC',
link: function(scope, element, attrs, ctrl) {
setTimeout(function() {
if (element[0].value) { // if value is already filled
if (attrs.focusNext) { // if next Field provided then put focus on next field
var target = angular.element(document.getElementById(attrs.focusNext));
target[0].focus();
} else element[0].focus();
} else element[0].focus(); //setting current value focus
}, 600);
}
};
}])
app.controller('MainCtrl', function($scope) {
$scope.test = "first input already filled"
});
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<body ng-app="plunker" ng-controller="MainCtrl">
<input ng-model="test" auto-focus focus-next="secondField">
<input id="secondField">
</body>

Related

After element.replaceWith(contents) how can go back to the original code

i have a problem that when i replace an element html i don't know how to go back to the original code before replacement.
Here is my code. http://jsfiddle.net/Mahmoudbay/o166xg0s/94/ here is the controller.
angular.module('App', [])
.controller('myCtrl', function($scope) {
$scope.checked = true;
})
.directive('ngBatchIf', function($compile) {
return {
restrict: 'A',
scope: {
check: '#'
},
controller: function($scope) {},
link: {
pre: function(scope, elm, attrs) {
attrs.$observe('check', function() {
// After flattening, Angular will still have the first element
// bound to the old scope, so we create a temporary marker
// to store it
var contents = elm.contents();
if (scope.check === "true") {
console.log(scope.check);
} else {
console.log(scope.check);
elm.replaceWith(contents);
}
})
}
}
}
});
thank you.
maybe you can create a clone of the original element?
var originalElm = elm.clone()

How to update the input text value using custom Directive in angularjs

I am newer in angularjs. I am just trying to update the input txt value using custom Directive. But i cant. Here i have showed my code What i did wrong this code. Some one help me and explain how it is working.
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
myApp.controller('MyCtrl',MyCtrl);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.myTime = '10:59';
}
myApp.directive('myDirective', function () {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
scope.$watch(attrs.ngModel, function (v) {
console.log('value changed, new value is: ' + v);
ngModel.$setViewValue('11')
//scope.ngModel = '11'
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MyCtrl">
Hello, {{name}}!
<input type="text" my-directive ng-model="myTime" name="customTime">
</div>
You should register your MyCtrl controller in your myApp module like below.
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl',MyCtrl);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.myTime = '10:59';
}
If you need to update the text field value to some desired value, once you're done with the update in the watcher using $setViewValue(), you need to call $render() as well on NgModelController.
link: function (scope, element, attrs, ngModel) {
scope.$watch(attrs.ngModel, function (v) {
console.log('value changed, new value is: ' + v);
ngModel.$setViewValue('11');
ngModel.$render();
});
}
Here's a Pen to check this change.

Data attribute change not being observed

I'm changing data attribute of a dom element and using $observe within the directive to detect for any changes but it doesn't seem to work after clicking on the "change data" button
HTML
<body ng-controller="MainCtrl">
<div id="container" data-name="somename" mydirective>Data</div>
<button ng-click="changeData();">Change Data Attribute</button>
</body>
JS
app.controller('MainCtrl', function($scope) {
$scope.changeData = function() {
var el = document.querySelector('#container');
angular.element(el).attr('data-name', 'hello');
}
});
app.directive('mydirective', function() {
return {
link : function(scope, element, attrs, ngModel) {
attrs.$observe("name", function (newValue) {
console.log(newValue);
});
}
}
Plnkr : http://plnkr.co/edit/saM7fO0DdsaaDBW7ADQH?p=preview
why dont you use expression data-name="{{datax}}" ?
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.datax = "somename";
$scope.changeData = function() {
//var el = document.querySelector('#container');
//angular.element(el).attr('data-name', 'hello');
$scope.datax = "hello";
}
});
app.directive('mydirective', function() {
return {
link : function(scope, element, attrs, ngModel) {
attrs.$observe("name", function (newValue) {
console.log(newValue);
});
}
}
});

Convert number to currency through directive

I am trying to convert number into currency suppose if user enter 5 in textbox i want to auto correct it like $5.00 for that i am trying to write directive but no idea how to make it work as working on directive for fist time.
(function () {
'use strict';
angular.module('commonModule')
.directive('srCurreny', function (utilSvc) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, model) {
element.bind('blur', function (event) {
var val = element.val();
if (!utilSvc.isEmptyOrUndefined(val)) {
var transform = currency + " " + val.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
model.$setViewValue(element.val(transform));
scope.$apply();
}
});
}
};
});
})();
JS
Set the amount in the Controller first.
angular.module('commonModule')
.controller('aController', ['$scope', function (scope) {
scope.amount = 5;
}])
.directive('srCurrency', ['$filter', function ($filter) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, el, attrs, ngModel) {
function onChangeCurrency () {
ngModel.$setViewValue($filter('currency')(ngModel.$viewValue, '$'));
ngModel.$render();
}
el.on('blur', function (e) {
scope.$apply(onChangeCurrency);
});
}
}
}]);
HTML
<div ng-app='app' ng-controller="aController">
<input type="text" sr-currency ng-model='amount' />
</div>
JSFIDDLE
I recommend using the build-in currency filter of Angular, or, if that doesn't meet your needs you can create your own.
https://docs.angularjs.org/api/ng/filter/currency

AngularJS UniformJS Select Control not updating

I'm building an application using AngularJS and UniformJS. I'd like to have a reset button on the view that would reset my select's to their default value. If I use uniform.js, it isn't working.
You can examine it here:
http://plnkr.co/edit/QYZRzlRf1qqAYgi8VbO6?p=preview
If you click the reset button continuously, nothing happens.
If you remove the attribute, therefore no longer using uniform.js, everything behaves correctly.
Thanks
UPDATE:
Required the use of timeout.
app.controller('MainCtrl', function($scope, $timeout) {
$scope.reset = function() {
$scope.test = "";
$timeout(jQuery.uniform.update, 0);
};
});
Found it. For the sake of completeness, I'm copying my comment here:
It looks like Uniform is really hacky. It covers up the actual select element, and displays span instead. Angular is working. The actual select element's value is changing, but the span that Uniform displays is not changing.
So you need to tell Uniform that your values have changed with jQuery.uniform.update. Uniform reads the value from the actual element to place in the span, and angular doesn't update the actual element until after the digest loop, so you need to wait a little bit before calling update:
app.controller('MainCtrl', function($scope, $timeout) {
$scope.reset = function() {
$scope.test = "";
$timeout(jQuery.uniform.update, 0);
};
});
Alternatively, you can put this in your directive:
app.directive('applyUniform',function($timeout){
return {
restrict:'A',
require: 'ngModel',
link: function(scope, element, attr, ngModel) {
element.uniform({useID: false});
scope.$watch(function() {return ngModel.$modelValue}, function() {
$timeout(jQuery.uniform.update, 0);
} );
}
};
});
Just a slightly different take on #john-tseng's answer. I didn't want to apply a new attribute to all my check-boxes as we had quite a few in the application already. This also gives you the option to opt out of applying uniform to certain check-boxes by applying the no-uniform attribute.
/*
* Used to make sure that uniform.js works with angular by calling it's update method when the angular model value updates.
*/
app.directive('input', function ($timeout) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attr, ngModel) {
if (attr.type === 'checkbox' && attr.ngModel && attr.noUniform === undefined) {
element.uniform({ useID: false });
scope.$watch(function () { return ngModel.$modelValue }, function () {
$timeout(jQuery.uniform.update, 0);
});
}
}
};
});
Please try blow code.
app.directive('applyUniform', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
if (!element.parents(".checker").length) {
element.show().uniform();
// update selected item check mark
setTimeout(function () { $.uniform.update(); }, 300);
}
}
};
});
<input apply-uniform type="checkbox" ng-checked="vm.Message.Followers.indexOf(item.usrID) > -1" ng-click="vm.toggleSelection(item.usrID)" />

Resources