summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2017-03-31 13:29:29 +0200
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commitc5d5d7a0ff05d1664e50e5239e5b5efa77a032f6 (patch)
treefc6bf94e30dc1a8627dc5ab17a6664ed39b417f6
parentd6d7923c679250f6091e06e9f6dcbcd4fd6230da (diff)
[FIX] web: monetary field was adding DOM at each rendering
Before this commit, the `render` method of the monetary field added the <input/> and currency elements without removing the previous ones. As this was called on each related `onchange`, the DOM was growing at each of these changes.
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js51
-rw-r--r--addons/web/static/test/fields/basic_fields_tests.js14
2 files changed, 40 insertions, 25 deletions
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index dcfc0671b0a..ffba3158d43 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -144,22 +144,27 @@ var InputField = DebouncedField.extend({
* Formats an input element for edit mode. This is in a separate function so
* extending widgets can use it on their input without having input as tagName.
*
- * @param {jQueryElement} $input
* @private
+ * @param {jQuery|undefined} $input
+ * The <input/> element to prepare and save as the $input attribute.
+ * If no element is given, the <input/> is created.
+ * @returns {jQuery} the prepared this.$input element
*/
_prepareInput: function ($input) {
- $input.addClass('o_form_input');
- $input.attr('type', 'text');
- if (this.attrs.placeholder) {
- $input.attr('placeholder', this.attrs.placeholder);
- }
- $input.attr('id', this.idForLabel);
- // save cursor position to restore it after updating value
+ this.$input = $input || $("<input/>");
+ this.$input.addClass('o_form_input');
+ this.$input.attr({
+ type: 'text',
+ id: this.idForLabel,
+ placeholder: this.attrs.placeholder || "",
+ });
+ // Save cursor position to restore it after updating value
var selectionStart = this.$input[0].selectionStart;
var selectionEnd = this.$input[0].selectionEnd;
this.$input.val(this._formatValue(this.value));
this.$input[0].selectionStart = selectionStart;
this.$input[0].selectionEnd = selectionEnd;
+ return this.$input;
},
/**
* Formats the HTML input tag for edit mode and stores selection status.
@@ -170,8 +175,7 @@ var InputField = DebouncedField.extend({
_renderEdit: function () {
// Keep a reference to the input so $el can become something else
// without losing track of the actual input.
- this.$input = this.$el;
- this._prepareInput(this.$input);
+ this._prepareInput(this.$el);
},
/**
* Resets the content to the formated value in readonly mode.
@@ -368,20 +372,21 @@ var FieldMonetary = InputField.extend({
* @private
*/
_renderEdit: function () {
- if (this.nodeOptions.currency_id) {
- var currency = session.get_currency(this.nodeOptions.currency_id);
- var $currencySymbol = $('<span>').text(currency.symbol);
- this.$input = $('<input>');
- this._prepareInput(this.$input);
- this.$input.appendTo(this.$el);
- if (currency.position === "after") {
- this.$el.append($currencySymbol);
- } else {
- this.$el.prepend($currencySymbol);
- }
- }
- else {
+ if (!this.nodeOptions.currency_id) {
this._super.apply(this, arguments);
+ return;
+ }
+
+ this.$el.empty();
+ // Prepare and add the input
+ this._prepareInput().appendTo(this.$el);
+ // prepare and add the currency symbol
+ var currency = session.get_currency(this.nodeOptions.currency_id);
+ var $currencySymbol = $('<span>', {text: currency.symbol});
+ if (currency.position === "after") {
+ this.$el.append($currencySymbol);
+ } else {
+ this.$el.prepend($currencySymbol);
}
},
diff --git a/addons/web/static/test/fields/basic_fields_tests.js b/addons/web/static/test/fields/basic_fields_tests.js
index 287134b43a1..8cea1900c7c 100644
--- a/addons/web/static/test/fields/basic_fields_tests.js
+++ b/addons/web/static/test/fields/basic_fields_tests.js
@@ -1332,12 +1332,17 @@ QUnit.module('basic_fields', {
list.destroy();
});
-
QUnit.test('monetary field with real monetary field in model', function (assert) {
- assert.expect(2);
+ assert.expect(3);
this.data.partner.fields.qux.type = "monetary";
+ this.data.partner.onchanges = {
+ bar: function (obj) {
+ obj.qux = obj.bar ? 100 : obj.qux;
+ },
+ };
+
var form = createView({
View: FormView,
model: 'partner',
@@ -1346,6 +1351,7 @@ QUnit.module('basic_fields', {
'<sheet>' +
'<field name="qux"/>' +
'<field name="currency_id" invisible="1"/>' +
+ '<field name="bar"/>' +
'</sheet>' +
'</form>',
res_id: 5,
@@ -1362,6 +1368,10 @@ QUnit.module('basic_fields', {
assert.strictEqual(form.$('.o_form_field_monetary > input').val(), "9.10",
"input value in edition should only contain the value, without the currency");
+ form.$('input[type="checkbox"]').click(); // Change the field on which the monetary depends
+ assert.strictEqual(form.$('.o_form_field_monetary > input').length, 1,
+ "After the onchange, the monetary <input/> should not have been duplicated");
+
form.destroy();
});