diff --git a/client/src/views/fields/currency.js b/client/src/views/fields/currency.js index dda7109444..d2f9626025 100644 --- a/client/src/views/fields/currency.js +++ b/client/src/views/fields/currency.js @@ -55,18 +55,22 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { maxDecimalPlaces: 3, data: function () { - var currencyValue = this.model.get(this.currencyFieldName) || this.getPreferences().get('defaultCurrency') || this.getConfig().get('defaultCurrency'); + var currencyValue = this.model.get(this.currencyFieldName) || + this.getPreferences().get('defaultCurrency') || + this.getConfig().get('defaultCurrency'); + return _.extend({ currencyFieldName: this.currencyFieldName, currencyValue: currencyValue, currencyOptions: this.currencyOptions, currencyList: this.currencyList, - currencySymbol: this.getMetadata().get(['app', 'currency', 'symbolMap', currencyValue]) || '' + currencySymbol: this.getMetadata().get(['app', 'currency', 'symbolMap', currencyValue]) || '', }, Dep.prototype.data.call(this)); }, setup: function () { Dep.prototype.setup.call(this); + this.currencyFieldName = this.name + 'Currency'; this.defaultCurrency = this.getConfig().get('defaultCurrency'); this.currencyList = this.getConfig().get('currencyList') || [this.defaultCurrency]; @@ -90,13 +94,16 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { }, _getTemplateName: function () { - if (this.mode == 'detail' || this.mode == 'list') { - var prop - if (this.mode == 'list') { + if (this.mode === 'detail' || this.mode === 'list') { + var prop; + + if (this.mode === 'list') { var prop = 'listTemplate' + this.getCurrencyFormat().toString(); - } else { + } + else { var prop = 'detailTemplate' + this.getCurrencyFormat().toString(); } + if (this.options.hideCurrency) { prop = 'detailTemplateNoCurrency'; } @@ -105,6 +112,7 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { return this[prop]; } } + return Dep.prototype._getTemplateName.call(this); }, @@ -112,6 +120,7 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { if (this.mode === 'list' || this.mode === 'detail') { return this.formatNumberDetail(value); } + return this.formatNumberEdit(value); }, @@ -120,6 +129,7 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { if (value !== null) { var parts = value.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandSeparator); if (parts.length > 1) { @@ -133,6 +143,7 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { return parts.join(this.decimalMark); } + return ''; }, @@ -142,19 +153,28 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { if (currencyDecimalPlaces === 0) { value = Math.round(value); - } else if (currencyDecimalPlaces) { - value = Math.round(value * Math.pow(10, currencyDecimalPlaces)) / (Math.pow(10, currencyDecimalPlaces)); - } else { - value = Math.round(value * Math.pow(10, this.maxDecimalPlaces)) / (Math.pow(10, this.maxDecimalPlaces)); + } + else if (currencyDecimalPlaces) { + value = Math.round( + value * Math.pow(10, currencyDecimalPlaces)) / (Math.pow(10, currencyDecimalPlaces) + ); + } + else { + value = Math.round( + value * Math.pow(10, this.maxDecimalPlaces)) / (Math.pow(10, this.maxDecimalPlaces) + ); } var parts = value.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandSeparator); if (currencyDecimalPlaces === 0) { return parts[0]; - } else if (currencyDecimalPlaces) { + } + else if (currencyDecimalPlaces) { var decimalPartLength = 0; + if (parts.length > 1) { decimalPartLength = parts[1].length; } else { @@ -163,6 +183,7 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { if (currencyDecimalPlaces && decimalPartLength < currencyDecimalPlaces) { var limit = currencyDecimalPlaces - decimalPartLength; + for (var i = 0; i < limit; i++) { parts[1] += '0'; } @@ -171,34 +192,40 @@ define('views/fields/currency', 'views/fields/float', function (Dep) { return parts.join(this.decimalMark); } + return ''; }, afterRender: function () { Dep.prototype.afterRender.call(this); - if (this.mode == 'edit') { + + if (this.mode === 'edit') { this.$currency = this.$el.find('[data-name="' + this.currencyFieldName + '"]'); - this.$currency.on('change', function () { + + this.$currency.on('change', () => { this.model.set(this.currencyFieldName, this.$currency.val(), {ui: true}); - }.bind(this)); + }); } }, fetch: function () { var value = this.$element.val(); + value = this.parse(value); var data = {}; var currencyValue = this.$currency.val(); + if (value === null) { currencyValue = null; } data[this.name] = value; - data[this.currencyFieldName] = currencyValue + data[this.currencyFieldName] = currencyValue; + return data; - } + }, }); }); diff --git a/client/src/views/fields/float.js b/client/src/views/fields/float.js index 3828de024b..4f6f4d47a7 100644 --- a/client/src/views/fields/float.js +++ b/client/src/views/fields/float.js @@ -26,7 +26,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -Espo.define('views/fields/float', 'views/fields/int', function (Dep) { +define('views/fields/float', 'views/fields/int', function (Dep) { return Dep.extend({ @@ -43,7 +43,8 @@ Espo.define('views/fields/float', 'views/fields/int', function (Dep) { if (this.getPreferences().has('decimalMark')) { this.decimalMark = this.getPreferences().get('decimalMark'); - } else { + } + else { if (this.getConfig().has('decimalMark')) { this.decimalMark = this.getConfig().get('decimalMark'); } @@ -52,6 +53,7 @@ Espo.define('views/fields/float', 'views/fields/int', function (Dep) { getValueForDisplay: function () { var value = isNaN(this.model.get(this.name)) ? null : this.model.get(this.name); + return this.formatNumber(value); }, @@ -59,11 +61,15 @@ Espo.define('views/fields/float', 'views/fields/int', function (Dep) { if (this.disableFormatting) { return value; } + if (value !== null) { var parts = value.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandSeparator); + return parts.join(this.decimalMark); } + return ''; }, @@ -72,29 +78,37 @@ Espo.define('views/fields/float', 'views/fields/int', function (Dep) { validateFloat: function () { var value = this.model.get(this.name); + if (isNaN(value)) { var msg = this.translate('fieldShouldBeFloat', 'messages').replace('{field}', this.getLabelText()); + this.showValidationMessage(msg); + return true; } }, 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); } + return value; }, fetch: function () { var value = this.$element.val(); + value = this.parse(value); var data = {}; + data[this.name] = value; + return data; }, }); diff --git a/client/src/views/fields/int.js b/client/src/views/fields/int.js index 181d456a37..1944503fb9 100644 --- a/client/src/views/fields/int.js +++ b/client/src/views/fields/int.js @@ -44,15 +44,27 @@ define('views/fields/int', 'views/fields/base', function (Dep) { thousandSeparator: ',', - searchTypeList: ['isNotEmpty', 'isEmpty', 'equals', 'notEquals', 'greaterThan', 'lessThan', 'greaterThanOrEquals', 'lessThanOrEquals', 'between'], + searchTypeList: [ + 'isNotEmpty', + 'isEmpty', + 'equals', + 'notEquals', + 'greaterThan', + 'lessThan', + 'greaterThanOrEquals', + 'lessThanOrEquals', + 'between', + ], setup: function () { Dep.prototype.setup.call(this); + this.setupMaxLength(); if (this.getPreferences().has('thousandSeparator')) { this.thousandSeparator = this.getPreferences().get('thousandSeparator'); - } else { + } + else { if (this.getConfig().has('thousandSeparator')) { this.thousandSeparator = this.getConfig().get('thousandSeparator'); } @@ -66,21 +78,22 @@ define('views/fields/int', 'views/fields/base', function (Dep) { afterRender: function () { Dep.prototype.afterRender.call(this); - if (this.mode == 'search') { + if (this.mode === 'search') { var $searchType = this.$el.find('select.search-type'); + this.handleSearchType($searchType.val()); - this.$el.find('select.search-type').on('change', function () { + this.$el.find('select.search-type').on('change', () => { this.trigger('change'); - }.bind(this)); + }); - this.$element.on('input', function () { + this.$element.on('input', () => { this.trigger('change'); - }.bind(this)); + }); - this.$el.find('input.additional').on('input', function () { + this.$el.find('input.additional').on('input', () => { this.trigger('change'); - }.bind(this)); + }); } }, @@ -90,10 +103,12 @@ define('views/fields/int', 'views/fields/base', function (Dep) { if (this.model.get(this.name) !== null && typeof this.model.get(this.name) !== 'undefined') { data.isNotEmpty = true; } + data.valueIsSet = this.model.has(this.name); if (this.isSearchMode()) { data.value = this.searchParams.value; + if (this.getSearchType() === 'between') { data.value = this.getSearchParamsData().value1 || this.searchParams.value1; data.value2 = this.getSearchParamsData().value2 || this.searchParams.value2; @@ -105,6 +120,7 @@ define('views/fields/int', 'views/fields/base', function (Dep) { getValueForDisplay: function () { var value = isNaN(this.model.get(this.name)) ? null : this.model.get(this.name); + return this.formatNumber(value); }, @@ -112,17 +128,21 @@ define('views/fields/int', 'views/fields/base', function (Dep) { if (this.disableFormatting) { return value; } + if (value !== null) { var stringValue = value.toString(); + stringValue = stringValue.replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandSeparator); + return stringValue; } + return ''; }, setupSearch: function () { this.events = _.extend({ - 'change select.search-type': function (e) { + 'change select.search-type': (e) => { this.handleSearchType($(e.currentTarget).val()); }, }, this.events || {}); @@ -130,15 +150,18 @@ define('views/fields/int', 'views/fields/base', function (Dep) { handleSearchType: function (type) { var $additionalInput = this.$el.find('input.additional'); + var $input = this.$el.find('input[data-name="'+this.name+'"]'); if (type === 'between') { $additionalInput.removeClass('hidden'); $input.removeClass('hidden'); - } else if (~['isEmpty', 'isNotEmpty'].indexOf(type)) { + } + else if (~['isEmpty', 'isNotEmpty'].indexOf(type)) { $additionalInput.addClass('hidden'); $input.addClass('hidden'); - } else { + } + else { $additionalInput.addClass('hidden'); $input.removeClass('hidden'); } @@ -177,15 +200,19 @@ define('views/fields/int', 'views/fields/base', function (Dep) { if (typeof max !== 'undefined' && max !== null) { maxValue = this.formatNumber(maxValue); + this.params.maxLength = maxValue.toString().length; } }, validateInt: function () { var value = this.model.get(this.name); + if (isNaN(value)) { var msg = this.translate('fieldShouldBeInt', 'messages').replace('{field}', this.getLabelText()); + this.showValidationMessage(msg); + return true; } }, @@ -202,25 +229,34 @@ define('views/fields/int', 'views/fields/base', function (Dep) { if (minValue !== null && maxValue !== null) { if (value < minValue || value > maxValue ) { - var msg = this.translate('fieldShouldBeBetween', 'messages').replace('{field}', this.getLabelText()) - .replace('{min}', minValue) - .replace('{max}', maxValue); + var msg = this.translate('fieldShouldBeBetween', 'messages') + .replace('{field}', this.getLabelText()) + .replace('{min}', minValue) + .replace('{max}', maxValue); + this.showValidationMessage(msg); + return true; } - } else { + } + else { if (minValue !== null) { if (value < minValue) { - var msg = this.translate('fieldShouldBeGreater', 'messages').replace('{field}', this.getLabelText()) - .replace('{value}', minValue); + var msg = this.translate('fieldShouldBeGreater', 'messages') + .replace('{field}', this.getLabelText()) + .replace('{value}', minValue); + this.showValidationMessage(msg); return true; } - } else if (maxValue !== null) { + } + else if (maxValue !== null) { if (value > maxValue) { - var msg = this.translate('fieldShouldBeLess', 'messages').replace('{field}', this.getLabelText()) - .replace('{value}', maxValue); + var msg = this.translate('fieldShouldBeLess', 'messages') + .replace('{field}', this.getLabelText()) + .replace('{value}', maxValue); this.showValidationMessage(msg); + return true; } } @@ -230,9 +266,12 @@ define('views/fields/int', 'views/fields/base', function (Dep) { validateRequired: function () { if (this.isRequired()) { var value = this.model.get(this.name); + if (value === null || value === false) { var msg = this.translate('fieldIsRequired', 'messages').replace('{field}', this.getLabelText()); + this.showValidationMessage(msg); + return true; } } @@ -240,22 +279,29 @@ 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 { + } + else { value = parseInt(value); } } + return value; }, fetch: function () { var value = this.$element.val(); value = this.parse(value); + var data = {}; + data[this.name] = value; + return data; }, @@ -283,17 +329,20 @@ define('views/fields/int', 'views/fields/base', function (Dep) { value2: valueTo } }; - } else if (type == 'isEmpty') { + } + else if (type === 'isEmpty') { data = { type: 'isNull', typeFront: 'isEmpty' }; - } else if (type == 'isNotEmpty') { + } + else if (type === 'isNotEmpty') { data = { type: 'isNotNull', typeFront: 'isNotEmpty' }; - } else { + } + else { data = { type: type, value: value, @@ -302,12 +351,13 @@ define('views/fields/int', 'views/fields/base', function (Dep) { } }; } + return data; }, getSearchType: function () { return this.searchParams.typeFront || this.searchParams.type; - } + }, }); }); diff --git a/client/src/views/fields/varchar.js b/client/src/views/fields/varchar.js index ce27e5f8b0..2c1b831b01 100644 --- a/client/src/views/fields/varchar.js +++ b/client/src/views/fields/varchar.js @@ -45,6 +45,7 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { setup: function () { this.setupOptions(); + if (this.options.customOptionList) { this.setOptionList(this.options.customOptionList); } @@ -57,9 +58,10 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { if (!this.originalOptionList) { this.originalOptionList = this.params.options || []; } + this.params.options = Espo.Utils.clone(optionList); - if (this.mode == 'edit') { + if (this.mode === 'edit') { if (this.isRendered()) { this.reRender(); } @@ -71,7 +73,7 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { this.params.options = Espo.Utils.clone(this.originalOptionList); } - if (this.mode == 'edit') { + if (this.mode === 'edit') { if (this.isRendered()) { this.reRender(); } @@ -98,6 +100,7 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { ) { data.isNotEmpty = true; } + data.valueIsSet = this.model.has(this.name); if (this.mode === 'search') { @@ -105,82 +108,103 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { this.searchData.value = this.searchParams.value; } } + return data; }, handleSearchType: function (type) { if (~['isEmpty', 'isNotEmpty'].indexOf(type)) { this.$el.find('input.main-element').addClass('hidden'); - } else { + } + else { this.$el.find('input.main-element').removeClass('hidden'); } }, afterRender: function () { Dep.prototype.afterRender.call(this); - if (this.mode == 'search') { + + if (this.mode === 'search') { var type = this.$el.find('select.search-type').val(); this.handleSearchType(type); } - if ((this.mode == 'edit' || this.mode == 'search') && this.params.options && this.params.options.length) { + if ( + (this.mode === 'edit' || this.mode === 'search') && + this.params.options && + this.params.options.length + ) { this.$element.autocomplete({ minChars: 0, lookup: this.params.options, maxHeight: 200, - beforeRender: function ($c) { + beforeRender: ($c) => { if (this.$element.hasClass('input-sm')) { $c.addClass('small'); } - }.bind(this), - formatResult: function (suggestion) { + }, + formatResult: (suggestion) => { return this.getHelper().escapeString(suggestion.value); - }.bind(this), - lookupFilter: function (suggestion, query, queryLowerCase) { + }, + lookupFilter: (suggestion, query, queryLowerCase) => { if (suggestion.value.toLowerCase().indexOf(queryLowerCase) === 0) { - if (suggestion.value.length === queryLowerCase.length) return false; + if (suggestion.value.length === queryLowerCase.length) { + return false; + } + return true; } + return false; }, - onSelect: function () { + onSelect: () => { this.trigger('change'); - }.bind(this) + }, }); + this.$element.attr('autocomplete', 'espo-' + this.name); - this.$element.on('focus', function () { - if (this.$element.val()) return; + this.$element.on('focus', () => { + if (this.$element.val()) { + return; + } + this.$element.autocomplete('onValueChange'); - }.bind(this)); - this.once('render', function () { + }); + + this.once('render', () => { this.$element.autocomplete('dispose'); - }, this); - this.once('remove', function () { + }); + + this.once('remove', () => { this.$element.autocomplete('dispose'); - }, this); + }); } if (this.mode === 'search') { - this.$el.find('select.search-type').on('change', function () { + this.$el.find('select.search-type').on('change', () => { this.trigger('change'); - }.bind(this)); + }); - this.$element.on('input', function () { + this.$element.on('input', () => { this.trigger('change'); - }.bind(this)); + }); } }, fetch: function () { var data = {}; + var value = this.$element.val(); + if (this.params.trim || this.forceTrim) { if (typeof value.trim === 'function') { value = value.trim(); } } + data[this.name] = value || null; + return data; }, @@ -190,7 +214,7 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { var data; if (~['isEmpty', 'isNotEmpty'].indexOf(type)) { - if (type == 'isEmpty') { + if (type === 'isEmpty') { data = { type: 'or', value: [ @@ -207,8 +231,9 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { data: { type: type } - } - } else { + }; + } + else { data = { type: 'and', value: [ @@ -228,27 +253,33 @@ define('views/fields/varchar', 'views/fields/base', function (Dep) { } } } + return data; - } else { + } + else { var value = this.$element.val().toString().trim(); + value = value.trim(); + if (value) { data = { value: value, type: type, data: { type: type - } - } + }, + }; + return data; } } + return false; }, getSearchType: function () { return this.getSearchParamsData().type || this.searchParams.typeFront || this.searchParams.type; - } + }, }); });