To convert currency from US to UK in AngularJS - angularjs

I tried this code to display but I need AngularJS to automatically convert currency:
<div ng-controller="ctrl">
default currency symbol ($): {{0.00 | currency}}
custom currency symbol (£): {{0.00 | currency:"£"}}
</div>
<script src="index.js"></script>
<script src="uk-locale.js"></script>

As #Andrey said, you should build your own custom filter to handle the currency conversion.
Here's a simple demo of how I would build such a thing:
angular.module('myModule').filter('currency', function() {
var defaultCurrency = '$';
return function(input, currencySymbol) {
var out = "";
currencySymbol = currencySymbol || defaultCurrency;
switch(currencySymbol) {
case '£':
out = 0.609273137 * input; // google
break;
default:
out = input;
}
return out + ' ' + currencySymbol;
}
});
check the online demo

AngularJs currencyFilter just formats output. If you want actually convert currency, you need to make custom filter, for example.
Here is possible example:
angular.module('myFilter', []).filter('currencyConverter', [function() {
function convert(inputValue, currecyId) {
// Your conversion code goes here
}
return function(inputValue, currencyId) {
return convert(inputValue, currencyId);
}
});

Related

AngularJS - Using custom filter in ng-repeat for prefixing comma

Need to remove comma if value is empty works good if I have value
present at start or middle; But same doesn't work in this scenario.
app.filter('isCSV', function() {
return function(data) {
return (data !== '') ? data + ', ' : '';
};
});
Angularjs ng repeat for addressline - Plunker
I would instead operate on arrays of properties and use a pair of filters, one to remove empty values, and one to join the array.
This way it's very explicit about what properties you are displaying.
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="item in details">
{{ [ item.address0, item.address1, item.address2, item.address3] | removeEmpties | joinBy:', ' }}
</li>
</ul>
</body>
With the following filters:
app.filter('removeEmpties', function () {
return function (input,delimiter) {
return (input || []).filter(function (i) { return !!i; });
};
});
app.filter('joinBy', function () {
return function (input,delimiter) {
return (input || []).join(delimiter || ',');
};
});
Here's the updated Plunkr
Tricky but should work in your case Also no filter need
{{ item.address0 }} <span ng-if="item.address1">,
</span> {{ item.address1}}<span ng-if="item.address2">,</span>{{
item.address2}}
<span ng-if="item.address3">,</span>{{ item.address3}}
Here is working example
I would prefer writing a function instead of adding a filter so many times.
$scope.mergeAddresses = function(item) {
var address = item.address0;
[1,2,3].forEach(function(i) {
var add = item["address"+i];
if (!add) return;
address += (address ? ", " : "") + add;
});
if (address) address += ".";
return address;
}
Plunker

Filter on string

I'm learning angularjs and got an exercise that wants me to Use angular filter to show a title in the following format :
first letter of each word upper cased and each other letter lower cased also
remove any non-English letters from the title. For example:
A title with the name
“##THIS is a Title!!”
should be changed to
“This Is A Title”
I'm getting each title from an array of objects and present them like so.
<div ng-repeat="obj in objects">
<h3 class="panel-title">{{obj.Title}}</h3>
</div>
i understand that filter receives an array and filters through it . but this requires me to filter the string.
been searching for a while, how can i do this?
please refer below fiddle
http://jsfiddle.net/HB7LU/28315/
<div ng-controller="MyCtrl">
Hello, {{ name | ordinal|capitalize }}
</div>
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Super hero!!12##3';
}
myApp.filter('ordinal', function() {
// Create the return function
// set the required parameter name to **number**
return function(strTitle) {
// Ensure that the passed in data is a number
// If the data is not a number or is less than one (thus not having a cardinal value) return it unmodified.
strTitle=strTitle.replace(/[^a-zA-Z ]/g, "")
return strTitle;
}
});
myApp.filter('capitalize', function() {
return function(input){
if(input.indexOf(' ') !== -1){
var inputPieces,
i;
input = input.toLowerCase();
inputPieces = input.split(' ');
for(i = 0; i < inputPieces.length; i++){
inputPieces[i] = capitalizeString(inputPieces[i]);
}
return inputPieces.toString().replace(/,/g, ' ');
}
else {
input = input.toLowerCase();
return capitalizeString(input);
}
function capitalizeString(inputString){
return inputString.substring(0,1).toUpperCase() + inputString.substring(1);
}
};
});
angular.module('app', []).filter('myFilter', function(){
return function(input){
if(!input)
return;
var out = '';
var english = /^[A-Za-z0-9 ]*$/;
for(var letter of input)
if(english.test(letter))
out += letter;
var result = '';
for(var i = 0; i < out.length; i++)
result += out[i][(i === 0 || out[i-1] == ' ') ? 'toUpperCase' : 'toLowerCase']();
return result;
}
})
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<body ng-app="app">
<input ng-init='text="##THIS is a Title!!"' type='text' ng-model='text'>
<p>{{text | myFilter}}</p>
</body>

