diff --git a/application/Espo/Resources/metadata/app/jsLibs.json b/application/Espo/Resources/metadata/app/jsLibs.json index 0b7307e011..4068bde144 100644 --- a/application/Espo/Resources/metadata/app/jsLibs.json +++ b/application/Espo/Resources/metadata/app/jsLibs.json @@ -32,6 +32,10 @@ "exportsTo": "window", "exportsAs": "Selectize" }, + "autonumeric": { + "exportsTo": "window", + "exportsAs": "AutoNumeric" + }, "cronstrue": { "path": "client/lib/cronstrue-i18n.js", "devPath": "client/lib/original/cronstrue-i18n.js", diff --git a/client/src/views/fields/currency.js b/client/src/views/fields/currency.js index b8f9a59dc1..563dc33736 100644 --- a/client/src/views/fields/currency.js +++ b/client/src/views/fields/currency.js @@ -88,6 +88,7 @@ function (Dep, /** module:ui/select*/Select) { this.currencyFieldName = this.name + 'Currency'; this.defaultCurrency = this.getConfig().get('defaultCurrency'); this.currencyList = this.getConfig().get('currencyList') || [this.defaultCurrency]; + this.decimalPlaces = this.getConfig().get('currencyDecimalPlaces'); if (this.params.onlyDefaultCurrency) { this.currencyList = [this.defaultCurrency]; @@ -104,6 +105,22 @@ function (Dep, /** module:ui/select*/Select) { } }, + /** + * @inheritDoc + */ + setupAutoNumericOptions: function () { + this.autoNumericOptions = { + digitGroupSeparator: this.thousandSeparator, + decimalCharacter: this.decimalMark, + modifyValueOnWheel: false, + selectOnFocus: false, + decimalPlaces: this.decimalPlaces, + allowDecimalPadding: true, + showWarnings: false, + formulaMode: true, + }; + }, + getCurrencyFormat: function () { return this.getConfig().get('currencyFormat') || 1; }, @@ -140,7 +157,7 @@ function (Dep, /** module:ui/select*/Select) { }, formatNumberEdit: function (value) { - let currencyDecimalPlaces = this.getConfig().get('currencyDecimalPlaces'); + let currencyDecimalPlaces = this.decimalPlaces; if (value !== null) { var parts = value.toString().split("."); @@ -186,15 +203,15 @@ function (Dep, /** module:ui/select*/Select) { formatNumberDetail: function (value) { if (value !== null) { - let currencyDecimalPlaces = this.getConfig().get('currencyDecimalPlaces'); + let currencyDecimalPlaces = this.decimalPlaces; if (currencyDecimalPlaces === 0) { value = Math.round(value); } else if (currencyDecimalPlaces) { - value = Math.round( - value * Math.pow(10, currencyDecimalPlaces)) / (Math.pow(10, currencyDecimalPlaces) - ); + value = Math.round( + value * Math.pow(10, currencyDecimalPlaces)) / (Math.pow(10, currencyDecimalPlaces) + ); } else { value = Math.round( diff --git a/client/src/views/fields/float.js b/client/src/views/fields/float.js index cb5c0a1281..c2144f1123 100644 --- a/client/src/views/fields/float.js +++ b/client/src/views/fields/float.js @@ -46,6 +46,8 @@ define('views/fields/float', ['views/fields/int'], function (Dep) { validations: ['required', 'float', 'range'], + decimalPlacesRawValue: 10, + /** * @inheritDoc */ @@ -55,13 +57,28 @@ define('views/fields/float', ['views/fields/int'], function (Dep) { if (this.getPreferences().has('decimalMark')) { this.decimalMark = this.getPreferences().get('decimalMark'); } - else { - if (this.getConfig().has('decimalMark')) { - this.decimalMark = this.getConfig().get('decimalMark'); - } + else if (this.getConfig().has('decimalMark')) { + this.decimalMark = this.getConfig().get('decimalMark'); } }, + /** + * @inheritDoc + */ + setupAutoNumericOptions: function () { + this.autoNumericOptions = { + digitGroupSeparator: this.thousandSeparator, + decimalCharacter: this.decimalMark, + modifyValueOnWheel: false, + selectOnFocus: false, + decimalPlaces: this.decimalPlacesRawValue, + decimalPlacesRawValue: this.decimalPlacesRawValue, + allowDecimalPadding: false, + showWarnings: false, + formulaMode: true, + }; + }, + getValueForDisplay: function () { var value = isNaN(this.model.get(this.name)) ? null : this.model.get(this.name); @@ -154,22 +171,24 @@ define('views/fields/float', ['views/fields/int'], function (Dep) { parse: function (value) { value = (value !== '') ? value : null; - if (value !== null) { - value = value.split(this.thousandSeparator).join(''); - value = value.split(this.decimalMark).join('.'); - value = parseFloat(value); + if (value === null) { + return null; } - return value; + value = value + .split(this.thousandSeparator) + .join('') + .split(this.decimalMark) + .join('.'); + + return parseFloat(value); }, fetch: function () { - var value = this.$element.val(); - + let value = this.$element.val(); value = this.parse(value); - var data = {}; - + let data = {}; data[this.name] = value; return data; diff --git a/client/src/views/fields/int.js b/client/src/views/fields/int.js index 423079e8d2..baf02c4c08 100644 --- a/client/src/views/fields/int.js +++ b/client/src/views/fields/int.js @@ -26,7 +26,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/fields/int', ['views/fields/base'], function (Dep) { +define('views/fields/int', ['views/fields/base', 'lib!autonumeric'], function (Dep, AutoNumeric) { /** * An integer field. @@ -41,13 +41,9 @@ define('views/fields/int', ['views/fields/base'], function (Dep) { type: 'int', listTemplate: 'fields/int/list', - detailTemplate: 'fields/int/detail', - editTemplate: 'fields/int/edit', - searchTemplate: 'fields/int/search', - validations: ['required', 'int', 'range'], thousandSeparator: ',', @@ -64,6 +60,18 @@ define('views/fields/int', ['views/fields/base'], function (Dep) { 'between', ], + /** + * @type {?Object.} + * @protected + */ + autoNumericOptions: null, + + /** + * @type {?AutoNumeric} + * @protected + */ + autoNumericInstance: null, + setup: function () { Dep.prototype.setup.call(this); @@ -72,10 +80,8 @@ define('views/fields/int', ['views/fields/base'], function (Dep) { if (this.getPreferences().has('thousandSeparator')) { this.thousandSeparator = this.getPreferences().get('thousandSeparator'); } - else { - if (this.getConfig().has('thousandSeparator')) { - this.thousandSeparator = this.getConfig().get('thousandSeparator'); - } + else if (this.getConfig().has('thousandSeparator')) { + this.thousandSeparator = this.getConfig().get('thousandSeparator'); } if (this.params.disableFormatting) { @@ -83,10 +89,36 @@ define('views/fields/int', ['views/fields/base'], function (Dep) { } }, + setupFinal: function () { + Dep.prototype.setupFinal.call(this); + + this.setupAutoNumericOptions(); + }, + + /** + * @protected + */ + setupAutoNumericOptions: function () { + this.autoNumericOptions = { + digitGroupSeparator: !this.disableFormatting ? this.thousandSeparator : null, + modifyValueOnWheel: false, + decimalPlaces: 0, + selectOnFocus: false, + formulaMode: true, + }; + }, + afterRender: function () { Dep.prototype.afterRender.call(this); - if (this.mode === 'search') { + if (this.mode === this.MODE_EDIT) { + + if (this.autoNumericOptions) { + this.autoNumericInstance = new AutoNumeric(this.$element.get(0), this.autoNumericOptions); + } + } + + if (this.mode === this.MODE_SEARCH) { var $searchType = this.$el.find('select.search-type'); this.handleSearchType($searchType.val()); @@ -99,9 +131,16 @@ define('views/fields/int', ['views/fields/base'], function (Dep) { this.trigger('change'); }); - this.$el.find('input.additional').on('input', () => { + let $inputAdditional = this.$el.find('input.additional'); + + $inputAdditional.on('input', () => { this.trigger('change'); }); + + if (this.autoNumericOptions) { + new AutoNumeric(this.$element.get(0), this.autoNumericOptions); + new AutoNumeric($inputAdditional.get(0), this.autoNumericOptions); + } } }, @@ -309,18 +348,19 @@ define('views/fields/int', ['views/fields/base'], function (Dep) { parse: function (value) { value = (value !== '') ? value : null; - if (value !== null) { - value = value.split(this.thousandSeparator).join(''); - - if (value.indexOf('.') !== -1 || value.indexOf(',') !== -1) { - value = NaN; - } - else { - value = parseInt(value); - } + if (value === null) { + return null; } - return value; + value = value + .split(this.thousandSeparator) + .join(''); + + if (value.indexOf('.') !== -1 || value.indexOf(',') !== -1) { + return NaN; + } + + return parseInt(value); }, fetch: function () { diff --git a/frontend/libs.json b/frontend/libs.json index 2c9121261e..f5a9615347 100644 --- a/frontend/libs.json +++ b/frontend/libs.json @@ -92,6 +92,10 @@ "src": "node_modules/selectize/dist/js/standalone/selectize.js", "bundle": true }, + { + "src": "node_modules/autonumeric/dist/autoNumeric.js", + "bundle": true + }, { "src": "node_modules/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js" }, diff --git a/package-lock.json b/package-lock.json index b8738390bb..aad66cf9dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "dependencies": { "ace-builds": "^1.4.12", "autobahn-espo": "github:yurikuzn/autobahn-espo#0.1.0", + "autonumeric": "^4.6.0", "backbone": "^1.3.3", "bootstrap": "^3.4.1", "bootstrap-colorpicker": "^2.5.2", @@ -723,6 +724,12 @@ "resolved": "git+ssh://git@github.com/yurikuzn/autobahn-espo.git#82e1d942b34d8226b25359eb076968e6211b79c2", "license": "MIT" }, + "node_modules/autonumeric": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/autonumeric/-/autonumeric-4.6.0.tgz", + "integrity": "sha512-bYnD2oD9UMZBTxSWcvXH1MTcp0w+CUBfXe4HI1QJLGzJu+O27Ny5gqzRcFuDsZB9jrZ5SJjqAG0PieJsaUdTcg==", + "hasInstallScript": true + }, "node_modules/backbone": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.3.3.tgz", @@ -5253,6 +5260,11 @@ "version": "git+ssh://git@github.com/yurikuzn/autobahn-espo.git#82e1d942b34d8226b25359eb076968e6211b79c2", "from": "autobahn-espo@github:yurikuzn/autobahn-espo#0.1.0" }, + "autonumeric": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/autonumeric/-/autonumeric-4.6.0.tgz", + "integrity": "sha512-bYnD2oD9UMZBTxSWcvXH1MTcp0w+CUBfXe4HI1QJLGzJu+O27Ny5gqzRcFuDsZB9jrZ5SJjqAG0PieJsaUdTcg==" + }, "backbone": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.3.3.tgz", diff --git a/package.json b/package.json index 9a7a0971b6..237bd48b8a 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "dependencies": { "ace-builds": "^1.4.12", "autobahn-espo": "github:yurikuzn/autobahn-espo#0.1.0", + "autonumeric": "^4.6.0", "backbone": "^1.3.3", "bootstrap": "^3.4.1", "bootstrap-colorpicker": "^2.5.2",