How to update the input text value using custom Directive in angularjs - 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.

Related

Convert string to date in AngularJS directive

I'm trying to convert a string date so that it works on a html input with the type set to 'date'.
So, I have the following angular app:
(function() {
var app = angular.module('test', []);
app.controller('MainCtrl', function($scope) {
$scope.load = function() {
$scope.message='2017-12-23T00:00:00Z';
};
});
app.directive('convertDate', function() {
return {
restrict: 'A',
scope: {
ngModel: '='
},
link: function (scope) {
console.log(scope);
console.log(scope.ngModel);
if (scope.ngModel) scope.ngModel = new Date(scope.ngModel);
}
};
});
})();
Then my html is as follows:
<div ng-controller='MainCtrl'>
<input type="date" convert-date ng-model="message">
<button ng-click="load()">load</button>
</div>
When I click on the load button I get the following error:
Error: [ngModel:datefmt] http://errors.angularjs.org/1.6.4/ngModel/datefmt?p0=2017-12-23T00%3A00%3A00Z
I understand the error is because it's a string and I need a date, which its the reason for my directive.
But even with the directive I still get the error.
What am I missing?
Thanks
Colin
You can change your directive to following:
angular.module('app').directive('convertDate', function() {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
if (!ctrl) return;
ctrl.$parsers.push(function(date) {
if (angular.isDate(date))
return new Date(date);
})
}
}
})
take a look at this working plunkr without error
https://plnkr.co/edit/8aSR1dlsRfDMrM7GfQQa?p=preview
It is because you are using same variable in ng-model for converting. So it encounters an error before your directive converts it.
According to me, you should convert it first and then assign to the ng-model variable in your controller.
Like this,
(function() {
var app = angular.module('test', []);
app.controller('MainCtrl', function($scope) {
$scope.load = function() {
var dateString = '2017-12-23T00:00:00Z';
$scope.message=new Date(dateString);
};
});
})();
No need to use directive

Minification safe directive with link attribute in angular js

There is very handly directive at to format date in ng-model with HTML input here.
angular.module('app', []).controller('Ctrl', function($scope){
$scope.firstDate = new Date();
$scope.secondDate = "2014-02-20";
}).directive('date', function (dateFilter) {
return {
require:'ngModel',
link:function (scope, elm, attrs, ctrl) {
var dateFormat = attrs['date'] || 'yyyy-MM-dd';
ctrl.$formatters.unshift(function (modelValue) {
return dateFilter(modelValue, dateFormat);
});
}
};
});
I tried to use same for my project,but the problem is that is fails to work when javascript file is minified. It logs an error [$injector:unpr] ...../$injector/unpr?p0=eProvider%20%3C-%20e%20%3C-%20dateDirective.
I tried to minify using this
Please guide me on how to minify this directive.
It happens because you don't use injection a.e $inject.
.controller('Ctrl', ['$scope',function($scope){/* ... */}]);
.directive('date', ['dateFilter', function (dateFilter) {/* ... */}]);
So your directive (and controller) will look like:
angular.module('app', []).controller('Ctrl', ['$scope',function($scope){
$scope.firstDate = new Date();
$scope.secondDate = "2014-02-20";
}]).directive('date', ['dateFilter', function (dateFilter) {
return {
require:'ngModel',
link:function (scope, elm, attrs, ctrl) {
var dateFormat = attrs['date'] || 'yyyy-MM-dd';
ctrl.$formatters.unshift(function (modelValue) {
return dateFilter(modelValue, dateFormat);
});
}
};
}]);

Why auto focus directive does not work

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>

How can I access $event inside a directive?

I can't seem to pass it as an attribute!
I can add an ng-click="function($event)" and pass $event that way to a controller function, but I would like to access it inside a directive.
The ultimate purpose is to stopPropagation() and/or preventDefault() of an element inside a directive instead of in a controller.
EDIT: I will post code accordingly
<div ng-app="myApp" ng-controller="MyCtrl">
<button stop-toggle ng-click="testFunction($event)">
click me
</button>
Hello, {{name}}!
</div>
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.testFunction = function($event){
console.log("you can access the event here:", $event);
$event.stopPropagation();
}
}
myApp.directive('stopToggle', function(){
return {
link: function(scope, elem, attrs){
elem.bind('click', function(){
console.log("how do i access the $event here??");
// elem.stopPropagation(); // invalid function
// elem.preventDefault(); // invalid function
})
}
}
});
http://jsfiddle.net/Lvc0u55v/10656/
var myApp = angular.module('myApp',[]);
myApp.directive('stopToggle', function(){
return {
link: function(scope, elem, attrs){
elem.on('click', function(e){
e.stopPropagation();
e.preventDefault();
})
}
}
});
Just pass event as an argument to the function inside .on()

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

Resources