UNPKG

angular-mask

Version:
137 lines (106 loc) 3.65 kB
'use strict'; angular.module('ui.utils.masks.global.scientific-notation', []) .directive('uiScientificNotationMask', ['$locale', '$parse', '$log', function($locale, $parse, $log) { var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP, defaultPrecision = 2; function significandMaskBuilder (decimals) { var mask = '0'; if(decimals > 0) { mask += decimalDelimiter; for (var i = 0; i < decimals; i++) { mask += '0'; } } return new StringMask(mask, { reverse: true }); } return { restrict: 'A', require: 'ngModel', link: function(scope, element, attrs, ctrl) { var decimals = $parse(attrs.uiScientificNotationMask)(scope); if(isNaN(decimals)) { decimals = defaultPrecision; } var significandMask = significandMaskBuilder(decimals); function splitNumber (value) { var stringValue = value.toString(), splittedNumber = stringValue.match(/(-?[0-9]*)[\.]?([0-9]*)?[Ee]?([\+-]?[0-9]*)?/); return { integerPartOfSignificand: splittedNumber[1], decimalPartOfSignificand: splittedNumber[2], exponent: splittedNumber[3] | 0 }; } function formatter (value) { $log.debug('[uiScientificNotationMask] Formatter called: ', value); if (angular.isUndefined(value)) { return value; } if (typeof value === 'string') { if (value.length === 0) { return value; } value = value.replace(decimalDelimiter, '.'); } else if (typeof value === 'number') { value = value.toExponential(decimals); } var formattedValue, exponent; var splittedNumber = splitNumber(value); var integerPartOfSignificand = splittedNumber.integerPartOfSignificand | 0; var numberToFormat = integerPartOfSignificand.toString(); if (angular.isDefined(splittedNumber.decimalPartOfSignificand)) { numberToFormat += splittedNumber.decimalPartOfSignificand; } var needsNormalization = (integerPartOfSignificand >= 1 || integerPartOfSignificand <= -1) && ( (angular.isDefined(splittedNumber.decimalPartOfSignificand) && splittedNumber.decimalPartOfSignificand.length > decimals) || (decimals === 0 && numberToFormat.length >= 2) ); if (needsNormalization) { exponent = numberToFormat.slice(decimals + 1, numberToFormat.length); numberToFormat = numberToFormat.slice(0, decimals + 1); } formattedValue = significandMask.apply(numberToFormat); if (splittedNumber.exponent !== 0) { exponent = splittedNumber.exponent; } if (angular.isDefined(exponent)) { formattedValue += 'e' + exponent; } return formattedValue; } function parser (value) { $log.debug('[uiScientificNotationMask] Parser called: ', value); if(angular.isUndefined(value) || value.toString().length === 0) { return value; } var viewValue = formatter(value), modelValue = parseFloat(viewValue.replace(decimalDelimiter, '.')); if (ctrl.$viewValue !== viewValue) { ctrl.$setViewValue(viewValue); ctrl.$render(); } return modelValue; } function validator (value) { $log.debug('[uiScientificNotationMask] Validator called: ', value); if(angular.isUndefined(value)) { return value; } var isMaxValid = value < Number.MAX_VALUE; ctrl.$setValidity('max', ctrl.$isEmpty(value) || isMaxValid); return value; } ctrl.$formatters.push(formatter); ctrl.$formatters.push(validator); ctrl.$parsers.push(parser); ctrl.$parsers.push(validator); } }; } ]);