Angular JS currency filter showing same format for ₹ and $

I have a scenario where i should be able to format the currency dynamically. I'm using angular currency filter.
Here is my code
<div ng-app="myApp" ng-controller="costCtrl">
<p>Rupee: {{ price | currency : "₹"}}</p>
<p>Dollar: {{ price | currency : "$"}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('costCtrl', function($scope) {
$scope.price = 5800000;
});
In the above code i'm using two types of currencies RUPEE and DOLLAR but it is showing same for the both currencies.
here is my output for above code
RUPEE : ₹5,800,000
DOLLAR: $5,800,000
below is my expected output
RUPEE : ₹58,00,000
DOLLAR: $5,800,000
please help me in this. Thanks in advance
I need a generic solution for all currency formats not only for indian rupee. Like €1.234.567,89 EUR
Here EUR currency format is different they use . as thousand separators and , as decimal separators.
Can i have any suggestions for implementing this.
You have to write your own currency convertor, below is a working fiddle:
.filter('currency', function() {
var defaultCurrency = '$';
return function(input, currencySymbol) {
var out = "";
currencySymbol = currencySymbol || defaultCurrency;
switch(currencySymbol) {
case '₹':
out = 67 * input;
break;
default:
out = input;
}
return out + ' ' + currencySymbol;
}
});
http://jsfiddle.net/bvgkwczd/

Highlighting a filtered result in AngularJS

I'm using a ng-repeat and filter in angularJS like the phones tutorial but I'd like to highlight the search results in the page. With basic jQuery I would have simply parsed the page on key up on the input, but I'm trying to do it the angular way. Any ideas ?
My code :
<input id="search" type="text" placeholder="Recherche DCI" ng-model="search_query" autofocus>
<tr ng-repeat="dci in dcis | filter:search_query">
<td class='marque'>{{dci.marque}} ®</td>
<td class="dci">{{dci.dci}}</td>
</tr>
In did that for AngularJS v1.2+
HTML:
<span ng-bind-html="highlight(textToSearchThrough, searchText)"></span>
JS:
$scope.highlight = function(text, search) {
if (!search) {
return $sce.trustAsHtml(text);
}
return $sce.trustAsHtml(text.replace(new RegExp(search, 'gi'), '<span class="highlightedText">$&</span>'));
};
CSS:
.highlightedText {
background: yellow;
}
angular ui-utils supports only one term. I'm using the following filter rather than a scope function:
app.filter('highlight', function($sce) {
return function(str, termsToHighlight) {
// Sort terms by length
termsToHighlight.sort(function(a, b) {
return b.length - a.length;
});
// Regex to simultaneously replace terms
var regex = new RegExp('(' + termsToHighlight.join('|') + ')', 'g');
return $sce.trustAsHtml(str.replace(regex, '<span class="match">$&</span>'));
};
});
And the HTML:
<span ng-bind-html="theText | highlight:theTerms"></span>
Try Angular UI
Filters -> Highlite (filter).
There is also Keypress directive.
index.html
<!DOCTYPE html>
<html>
<head>
<script src="angular.js"></script>
<script src="app.js"></script>
<style>
.highlighted { background: yellow }
</style>
</head>
<body ng-app="Demo">
<h1>Highlight text using AngularJS.</h1>
<div class="container" ng-controller="Demo">
<input type="text" placeholder="Search" ng-model="search.text">
<ul>
<!-- filter code -->
<div ng-repeat="item in data | filter:search.text"
ng-bind-html="item.text | highlight:search.text">
</div>
</ul>
</div>
</body>
</html>
app.js
angular.module('Demo', [])
.controller('Demo', function($scope) {
$scope.data = [
{ text: "<< ==== Put text to Search ===== >>" }
]
})
.filter('highlight', function($sce) {
return function(text, phrase) {
if (phrase) text = text.replace(new RegExp('('+phrase+')', 'gi'),
'<span class="highlighted">$1</span>')
return $sce.trustAsHtml(text)
}
})
Reference : http://codeforgeek.com/2014/12/highlight-search-result-angular-filter/
demo : http://demo.codeforgeek.com/highlight-angular/
I hope my light example will make it easy to understand:
app.filter('highlight', function() {
return function(text, phrase) {
return phrase
? text.replace(new RegExp('('+phrase+')', 'gi'), '<kbd>$1</kbd>')
: text;
};
});
<input type="text" ng-model="search.$">
<ul>
<li ng-repeat="item in items | filter:search">
<div ng-bind-html="item | highlight:search.$"></div>
</li>
</ul>
There is standart Highlight filter in the angular-bootstrap: typeaheadHighlight
Usage
<span ng-bind-html="text | typeaheadHighlight:query"></span>
With scope {text:"Hello world", query:"world"} renders in
<span...>Hello <strong>world</strong></span>
Going off of #uri's answer in this thread, I modified it to work with a single string OR a string array.
Here's the TypeScript version
module myApp.Filters.Highlight {
"use strict";
class HighlightFilter {
//This will wrap matching search terms with an element to visually highlight strings
//Usage: {{fullString | highlight:'partial string'}}
//Usage: {{fullString | highlight:['partial', 'string, 'example']}}
static $inject = ["$sce"];
constructor($sce: angular.ISCEService) {
// The `terms` could be a string, or an array of strings, so we have to use the `any` type here
/* tslint:disable: no-any */
return (str: string, terms: any) => {
/* tslint:enable */
if (terms) {
let allTermsRegexStr: string;
if (typeof terms === "string") {
allTermsRegexStr = terms;
} else { //assume a string array
// Sort array by length then join with regex pipe separator
allTermsRegexStr = terms.sort((a: string, b: string) => b.length - a.length).join('|');
}
//Escape characters that have meaning in regular expressions
//via: http://stackoverflow.com/a/6969486/79677
allTermsRegexStr = allTermsRegexStr.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Regex to simultaneously replace terms - case insensitive!
var regex = new RegExp('(' + allTermsRegexStr + ')', 'ig');
return $sce.trustAsHtml(str.replace(regex, '<mark class="highlight">$&</mark>'));
} else {
return str;
}
};
}
}
angular
.module("myApp")
.filter("highlight", HighlightFilter);
};
Which translates to this in JavaScript:
var myApp;
(function (myApp) {
var Filters;
(function (Filters) {
var Highlight;
(function (Highlight) {
"use strict";
var HighlightFilter = (function () {
function HighlightFilter($sce) {
// The `terms` could be a string, or an array of strings, so we have to use the `any` type here
/* tslint:disable: no-any */
return function (str, terms) {
/* tslint:enable */
if (terms) {
var allTermsRegexStr;
if (typeof terms === "string") {
allTermsRegexStr = terms;
}
else {
// Sort array by length then join with regex pipe separator
allTermsRegexStr = terms.sort(function (a, b) { return b.length - a.length; }).join('|');
}
//Escape characters that have meaning in regular expressions
//via: http://stackoverflow.com/a/6969486/79677
allTermsRegexStr = allTermsRegexStr.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Regex to simultaneously replace terms - case insensitive!
var regex = new RegExp('(' + allTermsRegexStr + ')', 'ig');
return $sce.trustAsHtml(str.replace(regex, '<mark class="highlight">$&</mark>'));
}
else {
return str;
}
};
}
//This will wrap matching search terms with an element to visually highlight strings
//Usage: {{fullString | highlight:'partial string'}}
//Usage: {{fullString | highlight:['partial', 'string, 'example']}}
HighlightFilter.$inject = ["$sce"];
return HighlightFilter;
})();
angular.module("myApp").filter("highlight", HighlightFilter);
})(Highlight = Filters.Highlight || (Filters.Highlight = {}));
})(Filters = myApp.Filters || (myApp.Filters = {}));
})(myApp|| (myApp= {}));
;
Or if you just want a simple JavaScript implementation without those generated namespaces:
app.filter('highlight', ['$sce', function($sce) {
return function (str, terms) {
if (terms) {
var allTermsRegexStr;
if (typeof terms === "string") {
allTermsRegexStr = terms;
}
else {
// Sort array by length then join with regex pipe separator
allTermsRegexStr = terms.sort(function (a, b) { return b.length - a.length; }).join('|');
}
//Escape characters that have meaning in regular expressions
//via: http://stackoverflow.com/a/6969486/79677
allTermsRegexStr = allTermsRegexStr.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Regex to simultaneously replace terms - case insensitive!
var regex = new RegExp('(' + allTermsRegexStr + ')', 'ig');
return $sce.trustAsHtml(str.replace(regex, '<mark class="highlight">$&</mark>'));
}
else {
return str;
}
};
}]);
EDITED to include a fix that would have previously broken this is someone searched for . or any other character that had meaning in a regular expression. Now those characters get escaped first.
Use ng-class that is applied when the search term is related to the data the element contains.
So on your ng-repeated elements, you'd have ng-class="{ className: search_query==elementRelatedValue}"
which would apply class "className" to elements dynamically when the condition is met.
My solution for highlight, used this with angular-ui-tree element: https://codepen.io/shnigi/pen/jKeaYG
angular.module('myApp').filter('highlightFilter', $sce =>
function (element, searchInput) {
element = element.replace(new RegExp(`(${searchInput})`, 'gi'),
'<span class="highlighted">$&</span>');
return $sce.trustAsHtml(element);
});
Add css:
.highlighted {
color: orange;
}
HTML:
<p ng-repeat="person in persons | filter:search.value">
<span ng-bind-html="person | highlightFilter:search.value"></span>
</p>
And to add search input:
<input type="search" ng-model="search.value">
About the problems with special caracter, I think just escaping you might lose regex search.
What about this:
function(text, search) {
if (!search || (search && search.length < 3)) {
return $sce.trustAsHtml(text);
}
regexp = '';
try {
regexp = new RegExp(search, 'gi');
} catch(e) {
return $sce.trustAsHtml(text);
}
return $sce.trustAsHtml(text.replace(regexp, '<span class="highlight">$&</span>'));
};
An invalid regexp could be user just typing the text:
valid: m
invalid: m[
invalid: m[ô
invalid: m[ôo
valid: m[ôo]
valid: m[ôo]n
valid: m[ôo]ni
valid: m[ôo]nic
valid: m[ôo]nica
What do you think #Mik Cox?
Another proposition:
app.filter('wrapText', wrapText);
function wrapText($sce) {
return function (source, needle, wrap) {
var regex;
if (typeof needle === 'string') {
regex = new RegExp(needle, "gi");
} else {
regex = needle;
}
if (source.match(regex)) {
source = source.replace(regex, function (match) {
return $('<i></i>').append($(wrap).text(match)).html();
});
}
return $sce.trustAsHtml(source);
};
} // wrapText
wrapText.$inject = ['$sce'];
// use like this
$filter('wrapText')('This is a word, really!', 'word', '<span class="highlight"></span>');
// or like this
{{ 'This is a word, really!' | wrapText:'word':'<span class="highlight"></span>' }}
I'm open to criticism ! ;-)
Thanks for asking this as it was something I was dealing with as well.
Two things though:
First, The top answer is great but the comment on it is accurate that highlight() has problem with special characters. That comment suggests using an escaping chain which will work but they suggest using unescape() which is being phased out. What I ended up with:
$sce.trustAsHtml(decodeURI(escape(text).replace(new RegExp(escape(search), 'gi'), '<span class="highlightedText">$&</span>')));
Second, I was trying to do this in a data bound list of URLs. While in the highlight() string, you don't need to data bind.
Example:
<li>{{item.headers.host}}{{item.url}}</li>
Became:
<span ng-bind-html="highlight(item.headers.host+item.url, item.match)"></span>
Was running into problems with leaving them in {{ }} and getting all sorts of errors.
Hope this helps anybody running into the same problems.
If you are using the angular material library there is a built in directive called md-highlight-text
From the documentation:
<input placeholder="Enter a search term..." ng-model="searchTerm" type="text">
<ul>
<li ng-repeat="result in results" md-highlight-text="searchTerm">
{{result.text}}
</li>
</ul>
Link to docs: https://material.angularjs.org/latest/api/directive/mdHighlightText

Removing AngularJS currency filter decimal/cents

Is there a way to remove the decimal/cents from the output of a currency filter? I'm doing something like this:
<div>{{Price | currency}}</div>
Which outputs:
$1,000.00
Instead, I'd like:
$1,000
Can that be done using the currency filter? I know I can prepend a dollar sign onto a number, and I could write my own filter, but I was hoping a simple method exists with the existing currency filter.
Thank you.
Update: as of version 1.3.0 - currencyFilter: add fractionSize as optional parameter, see commit
and updated plunker
{{10 | currency:undefined:0}}
Note that it's the second parameter so you need to pass in undefined to use the current locale currency symbol
Update: Take note that this only works for currency symbols that are displayed before the number.
As of version 1.2.9 it's still hardcoded to 2 decimal places.
Here is a modified version that uses a copy of angular's formatNumber to enable 0 fractionSize for currency.
Normally this should be configurable either in the locale definition or the currencyFilter call but right now(1.0.4) it's hardcoded to 2 decimal places.
Custom filter:
myModule.filter('noFractionCurrency',
[ '$filter', '$locale',
function(filter, locale) {
var currencyFilter = filter('currency');
var formats = locale.NUMBER_FORMATS;
return function(amount, currencySymbol) {
var value = currencyFilter(amount, currencySymbol);
var sep = value.indexOf(formats.DECIMAL_SEP);
if(amount >= 0) {
return value.substring(0, sep);
}
return value.substring(0, sep) + ')';
};
} ]);
Template:
<div>{{Price | noFractionCurrency}}</div>
Example:
Demo
Update: fixed a bug when handling negative values
The question seems to be pretty old and the given answers are nice. However, there is another alternative solution which can also help (which I use in my projects).
This is working very well with currency symbols prefixing as well as suffixing the number for positive and negative values.
Custom filter:
angular.module('your-module', [])
.filter('nfcurrency', [ '$filter', '$locale', function ($filter, $locale) {
var currency = $filter('currency'), formats = $locale.NUMBER_FORMATS;
return function (amount, symbol) {
var value = currency(amount, symbol);
return value.replace(new RegExp('\\' + formats.DECIMAL_SEP + '\\d{2}'), '')
}
}])
Template:
<div>{{yourPrice| nfcurrency}}</div>
Examples for different locales:
10.00 (en-gb) -> £10
20.00 (en-us) -> $20
-10.00 (en-us) -> ($10)
30.00 (da-dk) -> 30 kr
-30.00 (da-dk) -> -30 kr
Please have a look at live demo for US dollars and Danish Krone.
Update
Please note that this workaround is good for AngularJS 1.2 and earlier releases of the library. As of AngularJS 1.3 you can use currency formatter with third parameter specifying fraction size - "Number of decimal places to round the amount to".
Note that in order to use default currency format coming from AngularJS localization, you would have to use currency symbol (second parameter) set to undefined (null or empty will NOT work). Example in demos for US dollars and Danish Krone.
Another thing that is worth considering is if you know you only have one locale or one type of currency, you could put the currency symbol before the number and then use the number filter like so (for US currency).
${{Price | number:0}}
More of a quick fix solution if you don't want to throw in a new filter and only have one currency.
It's late but might be it can help some one
{{value | currency : 'Your Symbol' : decimal points}}
So let's see some examples with output
{{10000 | currency : "" : 0}} // 10,000
{{10000 | currency : '$' : 0}} // $10,000
{{10000 | currency : '$' : 2}} // $10,000.00
{{10000 | currency : 'Rs.' : 2}} // Rs.10,000.00
{{10000 | currency : 'USD $' : 2}} // USD $10,000.00
{{10000 | currency : '#' : 3}} // #10,000.000
{{10000 | currency : 'ANYTHING: ' : 5}} // ANYTHING: 10,000.00000
See the demo
This is another similar solution, but it removes .00 decimal, but leaves any other decimal amount.
$10.00 to $10
$10.20 to $10.20
app.filter('noFractionCurrency', [ '$filter', '$locale', function(filter, locale) {
var currencyFilter = filter('currency');
var formats = locale.NUMBER_FORMATS;
return function(amount, currencySymbol) {
amount = amount ? (amount*1).toFixed(2) : 0.00;
var value = currencyFilter(amount, currencySymbol);
// split into parts
var parts = value.split(formats.DECIMAL_SEP);
var dollar = parts[0];
var cents = parts[1] || '00';
cents = cents.substring(0,2)=='00' ? cents.substring(2) : '.'+cents; // remove "00" cent amount
return dollar + cents;
};
}]);
Solution for angular version < 1.3,
if you use i18n the simplest way is:
$filter('number')(x,0) + ' ' +$locale.NUMBER_FORMATS.CURRENCY_SYM;
This way you have the number formatted with correct separators and currency symbol based on locale.
Another solution, this one removes the trailing zeros and finds the proper currency symbol for the most common currencies:
{{10.00|money:USD}} to $10
{{10.00|money:EUR}} to €10
/**
* #ngdoc filter
* #name money
* #kind function
*
* #description
* Formats a number as a currency (ie $1,234.56), removing trailing zeros and using the real currency symbol when possible. When no currency symbol is provided, default
* symbol for current locale is used.
*
* #param {number} amount Input to filter.
* #param {string=} symbol Currency symbol or identifier to be displayed.
* #returns {string} Formatted number. *
*/
app.filter('money', [ '$filter', '$locale', function (filter, locale) {
var currencyFilter = filter('currency');
var formats = locale.NUMBER_FORMATS;
var getCurrencySymbol = function (code) {
switch (code.toUpperCase()) {
case 'EUR': //Euro
return '€';
case 'USD': //Dólar americano
case 'MXN': //Peso mejicano
case 'CAD': //Dólar de Canadá
case 'AUD': //Dólar australiano
case 'NZD': //Dólar neozelandés
case 'HKD': //Dólar de Hong Kong
case 'SGD': //Dólar de Singapur
case 'ARS': //Peso argentino
return '$';
case 'CNY': //Yuan chino
case 'JPY': //Yen japonés
return '¥';
case 'GBP': //Libra esterlina
case 'GIP': //Libras de Gibraltar
return '£';
case 'BRL': //Real brasileño
return 'R$';
case 'INR': //Rupia india
return 'Rp';
case 'CHF': //Franco suizo
return 'Fr';
case 'SEK': //Corona sueca
case 'NOK': //Corona noruega
return 'kr';
case 'KPW': //Won de Corea del Norte
case 'KRW': //Won de Corea del Sur
return '₩';
default:
return code;
}
};
return function (amount, currency) {
var value;
if (currency) {
value = currencyFilter(amount, getCurrencySymbol(currency));
}
else {
value = currencyFilter(amount);
}
//Remove trailing zeros
var regex = new RegExp("\\" + formats.DECIMAL_SEP + "0+", "i");
return value.replace(regex, '');
};
} ]);
And here if you want to round up to nearest $1000: Live Demo:
var app = angular.module('angularjs-starter', []);
app.filter('noFractionRoundUpCurrency',
[ '$filter', '$locale', function(filter, locale) {
var currencyFilter = filter('currency');
var formats = locale.NUMBER_FORMATS;
return function(amount, currencySymbol) {
var value = currencyFilter(amount, currencySymbol);
var sep = value.indexOf(formats.DECIMAL_SEP);
if(amount >= 0) {
if (amount % 1000 < 500){
return '$' + (amount - (amount % 500));
} else {
return '$' + (amount - (amount % 500) + 500);
}
}
else{
if (-amount % 1000 < 500){
return '($' + (-amount - (-amount % 500)) + ')';
} else {
return '($' + (-amount - (-amount % 500) + 500)+ ')';
}
}
};
} ]);
app.controller('MainCtrl', function($scope) {
});
Exactly what I needed!
I added a conditional to just replace Angular's currency filter altogether and just use a modified version of the filter seen above by #Tom. I'm sure there are better ways to do this but it seems to work well for me thus far.
'use strict';
angular.module('your-module')
.filter('nfcurrency', [ '$filter', '$locale', function ($filter, $locale) {
var currency = $filter('currency'), formats = $locale.NUMBER_FORMATS;
return function (amount, symbol) {
var value = currency(amount, symbol), valArr = value.split(formats.DECIMAL_SEP);
if(parseInt(valArr[(valArr.length - 1)]) > 0) {
return value;
} else {
return value.replace(new RegExp('\' + formats.DECIMAL_SEP + '\d{2}'), '');
}
};
}]);
I have modified a bit the filter posted by #Liviu T. to accept currencies with symbol after the number and certain number of decimals:
app.filter('noFractionCurrency',
[ '$filter', '$locale', function(filter, locale) {
var currencyFilter = filter('currency');
var formats = locale.NUMBER_FORMATS;
return function(amount, num, currencySymbol) {
if (num===0) num = -1;
var value = currencyFilter(amount, currencySymbol);
var sep = value.indexOf(formats.DECIMAL_SEP)+1;
var symbol = '';
if (sep<value.indexOf(formats.CURRENCY_SYM)) symbol = ' '+formats.CURRENCY_SYM;
return value.substring(0, sep+num)+symbol;
};
} ]);
For example:
{{10.234 | noFractionCurrency:0}}
{{10.55555 | noFractionCurrency:2}}
Outputs:
$10
$10.56
Demo
If you'd use angular-i18n (bower install angular-i18n), you could use a decorator to change the defaults in the locale files, like so:
$provide.decorator('$locale', ['$delegate',
function ($delegate) {
$delegate.NUMBER_FORMATS.PATTERNS[1].maxFrac = 0;
$delegate.NUMBER_FORMATS.PATTERNS[1].minFrac = 0;
return $delegate;
}]);
Note that this would apply to all currency filter uses in your code.
In Angular 4+
{{totalCost | currency : 'USD' : 'symbol' : '1.0-0' }}

Resources