Skip to content

Commit d96fe86

Browse files
author
Vaibhav Khullar
committed
Version 2.0.0 - Better number pattern encoding and parsing of formatted values
1 parent de10a6d commit d96fe86

File tree

7 files changed

+125
-217
lines changed

7 files changed

+125
-217
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# currencyFormatter.js
2-
A super simple currency formatting library by [https://usebx.com](https://usebx.com)
2+
A super simple currency formatting library by the Bx team at OSREC Technologies
3+
4+
This library was originally created by the Bx team at [OSREC Technologies](https://osrec.co.uk/) while developing Bx ([usebx.com](https://usebx.com)). Having found no library capable of formatting the more unusual currencies they decided to create their own and release it under an MIT Licence.
5+
6+
[Give Bx a try if you ever need a tool for invoicing, expenses or project management!](https://usebx.com/)
37

48
## Docs
5-
[Full docs available here ](https://osrec.github.io/currencyFormatter.js/)
9+
[Full docs available here](https://osrec.github.io/currencyFormatter.js/)
610

711
## Installation
812

@@ -11,8 +15,5 @@ A super simple currency formatting library by [https://usebx.com](https://usebx.
1115
npm install currencyformatter.js
1216
```
1317

14-
### bower
15-
```Bash
16-
bower install currencyFormatter.js
17-
```
18+
1819

bower.json

Lines changed: 0 additions & 24 deletions
This file was deleted.

currencyFormatter.js

Lines changed: 75 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
// Developed and distributed by OSREC (http://osrec.co.uk)
2-
// Version: 0.1
3-
// Date: 27 Sept 2016
1+
// CurrencyFormatter.js
2+
// ---------------------------------------------------------------------
3+
// Version: 2.0
4+
// Release Date: 9 Jan 2018
5+
// Created by the Bx team at OSREC Technologies (https://osrec.co.uk)
6+
//
7+
// Check out Bx @ https://usebx.com for free invoicing, expenses & project management
8+
// If you use this library in a commercial project, we appreciate a link back to https://osrec.co.uk :)
49

510
var OSREC = OSREC || {};
611

@@ -1041,122 +1046,74 @@ OSREC.CurrencyFormatter =
10411046
zu_ZA: { h: 'zu' },
10421047
},
10431048

1044-
getFormatter: function(p)
1049+
getFormatDetails: function(p)
10451050
{
10461051
var locales = OSREC.CurrencyFormatter.locales;
10471052
var defaultLocales = OSREC.CurrencyFormatter.defaultLocales;
10481053
var symbols = OSREC.CurrencyFormatter.symbols;
10491054

10501055
var locale, currency, symbol, pattern, decimal, group;
10511056

1052-
// Helper Functions
1053-
1054-
var isUndefined = function(o)
1055-
{
1056-
return (typeof o === 'undefined');
1057-
};
1058-
1059-
var toFixed = function( n, precision )
1060-
{
1061-
return (+(Math.round(+(n + 'e' + precision)) + 'e' + -precision)).toFixed(precision);
1062-
};
1063-
10641057
// Perform checks on inputs and set up defaults as needed (defaults to en, USD)
10651058

1066-
if(isUndefined(p)) { p = {}; }
1067-
1068-
currency = isUndefined(p.currency)? 'USD' : p.currency.toUpperCase();
1069-
locale = isUndefined(p.locale) ? locales[defaultLocales[currency]] : locales[p.locale];
1059+
p = p || {};
10701060

1071-
if(!isUndefined(locale.h)) locale = locales[locale.h]; // Locale inheritance
1061+
currency = (p.currency || 'USD').toUpperCase();
1062+
locale = locales[p.locale || defaultLocales[currency]];
10721063

1073-
symbol = isUndefined(p.symbol) ? symbols[currency] : p.symbol;
1064+
if(typeof locale.h !== 'undefined') { locale = locales[locale.h]; } // Locale inheritance
10741065

1075-
if(isUndefined(symbol)) symbol = currency; // In case we don't have the symbol, just use the ccy code
1066+
symbol = (p.symbol || symbols[currency]) || currency;
1067+
pattern = p.pattern || locale.p;
1068+
decimal = p.decimal || locale.d;
1069+
group = p.group || locale.g;
1070+
1071+
return { pattern: pattern, decimal: decimal, group: group, symbol: symbol };
10761072

1077-
pattern = isUndefined(p.pattern) ? locale.p : p.pattern;
1078-
decimal = isUndefined(p.decimal) ? locale.d : p.decimal;
1079-
group = isUndefined(p.group) ? locale.g : p.group;
1073+
},
10801074

1081-
//console.log(locale);
1075+
toFixed: function( n, precision )
1076+
{
1077+
return ( Math.round( Number(n) * Math.pow(10, precision) )/ Math.pow(10, precision) ).toFixed(precision);
1078+
},
10821079

1080+
getFormatter: function(p)
1081+
{
1082+
var formatDetails = OSREC.CurrencyFormatter.getFormatDetails(p);
1083+
1084+
var pattern = formatDetails.pattern;
1085+
var decimal = formatDetails.decimal;
1086+
var group = formatDetails.group;
1087+
var symbol = formatDetails.symbol;
1088+
10831089
// encodePattern Function - returns a few simple characteristics of the pattern provided
1084-
1090+
10851091
var encodePattern = function(pattern)
10861092
{
1087-
var decimalPlaces = 0;
1088-
var frontPadding = '';
1089-
var backPadding = '';
1090-
var groupLengths = [];
1091-
1092-
//console.log(pattern);
1093-
1094-
var patternStarted = false;
1095-
var decimalsStarted = false;
1096-
var patternEnded = false;
1097-
1098-
1099-
var currentGroupLength = 0;
1100-
var zeroLength = 0;
1101-
1102-
for(var i = 0; i < pattern.length; ++i )
1103-
{
1104-
var c = pattern[i];
1105-
1106-
if(!patternStarted && ['#','0',',','.'].indexOf(c) > -1)
1107-
{
1108-
patternStarted = true;
1109-
}
1110-
1111-
if(!patternStarted) { frontPadding += c; }
1112-
1113-
switch (c)
1114-
{
1115-
case '#':
1116-
++currentGroupLength;
1117-
break;
1118-
1119-
case '0':
1120-
if(decimalsStarted) { ++decimalPlaces; }
1121-
else { ++currentGroupLength; ++zeroLength; }
1122-
break;
1123-
1124-
case ',':
1125-
groupLengths.push(currentGroupLength);
1126-
currentGroupLength = 0;
1127-
break;
1128-
1129-
case '.':
1130-
groupLengths.push(currentGroupLength);
1131-
decimalsStarted = true;
1132-
break;
1133-
}
1134-
1135-
if(patternStarted && !(['#','0',',','.'].indexOf(c) > -1))
1136-
{
1137-
patternEnded = true;
1138-
1139-
if(!decimalsStarted)
1140-
{
1141-
groupLengths.push(currentGroupLength);
1142-
}
1143-
1144-
}
1145-
1146-
if(patternEnded) { backPadding += c; }
1147-
}
1148-
1093+
var numberFormatPattern = pattern.trim().match(/[#0,\.]+/)[0];
1094+
1095+
var split = numberFormatPattern.split('.');
1096+
var c = split[0]; // Decimal chars
1097+
var m = split[1]; // Decimal mantissa
1098+
1099+
var groups = c.split(',');
1100+
var groupLengths = groups.map(function(g) { return g.length; });
1101+
var zeroLength = (groups[groups.length - 1].match(/0/g) || []).length;
1102+
var decimalPlaces = typeof m === 'undefined' ? 0 : m.length;
1103+
var paddingSplit = pattern.split(numberFormatPattern);
1104+
11491105
var encodedPattern =
11501106
{
1107+
pattern: pattern,
11511108
decimalPlaces: decimalPlaces,
1152-
frontPadding: frontPadding,
1153-
backPadding: backPadding,
1109+
frontPadding: paddingSplit[0],
1110+
backPadding: paddingSplit[1],
11541111
groupLengths: groupLengths,
11551112
zeroLength: zeroLength
11561113
};
11571114

11581115
return encodedPattern;
1159-
};
1116+
}
11601117

11611118
// Zero Padding helper function
11621119

@@ -1170,21 +1127,23 @@ OSREC.CurrencyFormatter =
11701127

11711128
var format = function(n, f)
11721129
{
1173-
var formattedNumber = toFixed(Math.abs(n), f.decimalPlaces);
1130+
var formattedNumber = OSREC.CurrencyFormatter.toFixed(Math.abs(n), f.decimalPlaces);
11741131

11751132
var splitNumber = formattedNumber.split(".");
11761133

1177-
if(f.groupLengths.length > 1) // i.e. we actually have some sort of grouping in the values
1178-
{
1179-
var segment = "";
1134+
var segment = "";
1135+
1136+
var cursor = splitNumber[0].length;
11801137

1181-
var cursor = splitNumber[0].length;
1138+
var maxGroupIndex = f.groupLengths.length - 1;
11821139

1183-
var groupIndex = f.groupLengths.length - 1;
1140+
var groupIndex = maxGroupIndex;
11841141

1142+
if(maxGroupIndex > 0)
1143+
{
11851144
while(cursor > 0)
11861145
{
1187-
if(groupIndex <= 0) { groupIndex = 1; } // Always reset to the first group length if the number is big
1146+
if(groupIndex < 1) { groupIndex = 1; } // Always reset to the last group length (useful for big numbers)
11881147

11891148
var currentGroupLength = f.groupLengths[groupIndex];
11901149

@@ -1196,16 +1155,19 @@ OSREC.CurrencyFormatter =
11961155

11971156
--groupIndex;
11981157
}
1199-
1158+
12001159
segment = segment.substring(0, segment.length-1);
1201-
//console.log(segment);
1160+
}
1161+
else
1162+
{
1163+
segment = splitNumber[0];
12021164
}
12031165

12041166
if(segment.length < f.zeroLength) { segment = pad(segment, f.zeroLength); }
12051167

1206-
var formattedNumber = f.frontPadding + segment + ( isUndefined(splitNumber[1]) ? '' : (f.decimal + splitNumber[1]) ) + f.backPadding;
1168+
var formattedNumber = f.frontPadding + segment + ( typeof splitNumber[1] === 'undefined' ? '' : (f.decimal + splitNumber[1]) ) + f.backPadding;
12071169

1208-
return formattedNumber.replace('!', symbol);
1170+
return formattedNumber.replace(/\!/g, symbol);
12091171

12101172
};
12111173

@@ -1219,13 +1181,13 @@ OSREC.CurrencyFormatter =
12191181
positiveFormat.decimal = decimal;
12201182
positiveFormat.group = group;
12211183

1222-
var negativeFormat = isUndefined(patternArray[1]) ? encodePattern("-" + patternArray[0]) : encodePattern(patternArray[1]);
1184+
var negativeFormat = typeof patternArray[1] === 'undefined' ? encodePattern("-" + patternArray[0]) : encodePattern(patternArray[1]);
12231185

12241186
negativeFormat.symbol = symbol;
12251187
negativeFormat.decimal = decimal;
12261188
negativeFormat.group = group;
12271189

1228-
var zero = isUndefined(patternArray[2]) ? format(0, positiveFormat) : patternArray[2];
1190+
var zero = typeof patternArray[2] === 'undefined' ? format(0, positiveFormat) : patternArray[2];
12291191

12301192
return function(n)
12311193
{
@@ -1285,11 +1247,17 @@ OSREC.CurrencyFormatter =
12851247
var formatterFunction = OSREC.CurrencyFormatter.getFormatter(p);
12861248

12871249
return formatterFunction(n);
1250+
},
1251+
1252+
parse: function(str, p)
1253+
{
1254+
var decimal = OSREC.CurrencyFormatter.getFormatDetails(p).decimal;
1255+
var mult = str.indexOf('-') >= 0 ? -1 : 1;
1256+
return Math.abs(Number(str.replace(new RegExp(`[^0-9${decimal}]`, 'g'), '').replace(decimal, '.'))) * mult;
12881257
}
12891258
};
12901259

12911260

1292-
12931261
var hasDefine = typeof define === 'function';
12941262
var hasExports = typeof module !== 'undefined' && module.exports;
12951263
var root = (typeof window === 'undefined') ? global : window;

currencyFormatter.min.js

Lines changed: 1 addition & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/currencyFormatter.min.js

Lines changed: 1 addition & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)