autonumeric
Version:
autoNumeric is a standalone Javascript library that provides live *as-you-type* formatting for international numbers and currencies. It supports most international numeric formats and currencies including those used in Europe, Asia, and North and South Am
1,018 lines (969 loc) • 691 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["AutoNumeric"] = factory();
else
root["AutoNumeric"] = factory();
})(this, () => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/AutoNumeric.js":
/*!****************************!*\
!*** ./src/AutoNumeric.js ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ AutoNumeric)
/* harmony export */ });
/* harmony import */ var _AutoNumericHelper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AutoNumericHelper */ "./src/AutoNumericHelper.js");
/* harmony import */ var _AutoNumericEnum__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AutoNumericEnum */ "./src/AutoNumericEnum.js");
/* harmony import */ var _maths_Evaluator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./maths/Evaluator */ "./src/maths/Evaluator.js");
/* harmony import */ var _maths_Parser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./maths/Parser */ "./src/maths/Parser.js");
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
/**
* AutoNumeric.js
*
* @version 4.10.8
* @date 2025-03-03 UTC 08:10
*
* @authors 2016-2025 Alexandre Bonneau <alexandre.bonneau@linuxfr.eu>
* 2009-2016 Bob Knothe <bob.knothe@gmail.com>
* @contributors Sokolov Yura and others, cf. AUTHORS
* @copyright Alexandre Bonneau & Robert J. Knothe
* @since 2009-08-09
*
* @summary AutoNumeric is a standalone Javascript library
* that provides live *as-you-type* formatting for
* international numbers and currencies.
*
* @link http://autonumeric.org
* @docs https://docs.autonumeric.org
*
* Note : Some functions are borrowed from big.js
* @see https://github.com/MikeMcl/big.js/
*
* Please report any bugs to https://github.com/autoNumeric/autoNumeric
*
* @license Released under the MIT License
* @link http://www.opensource.org/licenses/mit-license.php
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sub license, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//TODO Prevent having to enter relative path in the js files (i.e. using `./AutoNumericHelper` instead of just `AutoNumericHelper`) (cf. http://moduscreate.com/es6-es2015-import-no-relative-path-webpack/)
/**
* Class declaration for the AutoNumeric object.
*
* An AutoNumeric element is an object wrapper that keeps a reference to the DOM element it manages (usually an <input> one), and provides autoNumeric-specific variables and functions.
*/
var AutoNumeric = /*#__PURE__*/function () {
/**
* Initialize the AutoNumeric object onto the given DOM element, and attach the settings and related event listeners to it.
* The options passed as a parameter is an object that contains the settings (i.e. {digitGroupSeparator: ".", decimalCharacter: ",", currencySymbol: '€ '})
*
* @example
* anElement = new AutoNumeric(domElement); // With the default options
* anElement = new AutoNumeric(domElement, { options }); // With one option object
* anElement = new AutoNumeric(domElement, 'euroPos'); // With a named pre-defined string
* anElement = new AutoNumeric(domElement, [{ options1 }, 'euroPos', { options2 }]); // With multiple option objects (the latest option overwriting the previous ones)
* anElement = new AutoNumeric(domElement, null, { options }); // With one option object, and a failed initial value
* anElement = new AutoNumeric(domElement).french(); // With one pre-defined language object
* anElement = new AutoNumeric(domElement).french({ options });// With one pre-defined language object and additional options that will override the defaults
*
* // ...or init and set the value in one call :
* anElement = new AutoNumeric(domElement, 12345.789); // With the default options, and an initial value
* anElement = new AutoNumeric(domElement, 12345.789, { options });
* anElement = new AutoNumeric(domElement, '12345.789', { options });
* anElement = new AutoNumeric(domElement, 12345.789, 'euroPos');
* anElement = new AutoNumeric(domElement, 12345.789, [{ options1 }, 'euroPos', { options2 }]);
* anElement = new AutoNumeric(domElement, 12345.789).french({ options });
* anElement = new AutoNumeric(domElement, 12345.789, { options }).french({ options }); // Not really helpful, but possible
*
* // The AutoNumeric constructor class can also accept a string as a css selector. Under the hood this use `QuerySelector` and limit itself to only the first element it finds.
* anElement = new AutoNumeric('.myCssClass > input');
* anElement = new AutoNumeric('.myCssClass > input', { options });
* anElement = new AutoNumeric('.myCssClass > input', 'euroPos');
* anElement = new AutoNumeric('.myCssClass > input', [{ options1 }, 'euroPos', { options2 }]);
* anElement = new AutoNumeric('.myCssClass > input', 12345.789);
* anElement = new AutoNumeric('.myCssClass > input', 12345.789, { options });
* anElement = new AutoNumeric('.myCssClass > input', 12345.789, 'euroPos');
* anElement = new AutoNumeric('.myCssClass > input', 12345.789, [{ options1 }, 'euroPos', { options2 }]);
* anElement = new AutoNumeric('.myCssClass > input', null, { options }); // With a failed initial value
* anElement = new AutoNumeric('.myCssClass > input', 12345.789).french({ options });
*
* @param {object|Array|number|string} arg1
* @param {object|Array|number|string|null} arg2
* @param {object|Array|number|string|null} arg3
* @throws
*/
function AutoNumeric() {
var _this = this;
var arg1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var arg2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var arg3 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
_classCallCheck(this, AutoNumeric);
// --------------------------------------------------------
// -------------- Initialization
// Initialize the arguments
var _AutoNumeric$_setArgu = AutoNumeric._setArgumentsValues(arg1, arg2, arg3),
domElement = _AutoNumeric$_setArgu.domElement,
initialValue = _AutoNumeric$_setArgu.initialValue,
userOptions = _AutoNumeric$_setArgu.userOptions;
// Initialize the element
this.domElement = domElement;
// Generate the settings
this.defaultRawValue = ''; // The default raw value to set when initializing an AutoNumeric object
this._setSettings(userOptions, false);
//TODO If `styleRules` is not null, add by default a class 'autoNumeric' that adds transition to color, background-color, border-color properties
// Check if the DOM element is supported
this._checkElement();
// Store the additional attributes inside the AutoNumeric object
// Note: This variable is needed and not a duplicate of `initialValueOnFirstKeydown` nor `valueOnFocus` since it serves a different purpose and has a different lifecycle
this.savedCancellableValue = null;
// Initialize the undo/redo variables
this.historyTable = []; // Keep track of *all* valid states of the element value
this.historyTableIndex = -1; // Pointer to the current undo/redo state. This will be set to '0' during initialization since it first adds itself.
this.onGoingRedo = false; // Variable that keeps track if a 'redo' is ongoing (in order to prevent an 'undo' to be launch when releasing the shift key before the ctrl key after a 'redo' shortcut)
// Initialize the parent form element, if any
this.parentForm = this._getParentForm();
// Set the initial value if it exists and if the `formatOnPageLoad` option will allow it
if (!this.runOnce && this.settings.formatOnPageLoad) {
// Format the element value if needed
this._formatDefaultValueOnPageLoad(initialValue);
} else {
// Otherwise set the `rawValue` and the element value, but do not format the latter yet
var valueToSet;
if (_AutoNumericHelper__WEBPACK_IMPORTED_MODULE_0__["default"].isNull(initialValue)) {
switch (this.settings.emptyInputBehavior) {
case AutoNumeric.options.emptyInputBehavior.min:
valueToSet = this.settings.minimumValue;
break;
case AutoNumeric.options.emptyInputBehavior.max:
valueToSet = this.settings.maximumValue;
break;
case AutoNumeric.options.emptyInputBehavior.zero:
valueToSet = '0';
break;
case AutoNumeric.options.emptyInputBehavior.focus:
case AutoNumeric.options.emptyInputBehavior.press:
case AutoNumeric.options.emptyInputBehavior.always:
valueToSet = '';
break;
// It's possible to set the `null` value as the initial value
case AutoNumeric.options.emptyInputBehavior["null"]:
valueToSet = null;
break;
// When `emptyInputBehavior` is a number or a string representing a number
default:
valueToSet = this.settings.emptyInputBehavior;
}
} else {
valueToSet = initialValue;
}
this._setElementAndRawValue(valueToSet);
}
this.runOnce = true;
// Add the events listeners only on input or editable elements
this.hasEventListeners = false;
if (this.isInputElement || this.isContentEditable) {
if (!this.settings.noEventListeners) {
//XXX Here we make sure the global list is created after creating the event listeners, to only create the event listeners on `document` once
this._createEventListeners();
}
this._setWritePermissions(true);
}
// Save the initial values (html attribute + element.value) for the pristine test
this._saveInitialValues(initialValue);
// Set up the data for the persistent storage solution (i.e. sessionStorage)
this.storageNamePrefix = 'AUTO_'; // The prefix for the raw value storage name variable can be modified here
this._setPersistentStorageName();
// --------------------------------------------------------
// -------------- Tracking
this.validState = true; // Keep track if the element is in the valid state
this.isFocused = false; // Keep track if the element is currently focused
this.isWheelEvent = false; // Keep track if a mouse wheel event is currently ongoing
this.isDropEvent = false; // Keep track if a drop event is currently ongoing
this.isEditing = false; // Keep track if the user is currently editing the element
this.rawValueOnFocus = void 0; // Keep track of the rawValue (needed to define if a change event must be sent on blur or enter key)
// Watch any external changes to the element value/textContent/nodeValue and `set()` the new value so that it gets formatted/saved in the history
this.internalModification = false; // This is temporarily set to `true` only when the AutoNumeric object does update the element value
this.attributeToWatch = this._getAttributeToWatch();
this.getterSetter = Object.getOwnPropertyDescriptor(this.domElement.__proto__, this.attributeToWatch);
this._addWatcher();
if (this.settings.createLocalList) {
// Keep track of every AutoNumeric elements that this object initialized
this._createLocalList();
}
// Keep track of all AutoNumeric elements in the current web page
this.constructor._addToGlobalList(this);
// --------------------------------------------------------
// -------------- Methods
// Create the global functions
this.global = {
/**
* Set the same given element value for each element in the local AutoNumeric element list, and format those elements immediately
*
* @param {number|string} newValue The value must be a number or a numeric string
* @param {object} options A settings object that will override the current settings. Note: the update is done only if the `newValue` is defined.
*/
set: function set(newValue) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.set(newValue, options);
});
},
/**
* Set the value given value directly as the DOM element value, without formatting it beforehand.
* This sets the same unformatted value for each element in the local AutoNumeric element list.
*
* @param {number|string} value
* @param {object} options
*/
setUnformatted: function setUnformatted(value) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.setUnformatted(value, options);
});
},
/**
* This is an alias of the `getNumericString()` function, and should not be used anymore.
*
* @param {function|null} callback If a callback is passed, then the result is passed to it as its first argument, and the AutoNumeric object has its second
* @returns {Array<string>}
* @deprecated
*/
get: function get() {
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var result = [];
_this.autoNumericLocalList.forEach(function (aNObject) {
result.push(aNObject.get());
});
_this._executeCallback(result, callback);
return result;
},
/**
* Return an array of the unformatted values (as a string) of each AutoNumeric element of the local AutoNumeric element list
*
* @param {function|null} callback If a callback is passed, then the result is passed to it as its first argument, and the AutoNumeric object has its second
* @returns {Array<string>}
*/
getNumericString: function getNumericString() {
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var result = [];
_this.autoNumericLocalList.forEach(function (aNObject) {
result.push(aNObject.getNumericString());
});
_this._executeCallback(result, callback);
return result;
},
/**
* Return an array of the current formatted values (as a string) of each AutoNumeric element of the local AutoNumeric element list
*
* @param {function|null} callback If a callback is passed, then the result is passed to it as its first argument, and the AutoNumeric object has its second
* @returns {Array<string>}
*/
getFormatted: function getFormatted() {
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var result = [];
_this.autoNumericLocalList.forEach(function (aNObject) {
result.push(aNObject.getFormatted());
});
_this._executeCallback(result, callback);
return result;
},
/**
* Return an array of the element unformatted values (as a real Javascript number), for each element of the local AutoNumeric element list
*
* @param {function|null} callback If a callback is passed, then the result is passed to it as its first argument, and the AutoNumeric object has its second
* @returns {Array<number>}
*/
getNumber: function getNumber() {
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var result = [];
_this.autoNumericLocalList.forEach(function (aNObject) {
result.push(aNObject.getNumber());
});
_this._executeCallback(result, callback);
return result;
},
/**
* Returns the unformatted values (following the `outputFormat` setting) of each element of the local AutoNumeric element list into an array
*
* @param {function|null} callback If a callback is passed, then the result is passed to it as its first argument, and the AutoNumeric object has its second
* @returns {Array<string>}
*/
getLocalized: function getLocalized() {
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var result = [];
_this.autoNumericLocalList.forEach(function (aNObject) {
result.push(aNObject.getLocalized());
});
_this._executeCallback(result, callback);
return result;
},
/**
* Force each element of the local AutoNumeric element list to reformat its value
*/
reformat: function reformat() {
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.reformat();
});
},
/**
* Remove the formatting and keep only the raw unformatted value (as a numericString) in each element of the local AutoNumeric element list
*/
unformat: function unformat() {
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.unformat();
});
},
/**
* Remove the formatting and keep only the localized unformatted value in the element, with the option to override the default outputFormat if needed
*
* @param {null|string} forcedOutputFormat If set to something different from `null`, then this is used as an overriding outputFormat option
*/
unformatLocalized: function unformatLocalized() {
var forcedOutputFormat = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.unformatLocalized(forcedOutputFormat);
});
},
/**
* Updates the AutoNumeric settings, and immediately format the elements accordingly, for each element of the local AutoNumeric element list
*
* @param {object} newOptions This can be either one or more option objects
*/
update: function update() {
for (var _len = arguments.length, newOptions = new Array(_len), _key = 0; _key < _len; _key++) {
newOptions[_key] = arguments[_key];
}
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.update.apply(aNObject, newOptions);
});
},
/**
* Return `true` if *all* the autoNumeric-managed elements are pristine, if their raw value hasn't changed.
* By default, this returns `true` if the raw unformatted value is still the same even if the formatted one has changed (due to a configuration update for instance).
*
* @param {boolean} checkOnlyRawValue If set to `true`, the pristine value is done on the raw unformatted value, not the formatted one. If set to `false`, this also checks that the formatted value hasn't changed.
* @returns {boolean}
*/
isPristine: function isPristine() {
var checkOnlyRawValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var isPristine = true;
_this.autoNumericLocalList.forEach(function (aNObject) {
if (isPristine && !aNObject.isPristine(checkOnlyRawValue)) {
isPristine = false;
}
});
return isPristine;
},
/**
* Execute the `clear()` method on each AutoNumeric object in the local AutoNumeric element list
*
* @param {boolean} forceClearAll
*/
clear: function clear() {
var forceClearAll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.clear(forceClearAll);
});
},
/**
* Execute the `remove()` method on each AutoNumeric object in the local AutoNumeric element list
*/
remove: function remove() {
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.remove();
});
},
/**
* Execute the `wipe()` method on each AutoNumeric object in the local AutoNumeric element list
*/
wipe: function wipe() {
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.wipe();
});
},
/**
* Execute the `nuke()` method on each AutoNumeric object in the local AutoNumeric element list
*/
nuke: function nuke() {
_this.autoNumericLocalList.forEach(function (aNObject) {
aNObject.nuke();
});
},
/**
* Return `true` if the given AutoNumeric object (or DOM element) is in the local AutoNumeric element list
*
* @param {HTMLElement|HTMLInputElement|AutoNumeric} domElementOrAutoNumericObject
* @returns {*}
*/
has: function has(domElementOrAutoNumericObject) {
var result;
if (domElementOrAutoNumericObject instanceof AutoNumeric) {
result = _this.autoNumericLocalList.has(domElementOrAutoNumericObject.node());
} else {
result = _this.autoNumericLocalList.has(domElementOrAutoNumericObject);
}
return result;
},
/**
* Add an existing AutoNumeric object (or DOM element) to the local AutoNumeric element list, using the DOM element as the key.
* This manages the case where `addObject` is used on an AutoNumeric object that already has multiple elements in its local list.
*
* @param {HTMLElement|HTMLInputElement|AutoNumeric} domElementOrAutoNumericObject
*/
addObject: function addObject(domElementOrAutoNumericObject) {
// Start with the same data, whatever the user passed as arguments
var domElement;
var otherAutoNumericObject;
if (domElementOrAutoNumericObject instanceof AutoNumeric) {
domElement = domElementOrAutoNumericObject.node();
otherAutoNumericObject = domElementOrAutoNumericObject;
} else {
domElement = domElementOrAutoNumericObject;
otherAutoNumericObject = AutoNumeric.getAutoNumericElement(domElement);
}
// Check if the current autoNumeric object has a local list
if (!_this._hasLocalList()) {
_this._createLocalList();
}
// Check if the other autoNumeric object has a local list...
var otherANLocalList = otherAutoNumericObject._getLocalList();
if (otherANLocalList.size === 0) {
// Special case if the other AutoNumeric object has an empty local list, then populate itself to it
otherAutoNumericObject._createLocalList();
otherANLocalList = otherAutoNumericObject._getLocalList(); // Update the other local list
}
var mergedLocalLists;
if (otherANLocalList instanceof Map) {
// ...If it does, merge the local lists together
mergedLocalLists = _AutoNumericHelper__WEBPACK_IMPORTED_MODULE_0__["default"].mergeMaps(_this._getLocalList(), otherANLocalList);
} else {
// ...If not, just set the current local list onto the other AutoNumeric object
// We need to specify the AutoNumeric object, otherwise the `_addToLocalList` function would not correctly add the AutoNumeric object since we would not have a reference to it, but a reference to the current AutoNumeric object on which is called this method.
_this._addToLocalList(domElement, otherAutoNumericObject);
mergedLocalLists = _this._getLocalList();
}
// Update the resulting list, on all the objects of that local list (so that we can indifferently use `init()` on any object belonging to that list)
mergedLocalLists.forEach(function (aNObject) {
aNObject._setLocalList(mergedLocalLists);
});
},
/**
* Remove the given AutoNumeric object (or DOM element) from the local AutoNumeric element list, using the DOM element as the key.
* If this function attempts to remove the current AutoNumeric object from the local list, a warning is shown, but the deletion is still done.
*
* Special cases :
* - If the current object removes itself, then it's removed from the shared local list, then a new empty local list is used/created
* - If another object remove this object, then a local list with only this object is used/created
*
* @param {HTMLElement|HTMLInputElement|AutoNumeric} domElementOrAutoNumericObject
* @param {boolean} keepCurrentANObject If set to `false`, then the function will also remove the current AutoNumeric object if asked, otherwise it will ignore it and print a warning message
*/
removeObject: function removeObject(domElementOrAutoNumericObject) {
var keepCurrentANObject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
// Start with the same data, whatever the user passed as arguments
var domElement;
var otherAutoNumericObject;
if (domElementOrAutoNumericObject instanceof AutoNumeric) {
domElement = domElementOrAutoNumericObject.node();
otherAutoNumericObject = domElementOrAutoNumericObject;
} else {
domElement = domElementOrAutoNumericObject;
otherAutoNumericObject = AutoNumeric.getAutoNumericElement(domElement);
}
// Remove the other object from the local list
var initialCompleteLocalList = _this.autoNumericLocalList;
_this.autoNumericLocalList["delete"](domElement);
// Update the local list for all objects in it
initialCompleteLocalList.forEach(function (aNObject) {
aNObject._setLocalList(_this.autoNumericLocalList);
});
if (!keepCurrentANObject && domElement === _this.node()) {
// This object is removed by itself
// Empty the object local list
otherAutoNumericObject._setLocalList(new Map());
} else {
// This object is removed by another object
// Set the local list for the removed object, with only this object in it
otherAutoNumericObject._createLocalList();
}
},
/**
* Remove all elements from the shared list, effectively emptying it.
* This is the equivalent of calling `detach()` on each of its elements.
*
* @param {boolean} keepEachANObjectInItsOwnList If set to `true`, then instead of completely emptying the local list of each AutoNumeric objects, each one of those keeps itself in its own local list
*/
empty: function empty() {
var keepEachANObjectInItsOwnList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var initialCompleteLocalList = _this.autoNumericLocalList;
// Update the local list for all objects in it
initialCompleteLocalList.forEach(function (aNObject) {
if (keepEachANObjectInItsOwnList) {
aNObject._createLocalList();
} else {
aNObject._setLocalList(new Map());
}
});
},
/**
* Return an array containing all the AutoNumeric DOM elements that have been initialized by each other
*
* @returns {Array<HTMLElement>}
*/
elements: function elements() {
var result = [];
_this.autoNumericLocalList.forEach(function (aNObject) {
result.push(aNObject.node());
});
return result;
},
/**
* Return the `Map` object directly
* @returns {Map}
*/
getList: function getList() {
return _this.autoNumericLocalList;
},
/**
* Return the number of element in the local AutoNumeric element list
* @returns {number}
*/
size: function size() {
return _this.autoNumericLocalList.size;
}
};
// Create the functions that will allow to change each setting one by one
/**
* For each option, we define if we need to reformat the element content (does changing the options should change the way its value is displayed?).
* If yes, then we use the `update()` for force a reformat, otherwise, we just update the `settings` object.
*/
this.options = {
/**
* Reset any options set previously, by overwriting them with the default settings
*
* @returns {AutoNumeric}
*/
reset: function reset() {
//TODO Add a `settings` parameter so that the user can reset to a specific set of settings. This is different than update since it drops any non-default settings before using those new settings.
_this.settings = {
rawValue: _this.defaultRawValue
}; // Here we pass the default rawValue in order to prevent showing a warning that we try to set an `undefined` value
_this.update(AutoNumeric.defaultSettings);
return _this;
},
allowDecimalPadding: function allowDecimalPadding(_allowDecimalPadding) {
_this.update({
allowDecimalPadding: _allowDecimalPadding
});
return _this;
},
alwaysAllowDecimalCharacter: function alwaysAllowDecimalCharacter(_alwaysAllowDecimalCharacter) {
//FIXME Test this
_this.update({
alwaysAllowDecimalCharacter: _alwaysAllowDecimalCharacter
});
return _this;
},
caretPositionOnFocus: function caretPositionOnFocus(_caretPositionOnFocus) {
//FIXME test this
_this.settings.caretPositionOnFocus = _caretPositionOnFocus;
return _this;
},
createLocalList: function createLocalList(_createLocalList2) {
_this.settings.createLocalList = _createLocalList2;
// Delete the local list when this is set to `false`, create it if this is set to `true` and there is not pre-existing list
if (_this.settings.createLocalList) {
if (!_this._hasLocalList()) {
_this._createLocalList();
}
} else {
_this._deleteLocalList();
}
return _this;
},
currencySymbol: function currencySymbol(_currencySymbol) {
_this.update({
currencySymbol: _currencySymbol
});
return _this;
},
currencySymbolPlacement: function currencySymbolPlacement(_currencySymbolPlacement) {
_this.update({
currencySymbolPlacement: _currencySymbolPlacement
});
return _this;
},
decimalCharacter: function decimalCharacter(_decimalCharacter) {
_this.update({
decimalCharacter: _decimalCharacter
});
return _this;
},
decimalCharacterAlternative: function decimalCharacterAlternative(_decimalCharacterAlternative) {
_this.settings.decimalCharacterAlternative = _decimalCharacterAlternative;
return _this;
},
/**
* Update the decimal places globally, which means this override any previously set number of decimal shown on focus, on blur, or in the raw value.
*
* @param {int} decimalPlaces
* @returns {AutoNumeric}
*/
decimalPlaces: function decimalPlaces(_decimalPlaces) {
_AutoNumericHelper__WEBPACK_IMPORTED_MODULE_0__["default"].warning('Using `options.decimalPlaces()` instead of calling the specific `options.decimalPlacesRawValue()`, `options.decimalPlacesShownOnFocus()` and `options.decimalPlacesShownOnBlur()` methods will reset those options.\nPlease call the specific methods if you do not want to reset those.', _this.settings.showWarnings);
_this.update({
decimalPlaces: _decimalPlaces
});
return _this;
},
decimalPlacesRawValue: function decimalPlacesRawValue(_decimalPlacesRawValue) {
//FIXME test this
_this.update({
decimalPlacesRawValue: _decimalPlacesRawValue
});
return _this;
},
decimalPlacesShownOnBlur: function decimalPlacesShownOnBlur(_decimalPlacesShownOnBlur) {
_this.update({
decimalPlacesShownOnBlur: _decimalPlacesShownOnBlur
});
return _this;
},
decimalPlacesShownOnFocus: function decimalPlacesShownOnFocus(_decimalPlacesShownOnFocus) {
_this.update({
decimalPlacesShownOnFocus: _decimalPlacesShownOnFocus
});
return _this;
},
defaultValueOverride: function defaultValueOverride(_defaultValueOverride) {
_this.update({
defaultValueOverride: _defaultValueOverride
});
return _this;
},
digitalGroupSpacing: function digitalGroupSpacing(_digitalGroupSpacing) {
_this.update({
digitalGroupSpacing: _digitalGroupSpacing
});
return _this;
},
digitGroupSeparator: function digitGroupSeparator(_digitGroupSeparator) {
_this.update({
digitGroupSeparator: _digitGroupSeparator
});
return _this;
},
divisorWhenUnfocused: function divisorWhenUnfocused(_divisorWhenUnfocused) {
_this.update({
divisorWhenUnfocused: _divisorWhenUnfocused
});
return _this;
},
emptyInputBehavior: function emptyInputBehavior(_emptyInputBehavior) {
if (_this.rawValue === null && _emptyInputBehavior !== AutoNumeric.options.emptyInputBehavior["null"]) {
// Special case : if the current `rawValue` is `null` and the `emptyInputBehavior` is changed to something else than `'null'`, then it makes that `rawValue` invalid.
// Here we can either prevent the option update and throw an error, or still accept the option update and update the value from `null` to `''`.
// We cannot keep `rawValue` to `null` since if `emptyInputBehavior` is not set to `null`, lots of function assume `rawValue` is a string.
_AutoNumericHelper__WEBPACK_IMPORTED_MODULE_0__["default"].warning("You are trying to modify the `emptyInputBehavior` option to something different than `'null'` (".concat(_emptyInputBehavior, "), but the element raw value is currently set to `null`. This would result in an invalid `rawValue`. In order to fix that, the element value has been changed to the empty string `''`."), _this.settings.showWarnings);
_this.rawValue = '';
}
_this.update({
emptyInputBehavior: _emptyInputBehavior
});
return _this;
},
eventBubbles: function eventBubbles(_eventBubbles) {
_this.settings.eventBubbles = _eventBubbles;
return _this;
},
eventIsCancelable: function eventIsCancelable(_eventIsCancelable) {
_this.settings.eventIsCancelable = _eventIsCancelable;
return _this;
},
failOnUnknownOption: function failOnUnknownOption(_failOnUnknownOption) {
_this.settings.failOnUnknownOption = _failOnUnknownOption; //TODO test this with unit tests
return _this;
},
formatOnPageLoad: function formatOnPageLoad(_formatOnPageLoad) {
_this.settings.formatOnPageLoad = _formatOnPageLoad; //TODO test this with unit tests
return _this;
},
formulaMode: function formulaMode(_formulaMode) {
_this.settings.formulaMode = _formulaMode; //TODO test this with unit tests
return _this;
},
historySize: function historySize(_historySize) {
_this.settings.historySize = _historySize;
return _this;
},
invalidClass: function invalidClass(_invalidClass) {
_this.settings.invalidClass = _invalidClass; //TODO test this with unit tests
return _this;
},
isCancellable: function isCancellable(_isCancellable) {
_this.settings.isCancellable = _isCancellable; //TODO test this with unit tests
return _this;
},
leadingZero: function leadingZero(_leadingZero) {
_this.update({
leadingZero: _leadingZero
});
return _this;
},
maximumValue: function maximumValue(_maximumValue) {
_this.update({
maximumValue: _maximumValue
});
return _this;
},
minimumValue: function minimumValue(_minimumValue) {
_this.update({
minimumValue: _minimumValue
});
return _this;
},
modifyValueOnUpDownArrow: function modifyValueOnUpDownArrow(_modifyValueOnUpDownArrow) {
_this.settings.modifyValueOnUpDownArrow = _modifyValueOnUpDownArrow; //TODO test this with unit tests
return _this;
},
modifyValueOnWheel: function modifyValueOnWheel(_modifyValueOnWheel) {
_this.settings.modifyValueOnWheel = _modifyValueOnWheel; //TODO test this with unit tests
return _this;
},
negativeBracketsTypeOnBlur: function negativeBracketsTypeOnBlur(_negativeBracketsTypeOnBlur) {
_this.update({
negativeBracketsTypeOnBlur: _negativeBracketsTypeOnBlur
});
return _this;
},
negativePositiveSignPlacement: function negativePositiveSignPlacement(_negativePositiveSignPlacement) {
_this.update({
negativePositiveSignPlacement: _negativePositiveSignPlacement
});
return _this;
},
negativeSignCharacter: function negativeSignCharacter(_negativeSignCharacter) {
_this.update({
negativeSignCharacter: _negativeSignCharacter
});
return _this;
},
negativePositiveSignBehavior: function negativePositiveSignBehavior(_negativePositiveSignBehavior) {
_this.settings.negativePositiveSignBehavior = _negativePositiveSignBehavior; //TODO test this with unit tests
return _this;
},
noEventListeners: function noEventListeners(_noEventListeners) {
//TODO test this with unit tests
if (_noEventListeners === AutoNumeric.options.noEventListeners.noEvents && _this.settings.noEventListeners === AutoNumeric.options.noEventListeners.addEvents) {
// Remove the events once
_this._removeEventListeners();
}
_this.update({
noEventListeners: _noEventListeners
});
return _this;
},
onInvalidPaste: function onInvalidPaste(_onInvalidPaste) {
_this.settings.onInvalidPaste = _onInvalidPaste; //TODO test this with unit tests
return _this;
},
outputFormat: function outputFormat(_outputFormat) {
_this.settings.outputFormat = _outputFormat;
return _this;
},
overrideMinMaxLimits: function overrideMinMaxLimits(_overrideMinMaxLimits) {
_this.update({
overrideMinMaxLimits: _overrideMinMaxLimits
});
return _this;
},
positiveSignCharacter: function positiveSignCharacter(_positiveSignCharacter) {
_this.update({
positiveSignCharacter: _positiveSignCharacter
});
return _this;
},
rawValueDivisor: function rawValueDivisor(_rawValueDivisor) {
_this.update({
rawValueDivisor: _rawValueDivisor
});
return _this;
},
readOnly: function readOnly(_readOnly) {
// When changing the readOnly attribute, the raw and formatted values do not change, so no need to call the costly 'update()` method
_this.settings.readOnly = _readOnly;
_this._setWritePermissions();
return _this;
},
roundingMethod: function roundingMethod(_roundingMethod) {
_this.update({
roundingMethod: _roundingMethod
});
return _this;
},
saveValueToSessionStorage: function saveValueToSessionStorage(_saveValueToSessionStorage) {
_this.update({
saveValueToSessionStorage: _saveValueToSessionStorage
});
return _this;
},
symbolWhenUnfocused: function symbolWhenUnfocused(_symbolWhenUnfocused) {
_this.update({
symbolWhenUnfocused: _symbolWhenUnfocused
});
return _this;
},
selectNumberOnly: function selectNumberOnly(_selectNumberOnly) {
_this.settings.selectNumberOnly = _selectNumberOnly; //TODO test this with unit tests
return _this;
},
selectOnFocus: function selectOnFocus(_selectOnFocus) {
_this.settings.selectOnFocus = _selectOnFocus; //TODO test this with unit tests
return _this;
},
serializeSpaces: function serializeSpaces(_serializeSpaces) {
_this.settings.serializeSpaces = _serializeSpaces; //TODO test this with unit tests
return _this;
},
showOnlyNumbersOnFocus: function showOnlyNumbersOnFocus(_showOnlyNumbersOnFocus) {
_this.update({
showOnlyNumbersOnFocus: _showOnlyNumbersOnFocus
});
return _this;
},
showPositiveSign: function showPositiveSign(_showPositiveSign) {
_this.update({
showPositiveSign: _showPositiveSign
});
return _this;
},
showWarnings: function showWarnings(_showWarnings) {
_this.settings.showWarnings = _showWarnings; //TODO test this with unit tests
return _this;
},
styleRules: function styleRules(_styleRules) {
_this.update({
styleRules: _styleRules
});
return _this;
},
suffixText: function suffixText(_suffixText) {
_this.update({
suffixText: _suffixText
});
return _this;
},
unformatOnHover: function unformatOnHover(_unformatOnHover) {
_this.settings.unformatOnHover = _unformatOnHover; //TODO test this with unit tests
return _this;
},
unformatOnSubmit: function unformatOnSubmit(_unformatOnSubmit2) {
_this.settings.unformatOnSubmit = _unformatOnSubmit2; //TODO test this with unit tests
return _this;
},
upDownStep: function upDownStep(_upDownStep) {
_this.settings.upDownStep = _upDownStep; //TODO test this with unit tests
return _this;
},
valuesToStrings: function valuesToStrings(_valuesToStrings) {
_this.update({
valuesToStrings: _valuesToStrings
});
return _this;
},
watchExternalChanges: function watchExternalChanges(_watchExternalChanges) {
//TODO test this with unit tests
_this.update({
watchExternalChanges: _watchExternalChanges
});
return _this;
},
wheelOn: function wheelOn(_wheelOn) {
_this.settings.wheelOn = _wheelOn; //TODO test this with unit tests
return _this;
},
wheelStep: function wheelStep(_wheelStep) {
_this.settings.wheelStep = _wheelStep; //TODO test this with unit tests
return _this;
}
};
// Once the autoNumeric element has been initialized, broadcast that message with additional info.
// Note: When using `AutoNumeric.multiple()`, one event is sent *per* element initialized
this._triggerEvent(AutoNumeric.events.initialized, this.domElement, {
newValue: _AutoNumericHelper__WEBPACK_IMPORTED_MODULE_0__["default"].getElementValue(this.domElement),
newRawValue: this.rawValue,
error: null,
aNElement: this
});
}
/**
* Take the parameters given to the AutoNumeric object, and output the three variables that are needed to finish initializing it :
* - domElement : The target DOM element
* - initialValue : The initial value, or `null` if none is given
* - userOptions : The option object
*
* @param {object|Array|number|string} arg1
* @param {object|Array|number|string|null} arg2
* @param {object|Array|number|string|null} arg3
* @returns {{domElement: *, initialValue: *, userOptions: *}}
* @throws
* @private
*/
_createClass(AutoNumeric, [{
key: "_saveInitialValues",
value:
/**
* Save the initial element values for later use in the pristine test.
* Those values are :
* - the html attribute (i.e. <input value='42'>), and
* - the script `value` (i.e. `let domElement.value`)
*
* @param {null|number|string} initialValue
* @private
*/
function _saveInitialValues(initialValue) {
// Keep the very