Files
calcserubi/assets/js/format.js
T
2026-10-20 13:16:38 +09:00

55 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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);