55 lines
2.3 KiB
JavaScript
55 lines
2.3 KiB
JavaScript
/* Indonesian number formatting shared by the calculator and admin pages. */
|
||
(function (root) {
|
||
'use strict';
|
||
var nf0 = new Intl.NumberFormat('id-ID', { maximumFractionDigits: 0 });
|
||
var nf2 = new Intl.NumberFormat('id-ID', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||
var nfp = new Intl.NumberFormat('id-ID', { minimumFractionDigits: 0, maximumFractionDigits: 4 });
|
||
|
||
var F = {
|
||
/** 1234567.8 -> "Rp1.234.568" */
|
||
rp: function (x) {
|
||
var v = Math.round(Number(x) || 0);
|
||
return (v < 0 ? '−Rp' : 'Rp') + nf0.format(Math.abs(v));
|
||
},
|
||
/** 0.027 -> "2,70%" */
|
||
pct: function (x) { return nf2.format((Number(x) || 0) * 100) + '%'; },
|
||
/** 0.0075 -> "0,75" (for inputs) */
|
||
pctInput: function (x) { return nfp.format((Number(x) || 0) * 100); },
|
||
num: function (x) { return nf0.format(Math.round(Number(x) || 0)); },
|
||
/** "55.000.000" -> 55000000 */
|
||
parseIdr: function (s) {
|
||
var d = String(s == null ? '' : s).replace(/[^0-9]/g, '');
|
||
return d === '' ? null : Number(d);
|
||
},
|
||
/** "0,75" / "0.75" -> 0.0075; "" -> null; invalid -> NaN */
|
||
parsePct: function (s) {
|
||
var t = String(s == null ? '' : s).replace(/[\s%]/g, '').replace(',', '.');
|
||
if (t === '') return null;
|
||
if (!/^-?\d+(\.\d+)?$/.test(t)) return NaN;
|
||
return Math.round(parseFloat(t) * 1e6) / 1e8;
|
||
},
|
||
/** 50000000 -> "50 jt", 2e9 -> "2 M" */
|
||
short: function (x) {
|
||
var v = Number(x) || 0;
|
||
if (v >= 1e12) return nfp.format(v / 1e12) + ' T';
|
||
if (v >= 1e9) return nfp.format(v / 1e9) + ' M';
|
||
if (v >= 1e6) return nfp.format(v / 1e6) + ' jt';
|
||
return nf0.format(v);
|
||
},
|
||
/** Keeps the caret position stable while re-formatting a thousands-separated input. */
|
||
liveFormatIdr: function (input) {
|
||
var before = input.value;
|
||
var caret = input.selectionStart == null ? before.length : input.selectionStart;
|
||
var digitsBefore = before.slice(0, caret).replace(/[^0-9]/g, '').length;
|
||
var n = F.parseIdr(before);
|
||
var after = n === null ? '' : nf0.format(n);
|
||
input.value = after;
|
||
var pos = 0, seen = 0;
|
||
while (pos < after.length && seen < digitsBefore) { if (/[0-9]/.test(after[pos])) seen++; pos++; }
|
||
try { input.setSelectionRange(pos, pos); } catch (e) { /* not focusable */ }
|
||
return n;
|
||
}
|
||
};
|
||
root.SerubiFormat = F;
|
||
})(window);
|