Getting NaN when a directive is used in angularJs - html

I am using a directive to show the number count effect for my dashboard when i used the directive for the h3 i am getting the result as NaN. when i remove the directive from the h3 i am getting the correct output.
When i looked into the directive i can the the value is get from element which shows the value as NaN. can anyone tell me what is wrong in the code?
Output with directive:
<h3 animate-numbers="" class="ng-binding">NaN</h3>
Html:
<h3 animate-numbers>{{vm.dashboard.no_of_applications}}</h3>
Controller:
vm.dashboard = {
no_of_users: 0,
no_of_applications: 0,
no_of_departments: 0,
no_of_schemes: 0,
};
Directive:
'use strict';
angular.module('ss')
.directive('animateNumbers', function ($timeout, $log) {
return {
replace: false,
scope: true,
link: function (scope, element) {
var e = element[0];
$log.log('e is', e);
var refreshInterval = 30;
var duration = 1000; //milliseconds
var number = parseInt(e.innerText);
var step = 0;
var num = 0;
var steps = Math.ceil(duration / refreshInterval);
var increment = (number / steps);
var percentCompleted = 0;
var lastNumberSlowCount = 3;
if (number > lastNumberSlowCount) {
number = number - lastNumberSlowCount;
}
scope.timoutId = null;
var slowCounter = function () {
scope.timoutId = $timeout(function () {
lastNumberSlowCount --;
if (lastNumberSlowCount < 0) {
$timeout.cancel(scope.timoutId);
} else {
number++;
e.textContent = number;
slowCounter();
}
}, 500);
};
var counter = function () {
scope.timoutId = $timeout(function () {
num += increment;
percentCompleted = Math.round((num / number) * 100);
if (percentCompleted > 60 && percentCompleted < 80) {
refreshInterval = refreshInterval + 10;
} else if (percentCompleted > 90) {
refreshInterval = 200;
}
step++;
if (step >= steps) {
$timeout.cancel(scope.timoutId);
num = number;
e.textContent = number;
if (number > lastNumberSlowCount) {
slowCounter();
}
} else {
e.textContent = Math.round(num);
counter();
}
}, refreshInterval);
};
counter();
return true;
}
};
});

Related

gulpuglify error how to convert code to es5

I am getting this error while trying to push my code to staging enviroment:
throw er; // Unhandled 'error' event
^
GulpUglifyError: unable to minify JavaScript
Is there any way to convert this code to ES5, I have no idea where to start or what the error is? Can you help me please?
//animated number counter
var stats = document.querySelectorAll(".counter");
stats.forEach(stat => {
var patt = /(\D+)?(\d+)(\D+)?(\d+)?(\D+)?/;
var time = 1000;
var result = [...patt.exec(stat.textContent)];
var fresh = true;
var ticks;
result.shift();
result = result.filter(res => res != null);
while (stat.firstChild) {
stat.removeChild(stat.firstChild);
}
for (var res of result) {
if (isNaN(res)) {
stat.insertAdjacentHTML("beforeend", `<span>${res}</span>`);
} else {
for (var i = 0; i < res.length; i++) {
stat.insertAdjacentHTML(
"beforeend",
`<span data-value="${res[i]}">
<span>–</span>
${Array(parseInt(res[i]) + 1)
.join(0)
.split(0)
.map(
(x, j) => `
<span>${j}</span>
`
)
.join("")}
</span>`
);
}
}
}
ticks = [...stat.querySelectorAll("span[data-value]")];
var activate = () => {
var top = stat.getBoundingClientRect().top;
var offset = window.innerHeight * 0.8;
setTimeout(() => {
fresh = false;
}, time);
if (top < offset) {
setTimeout(() => {
for (var tick of ticks) {
var dist = parseInt(tick.getAttribute("data-value")) + 1;
tick.style.transform = `translateY(-${dist * 100}%)`;
}
}, fresh ? time : 0);
window.removeEventListener("scroll", activate);
}
};
window.addEventListener("scroll", activate);
activate();
});

calling a controller function - angularjs

