UNPKG

tablefilter

Version:

A Javascript library making HTML tables filterable and a bit more

97 lines (90 loc) • 3.66 kB
import {isNumber} from './types'; /** * Formats a numeric value with configurable separators and affixes. * @param {Number|String} value Numeric value * @param {Object} [options={}] Formatting options * @param {String} [options.locale='en'] Intl locale * @param {String} [options.decimal] Decimal separator override * @param {String} [options.integerSeparator] Thousands separator override * @param {Number} [options.precision] Fixed number of fraction digits * @param {Number} [options.round] Maximum number of fraction digits * @param {String} [options.prefix=''] Value prefix * @param {String} [options.suffix=''] Value suffix * @returns {String} Formatted number */ export const formatNumberValue = (value, options = {}) => { if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) { return ''; } const num = Number(value); if (isNaN(num) || !isFinite(num)) { return ''; } const locale = options.locale || 'en'; const prefix = options.prefix || ''; const suffix = options.suffix || ''; const numericText = typeof value === 'string' ? value.trim() : num.toString(); const coefficient = numericText.toLowerCase().split('e')[0]; const exponent = Number(numericText.toLowerCase().split('e')[1] || 0); const decimalIndex = coefficient.indexOf('.'); const inputPrecision = Math.max(0, decimalIndex < 0 ? 0 : coefficient.length - decimalIndex - 1 - exponent); const maximumPrecision = options.round !== undefined ? options.round : options.precision !== undefined ? options.precision : inputPrecision; const minimumPrecision = options.precision !== undefined ? Math.min(options.precision, maximumPrecision) : Math.min(inputPrecision, maximumPrecision); const formatter = new Intl.NumberFormat(locale, { useGrouping: options.integerSeparator === undefined || Boolean(options.integerSeparator), minimumFractionDigits: minimumPrecision, maximumFractionDigits: maximumPrecision }); let sign = ''; const formatted = formatter.formatToParts(num).map((part) => { if (part.type === 'group') { return options.integerSeparator === undefined ? part.value : options.integerSeparator; } if (part.type === 'decimal') { return options.decimal || part.value; } if (part.type === 'minusSign') { sign = part.value; return ''; } return part.value; }).join(''); return `${sign}${prefix}${formatted}${suffix}`; }; /** * Takes a string, removes all formatting/cruft and returns the raw float value * @param {String} Formatted number * @param {String} Decimal type '.' or ',' * @return {Number} Unformatted number * * https://github.com/openexchangerates/accounting.js/blob/master/accounting.js */ export const parse = (value, decimal = '.') => { // Return the value as-is if it's already a number if (isNumber(value)) { return value; } // Build regex to strip out everything except digits, decimal point and // minus sign let regex = new RegExp('[^0-9-' + decimal + ']', ['g']); let unformatted = parseFloat( ('' + value) // replace bracketed values with negatives .replace(/\((.*)\)/, '-$1') // strip out any cruft .replace(regex, '') // make sure decimal point is standard .replace(decimal, '.') ); // This will fail silently return !isNaN(unformatted) ? unformatted : 0; };