Want to call a controller function from a directive tag.
Demo : https://jsfiddle.net/6qqfv61k/
when clicked on 'Export to Excel' i want to call dataToExport() from appCtrl as data is available to export.Any inputs?
html:
<div ng-controller="appCtrl">
</div>
<div excel-export export-data="exportData" file-name="{{fileName}}"></div>
js code:
var app = angular.module('myApp', []);
app.controller('appCtrl', ['$scope', function($scope) {
$scope.dataToExport = function(){
$scope.jsonToExport = [
{
"col1data": "1",
"col2data": "Fight Club",
"col3data": "Brad Pitt"
},
{
"col1data": "2",
"col2data": "Matrix (Series)",
"col3data": "Keanu Reeves"
},
{
"col1data": "3",
"col2data": "V for Vendetta",
"col3data": "Hugo Weaving"
}
];
// Prepare Excel data:
$scope.fileName = "report";
$scope.exportData = [];
// Headers:
$scope.exportData.push(["#", "Movie", "Actor"]);
// Data:
angular.forEach($scope.jsonToExport, function(value, key) {
$scope.exportData.push([value.col1data, value.col2data, value.col3data]);
});
}
}]);
//directive
Use & in the scope option of the directive. & bindings are ideal for binding callback functions to directive. Pass function to the directive as callback
Move the directive inside controller scope
<div ng-controller="appCtrl">
<div excel-export export-data="exportData" file-name="{{fileName}}" call-back="dataToExport()"></div>
</div>
Directive
.directive('excelExport',
function () {
return {
restrict: 'A',
scope: {
fileName: "#",
data: "&exportData",
callBack: "&"
},..
invoke callBack() in the click method of the directive
scope.download = function() {
scope.callBack();
....
}
you can define dataToExport into directives scope function. please take a look
<div ng-controller="appCtrl">
<div excel-export export-data="exportData" export="dataToExport()" file-name="{{fileName}}"></div>
</div>
app
.directive('excelExport',
function () {
return {
restrict: 'A',
scope: {
fileName: "#",
data: "&exportData",
dataToExport: '&export'
},
replace: true,
template: '<button class="btn btn-primary btn-ef btn-ef-3 btn-ef-3c mb-10" ng-click="download()">Export to Excel <i class="fa fa-download"></i></button>',
link: function (scope, element) {
scope.download = function() {
scope.dataToExport();
function datenum(v, date1904) {
if(date1904) v+=1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
};
function getSheet(data, opts) {
var ws = {};
var range = {s: {c:10000000, r:10000000}, e: {c:0, r:0 }};
for(var R = 0; R != data.length; ++R) {
for(var C = 0; C != data[R].length; ++C) {
if(range.s.r > R) range.s.r = R;
if(range.s.c > C) range.s.c = C;
if(range.e.r < R) range.e.r = R;
if(range.e.c < C) range.e.c = C;
var cell = {v: data[R][C] };
if(cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({c:C,r:R});
if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.t = 'n'; cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if(range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
};
function Workbook() {
if(!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
var wb = new Workbook(), ws = getSheet(scope.data());
/* add worksheet to workbook */
wb.SheetNames.push(scope.fileName);
wb.Sheets[scope.fileName] = ws;
var wbout = XLSX.write(wb, {bookType:'xlsx', bookSST:true, type: 'binary'});
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), scope.fileName+'.xlsx');
};
}
};
}
);

Not able to get ng-bind-html to work

Problem: I am trying to use ng-bind-html but I am getting the following errors on the console:
The following is the controller where I am calling ngSanitize:
and using the following file:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-sanitize.js"></script>
In my form, I do the following to use ng-bind-html. So when I try to see my results, it is still rendering the &rather then &:
<div ng-bind-html="e.Specialty"></div>
and the following is what occurs in the Specialty:
Any help would be appreciated.
#lealceldeiro: Here is the controller in which I am trying to implement your suggestion but not sure where I will add it:
(
function(){
var $scope, $location;
var indexApp = angular.module('indexApp',['ui.bootstrap', 'ngSanitize']);
indexApp.controller('IndexController',function($scope,$sce,$http,$location,anchorSmoothScroll){
$scope.Lang = 'initVal';
$scope.ShowResults = false;
$scope.ShowDesc = true;
$scope.NoResults = false;
$scope.currentPage = 1;
$scope.maxPageNumbersToShow = 10;
$scope.formModel = {};
$scope.searchMode = 0;
$scope.miles = [{'value':'5'},{'value':'10'},{'value':'15'},{'value':'20' }];
$scope.Specialties = [{'value':'Family practice'},{'value':'General practice'},{'value':'Internal medicine'},{'value':'Pediatrics'}];
$scope.Gender = [{'value':'Male'},{'value':'Female'}];
$scope.Languages = {};
$scope.Cities = {};
//$scope.lastAction = '';
$scope.searchParam = {};
$("input").removeAttr('disabled');
$scope.searchParam.Distance = $scope.miles[0];
$scope.GetCurrentZip = function (){
try{
var lon, lat;
// console.log('starting geoposition code.');
if("geolocation" in navigator){
window.navigator.geolocation.getCurrentPosition(function(pos){
lat = pos.coords.latitude.toFixed(3);
lon = pos.coords.longitude.toFixed(3);
// console.log(lat + ' ' + lon);
$http.get("/Brokers-en-us/includes/remote/ReturnCurrentZipcode.cfm?Lat=" + lat + "&Lon=" + lon)
.then(function(response){
$scope.searchParam.Zip = response.data;
})
})
}
else{ console.log('No geolocation'); }
}
catch(err) { console.log(err.message); }
}
$scope.GetCityList = function (){
try{
$http.get("/Brokers-en-us/includes/remote/ReturnCityList.cfm")
.then(function(response){
$scope.Cities = response.data.Cities;
})
}
catch(err){}
}
$scope.GetLangList = function (){
try{
$http.get("/Brokers-en-us/includes/remote/ReturnLangList.cfm")
.then(function(response){
$scope.Languages = response.data.Languages;
})
}
catch(err){}
}
$scope.SearchProvider = function(searchParam){
try{
//debugger;
$scope.searchMode = 1;
var queryString='';
if($scope.formModel && $scope.formModel !== searchParam){
$scope.resultsCount = 0;
currentPage = 1;
}
if(searchParam){
//debugger;
$scope.formModel = searchParam;
for(var param in searchParam){
if(searchParam.hasOwnProperty(param)){
var paramValue = searchParam[param].value ? searchParam[param].value : searchParam[param];
if (paramValue.length > 0)
queryString += param + '=' + paramValue + '&';
}
}
}
console.log(queryString);
queryString= '?' + queryString + 'currentpage=' + $scope.currentPage;
$http.get("/Brokers-en-us/includes/remote/ReturnProvidersList.cfm" + queryString)
.then(function(response){
$scope.providers = response.data.provider;
$scope.resultsCount = response.data.rowCount;
if (!$scope.providers){
$scope.NoResults = true;
$scope.ShowResults = false;
$scope.ShowDesc = false;
}
else{
$scope.NoResults = false;
$scope.ShowResults = true;
$scope.ShowDesc = false;
}
})
}
catch(err){ alert('No response.: ' + err.message); }
}
/*Testing purposes*/
$scope.clearTopForm = function(searchParam){
//console.log("I clicked this.")
}
/*Clears the drop downs and input fields*/
$scope.$watch('searchParam.Distance', function(newValue, oldValue) {
//debugger;
if(newValue != ''){
//$scope.lastAction = 'miles';
$scope.searchParam.City = '';
$scope.searchParam.Specialty = '';
$scope.searchParam.Gender = '';
}
});
$scope.$watch('searchParam.Zip', function(newValue, oldValue) {
if(newValue != ''){
//$scope.lastAction = 'miles';
$scope.searchParam.Gender = '';
$scope.searchParam.Specialty = '';
$scope.searchParam.City = '';
}
});
$scope.cityChange = function(){
//debugger;
if($scope.searchParam.City != ''){
//$scope.lastAction = 'city';
$scope.searchParam.Distance = '';
$scope.searchParam.Zip = '';
}
}
$scope.specialtyChange = function(){
//debugger;
if($scope.searchParam.Specialty != ''){
//$scope.lastAction = 'specialty';
$scope.searchParam.Distance = '';
$scope.searchParam.Zip = '';
}
}
$scope.genderChange = function(){
//debugger;
if($scope.searchParam.Gender != ''){
//$scope.lastAction = 'gender';
$scope.searchParam.Distance = '';
$scope.searchParam.Zip = '';
}
}
$scope.$watchGroup(['currentPage'], function(){
try{
if($scope.searchMode == 1){
$scope.SearchProvider($scope.formModel);
}
}
catch(err){}
});
$scope.GetCityList();
$scope.GetLangList();
$scope.GetCurrentZip();
$scope.gotoElement = function (eID){
//http://jsfiddle.net/brettdewoody/y65G5/
// set the location.hash to the id of
// the element you wish to scroll to.
//$location.hash('bottom');
// call $anchorScroll()
var browserWidth = screen.availWidth;
if (browserWidth < 768)
anchorSmoothScroll.scrollTo(eID);
};
});
indexApp.service('anchorSmoothScroll', function(){
this.scrollTo = function(eID) {
// This scrolling function
// is from http://www.itnewb.com/tutorial/Creating-the-Smooth-Scroll-Effect-with-JavaScript
var startY = currentYPosition();
var stopY = elmYPosition(eID);
var distance = stopY > startY ? stopY - startY : startY - stopY;
if (distance < 100) {
scrollTo(0, stopY); return;
}
var speed = Math.round(distance / 100);
if (speed >= 20) speed = 20;
var step = Math.round(distance / 25);
var leapY = stopY > startY ? startY + step : startY - step;
var timer = 0;
if (stopY > startY) {
for ( var i=startY; i<stopY; i+=step ) {
setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
leapY += step; if (leapY > stopY) leapY = stopY; timer++;
} return;
}
for ( var i=startY; i>stopY; i-=step ) {
setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
}
function currentYPosition() {
// Firefox, Chrome, Opera, Safari
if (self.pageYOffset) return self.pageYOffset;
// Internet Explorer 6 - standards mode
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
// Internet Explorer 6, 7 and 8
if (document.body.scrollTop) return document.body.scrollTop;
return 0;
}
function elmYPosition(eID) {
var elm = document.getElementById(eID);
var y = elm.offsetTop;
var node = elm;
while (node.offsetParent && node.offsetParent != document.body) {
node = node.offsetParent;
y += node.offsetTop;
} return y;
}
};
});
indexApp.directive('allowPattern',[allowPatternDirective]);
indexApp.directive('popPopup',[describePopup]);
indexApp.directive('pop', function pop ($tooltip, $timeout) {
var tooltip = $tooltip('pop', 'pop', 'event');
var compile = angular.copy(tooltip.compile);
tooltip.compile = function (element, attrs) {
var first = true;
attrs.$observe('popShow', function (val) {
if (JSON.parse(!first || val || false)) {
$timeout(function(){
element.triggerHandler('event');
});
}
first = false;
});
return compile(element, attrs);
};
return tooltip;
});
indexApp.filter('PhoneNumber', function(){
return function(phoneNumber){
var dash = '-';
var openParen = '(';
var closeParen = ') ';
if(phoneNumber){
var pn = phoneNumber;
pn = [pn.slice(0, 6), dash, pn.slice(6)].join('');
pn = openParen + [pn.slice(0, 3), closeParen, pn.slice(3)].join('');
return pn;
}
return phoneNumber;
}
});
indexApp.filter('Zip', function(){
return function(zipcode){
var dash = '-';
if(zipcode && zipcode.length > 5){
var zc = zipcode;
zc = [zc.slice(0, 5), dash, zc.slice(5)].join('');
return zc;
}
return zipcode;
}
});
function allowPatternDirective(){
return{
restrict: "A",
compile: function(tElement, tAttrs){
return function(scope, element, attrs){
element.bind("keypress", function(event){
var keyCode = event.which || event.keyCode;
var keyCodeChar = String.fromCharCode(keyCode);
if(!keyCodeChar.match(new RegExp(attrs.allowPattern, "i"))){
event.preventDefault();
return false;
}
});
}
}
}
}
function describePopup(){
return {
restrict: 'EA',
replace: true,
scope: { title: '#', content: '#', placement: '#', animation: '&', isOpen: '&' },
templateUrl: 'template/popover/popover.html'
};
}
})();
(function($) {
// #todo Document this.
$.extend($,{ placeholder: {
browser_supported: function() {
return this._supported !== undefined ?
this._supported :
( this._supported = !!('placeholder' in $('<input type="text">')[0]) );
},
shim: function(opts) {
var config = {
color: '#888',
cls: 'placeholder',
selector: 'input[placeholder], textarea[placeholder]'
};
$.extend(config,opts);
return !this.browser_supported() && $(config.selector)._placeholder_shim(config);
}
}});
$.extend($.fn,{
_placeholder_shim: function(config) {
function calcPositionCss(target)
{
var op = $(target).offsetParent().offset();
var ot = $(target).offset();
return {
top: ot.top - op.top,
left: ot.left - op.left,
width: $(target).width()
};
}
function adjustToResizing(label) {
var $target = label.data('target');
if(typeof $target !== "undefined") {
label.css(calcPositionCss($target));
$(window).one("resize", function () { adjustToResizing(label); });
}
}
return this.each(function() {
var $this = $(this);
if( $this.is(':visible') ) {
if( $this.data('placeholder') ) {
var $ol = $this.data('placeholder');
$ol.css(calcPositionCss($this));
return true;
}
var possible_line_height = {};
if( !$this.is('textarea') && $this.css('height') != 'auto') {
possible_line_height = { lineHeight: $this.css('height'), whiteSpace: 'nowrap' };
}
var isBorderBox = ($this.css('box-sizing') === 'border-box');
var isTextarea = $this.is('textarea');
var ol = $('<label />')
.text($this.attr('placeholder'))
.addClass(config.cls)
.css($.extend({
position:'absolute',
display: 'inline',
'float':'none',
overflow:'hidden',
textAlign: 'left',
color: config.color,
cursor: 'text',
paddingTop: !isTextarea && isBorderBox ? '0' : $this.css('padding-top'),
paddingRight: $this.css('padding-right'),
paddingBottom: !isTextarea && isBorderBox ? '0' : $this.css('padding-bottom'),
paddingLeft: $this.css('padding-left'),
fontSize: $this.css('font-size'),
fontFamily: $this.css('font-family'),
fontStyle: $this.css('font-style'),
fontWeight: $this.css('font-weight'),
textTransform: $this.css('text-transform'),
backgroundColor: 'transparent',
zIndex: 99,
}, possible_line_height))
.css(calcPositionCss(this))
.attr('for', this.id)
.data('target',$this)
.click(function(){
if (!$(this).data('target').is(':disabled')) {
$(this).data('target').focus();
}
})
.insertBefore(this);
$this
.data('placeholder', ol)
.on('keydown', function () {
ol.hide();
})
.on('blur change', function () {
ol[$this.val().length ? 'hide' : 'show']();
})
.triggerHandler('blur');
$(window).one("resize", function () { adjustToResizing(ol); });
}
});
}
});
})(jQuery);
jQuery(document).add(window).bind('ready load', function() {
if (jQuery.placeholder) {
jQuery.placeholder.shim();
}
});
When you use ng-bind-html, AngularJS sometimes consider some contents as unsafe (as your case), so you need to use the $sce service in order to "mark" this content as safe (to be used) like this:
$sce.trustAsHtml("CLINICAL & SOCIAL"); (See demo below)
From $sanitize
The input is sanitized by parsing the HTML into tokens. All safe
tokens (from a whitelist) are then serialized back to properly escaped
html string. This means that no unsafe input can make it into the
returned string.
In this case the "unsafe" part is &
angular
.module('app', [])
.controller('ctrl', ctrl);
function ctrl($scope, $sce) {
$scope.Specialty = $sce.trustAsHtml("CLINICAL & SOCIAL");
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-sanitize.js"></script>
<div ng-app="app" ng-controller="ctrl">
Specialty: <span ng-bind-html="Specialty"></span>
</div>

How to call a custom directive from angular controller

I have a directive which is depending on some input. I want to call that directive from angular controller when ever that input changed. Here is my directive.
var app = angular.module('App', ['ui.bootstrap']);
app.controller('fcController', function($scope, fcService, $uibModal) {
$scope.formatType = '1';
});
app.directive('fcsaNumber', function($filter) {
var addCommasToInteger, controlKeys, hasMultipleDecimals, isNotControlKey, isNotDigit, isNumber, makeIsValid, makeMaxDecimals, makeMaxDigits, makeMaxNumber, makeMinNumber;
isNumber = function(val) {
return !isNaN(parseFloat(val)) && isFinite(val);
};
isNotDigit = function(which) {
return which < 45 || which > 57 || which === 47;
};
controlKeys = [0, 8, 13];
isNotControlKey = function(which) {
return controlKeys.indexOf(which) === -1;
};
hasMultipleDecimals = function(val) {
return (val != null) && val.toString().split('.').length > 2;
};
makeMaxDecimals = function(maxDecimals) {
var regexString, validRegex;
if (maxDecimals > 0) {
regexString = "^-?\\d*\\.?\\d{0," + maxDecimals + "}$";
} else {
regexString = "^-?\\d*$";
}
validRegex = new RegExp(regexString);
return function(val) {
return validRegex.test(val);
};
};
makeMaxNumber = function(maxNumber) {
return function(val, number) {
return number <= maxNumber;
};
};
makeMinNumber = function(minNumber) {
return function(val, number) {
return number >= minNumber;
};
};
makeMaxDigits = function(maxDigits) {
var validRegex;
validRegex = new RegExp("^-?\\d{0," + maxDigits + "}(\\.\\d*)?$");
return function(val) {
return validRegex.test(val);
};
};
makeIsValid = function(options) {
var validations;
validations = [];
if (options.maxDecimals != null) {
validations.push(makeMaxDecimals(options.maxDecimals));
}
if (options.max != null) {
validations.push(makeMaxNumber(options.max));
}
if (options.min != null) {
validations.push(makeMinNumber(options.min));
}
if (options.maxDigits != null) {
validations.push(makeMaxDigits(options.maxDigits));
}
return function(val) {
var i, number, _i, _ref;
if (!isNumber(val)) {
return false;
}
if (hasMultipleDecimals(val)) {
return false;
}
number = Number(val);
for (i = _i = 0, _ref = validations.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
if (!validations[i](val, number)) {
return false;
}
}
return true;
};
};
addCommasToInteger = function(val) {
var commas, decimals, wholeNumbers;
decimals = val.indexOf('.') == -1 ? '.00' : val.replace(/^\d+(?=\.)/, '');
wholeNumbers = val.replace(/(\.\d+)$/, '');
commas = wholeNumbers.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
return "" + commas + decimals.substring(0, 3);
};
return {
restrict: 'A',
require: 'ngModel',
scope: {
options: '#fcsaNumber',
},
link: function(scope, elem, attrs, ngModelCtrl) {
var isValid, options;
options = {};
if (scope.options != null) {
options = scope.$eval(scope.options);
}
isValid = makeIsValid(options);
ngModelCtrl.$parsers.unshift(function(viewVal) {
var noCommasVal;
noCommasVal = viewVal.replace(/,/g, '');
if (isValid(noCommasVal) || !noCommasVal) {
ngModelCtrl.$setValidity('fcsaNumber', true);
return noCommasVal;
} else {
ngModelCtrl.$setValidity('fcsaNumber', false);
return void 0;
}
});
ngModelCtrl.$formatters.push(function(val) {
if ((options.nullDisplay != null) && (!val || val === '')) {
return options.nullDisplay;
}
if ((val == null) || !isValid(val)) {
return val;
}
ngModelCtrl.$setValidity('fcsaNumber', true);
val = addCommasToInteger(val.toString());
if (options.key == 1) {
options.prepend = 'S/.';
}
if (options.key == 2) {
options.prepend = '$';
}
if (options.prepend != null) {
val = "" + options.prepend + val;
}
if (options.append != null) {
val = "" + val + options.append;
}
return val;
});
elem.on('blur', function() {
var formatter, viewValue, _i, _len, _ref;
viewValue = ngModelCtrl.$modelValue;
if ((viewValue == null) || !isValid(viewValue)) {
return;
}
_ref = ngModelCtrl.$formatters;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
formatter = _ref[_i];
viewValue = formatter(viewValue);
}
ngModelCtrl.$viewValue = viewValue;
return ngModelCtrl.$render();
});
elem.on('focus', function() {
var val;
val = elem.val();
if (options.prepend != null) {
val = val.replace(options.prepend, '');
}
if (options.append != null) {
val = val.replace(options.append, '');
}
elem.val(val.replace(/,/g, ''));
return elem[0].select();
});
if (options.preventInvalidInput === true) {
return elem.on('keypress', function(e) {
if (isNotDigit(e.which && isNotControlKey(e.which))) {
return e.preventDefault();
}
});
}
}
};
});
HTML:
<input type ="text" ng-model ="currency" fcsa-number="{key : {{formatType}}}">
Here $scope.formatType = '1'; is the input. If this formatType changed then That directive need to call. One friend suggested me this
link: function(scope,elem,attr,ctrl){
scope.$watch('fcsaNumber', function(){
// do your stuff
});
but it is not calling my directive manually.
even I have tried with
.controller("ctrl", function($scope) {
$scope.$watch('formatType', function() {
$scope.$broadcast("call_dir")
})
})
return {
restrict: 'A',
require: 'ngModel',
scope: {
options: '#fcsaNumber',
},
link: function(scope, elem, attrs, ngModelCtrl) {
var isValid, options;
options = {};
scope.$on('call_dir', function(ev) {
//your code
})
};
You need to watch the value that is going to change in your controller. In your case it is formatType.
You should try to use this expression in your isolated scope:
scope: {
options: '=fcsaNumber',
}
And if you want the event broadcasting to work, i.e. the $scope.$bradcast approach, then make sure your directive is a child of the controller scope in the scope hierarchy. Else a easier way (but not always recommended) would be to broadcast your event from $rootScope.
So something like this should also work (with your event based solution):
.controller("ctrl", function($scope, $rootScope) {
$scope.$watch('formatType', function() {
$rootScope.$broadcast("call_dir")
})
})

Progressbar in angular

I want to make Progressbar in Angular.js in decimal format, simple format, times based Progressbar. Someone could pls help !
E.g.
Start Timer {{ counter }}/{{ max }} = {{ (counter/max)*100 }}%
Start Timer 20/30 = 66.66666666666666%
Here is example.js:
angular.module('plunker', ['ui.bootstrap']);
var ProgressDemoCtrl = function ($scope) {
$scope.max = 200;
$scope.random = function () {
var value = Math.floor((Math.random() * 100) + 1);
var type;
if (value < 25) {
type = 'success';
} else if (value < 50) {
type = 'info';
} else if (value < 75) {
type = 'warning';
} else {
type = 'danger';
}
$scope.showWarning = (type === 'danger' || type === 'warning');
$scope.dynamic = value;
$scope.type = type;
};
var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('ProgressDemoCtrl', function ($scope) {
$scope.value = 40;
$scope.state = "progress-bar-success";
$scope.myStyle = {width: $scope.value + '%'};
});
$scope.random();
$scope.randomStacked = function() { $scope.stacked = [];
var types = ['success', 'info', 'warning', 'danger']; for (var i = 0, n = Math.floor((Math.random() * 4) + 1); i < n; i++) { var index = Math.floor((Math.random() * 4));
$scope.stacked.push({ value: Math.floor((Math.random() * 30) + 1),
type: types[index] }); } }; $scope.randomStacked(); };
var app = angular.module('progressApp',['nprogress']); var MainCtrl = function($scope,ngProgress){ }
I use this round progress ba directive, works pretty well:
http://www.youtube.com/watch?v=w2qrYL0Le24
https://github.com/angular-directives/angular-round-progress-directive
If you need a rectangular one give me a buzz I, have a custom directive implemented.
If you need two decimal numbers you only have to adjust the font size.
Test with two decimals:
Code to change (configuring ang:roundprogress directive)
data-round-progress-label-font="80pt Arial"
Whole markup
<div ang:round:progress data-round-progress-model="roundProgressData"
data-round-progress-width="500"
data-round-progress-height="500"
data-round-progress-outer-circle-width="40"
data-round-progress-inner-circle-width="10"
data-round-progress-outer-circle-radius="200"
data-round-progress-inner-circle-radius="140"
data-round-progress-label-font="80pt Arial"
data-round-progress-outer-circle-background-color="#505769"
data-round-progress-outer-circle-foreground-color="#12eeb9"
data-round-progress-inner-circle-color="#505769"
data-round-progress-label-color="#fff"></div>