From d9ff1e6c69e7aaf45525433edff820e03199df3b Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Wed, 6 Jan 2021 13:53:23 +0000 Subject: [PATCH] [FIX] web: fix duplication on phone+sms button rerendering STEPS: * Add related phone field to a form (e.g. partner_id.phone to sale.order form) * Use widget "phone" + activate sms feature * Create a record * Click edit, select partner that has phone specified (e.g. +1 234), edit partner's phone (e.g. +1 234 555), save BEFORE: ``+1 234 []SMS`` is converted to ``+1 234 555 +1 234 555`` AFTER: ``+1 234 555 []SMS`` WHY: * FieldPhone is inherited from FieldEmail https://github.com/odoo/odoo/blob/0de069b8ca9fb005ba5b076984f5677de25889ee/addons/web/static/src/js/fields/basic_fields.js#L1549 * sms module adds SMS button to ``$el`` https://github.com/odoo/odoo/blob/0de069b8ca9fb005ba5b076984f5677de25889ee/addons/sms/static/src/js/fields_phone_widget.js#L91 * So this commit filters ``$el`` before updating it This also solves the same issue but this time for the EmailField widget introduced at 2689915e3f47686f69729b95216acf9e930740fb --- opw-2425949 closes odoo/odoo#65879 X-original-commit: b25104bae7f38d4d1de182176d239b1b7c8f803d Signed-off-by: Lucas Perais (lpe) --- .../sms/static/src/js/fields_phone_widget.js | 1 - addons/sms/static/tests/sms_widget_test.js | 50 +++++++++++++++++++ .../web/static/src/js/fields/basic_fields.js | 1 + .../static/tests/fields/basic_fields_tests.js | 42 ++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/addons/sms/static/src/js/fields_phone_widget.js b/addons/sms/static/src/js/fields_phone_widget.js index 8e76124f164..76250a832d1 100644 --- a/addons/sms/static/src/js/fields_phone_widget.js +++ b/addons/sms/static/src/js/fields_phone_widget.js @@ -90,7 +90,6 @@ Phone.include({ $composerButton.on('click', this._onClickSMS.bind(this)); this.$el = this.$el.add($composerButton); } - return def; }, }); diff --git a/addons/sms/static/tests/sms_widget_test.js b/addons/sms/static/tests/sms_widget_test.js index 8d27965b9c1..6b12ab08223 100644 --- a/addons/sms/static/tests/sms_widget_test.js +++ b/addons/sms/static/tests/sms_widget_test.js @@ -15,11 +15,13 @@ QUnit.module('fields', { fields: { message: {string: "message", type: "text"}, foo: {string: "Foo", type: "char", default: "My little Foo Value"}, + mobile: {string: "mobile", type: "text"}, }, records: [{ id: 1, message: "", foo: 'yop', + mobile: "+32494444444", }, { id: 2, message: "", @@ -175,5 +177,53 @@ QUnit.module('fields', { list.destroy(); }); + + QUnit.test('readonly sms phone field is properly rerendered after been changed by onchange', async function (assert) { + assert.expect(4); + + const NEW_PHONE = '+32595555555'; + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + // onchange to update mobile in readonly mode directly + '' + // readonly only, we don't want to go through write mode + '' + + '' + + '
', + res_id: 1, + viewOptions: {mode: 'edit'}, + mockRPC: function (route, args) { + if (args.method === 'onchange') { + return Promise.resolve({ + value: { + mobile: NEW_PHONE, // onchange to update mobile in readonly mode directly + }, + }); + } + return this._super.apply(this, arguments); + }, + }); + // check initial rendering + assert.strictEqual(form.$('.o_field_phone').text(), "+32494444444", + 'Initial Phone text should be set'); + assert.strictEqual(form.$('.o_field_phone_sms').text(), 'SMS', + 'SMS button label should be rendered'); + + // trigger the onchange to update phone field, but still in readonly mode + await testUtils.fields.editInput($('input[name="foo"]'), 'someOtherFoo'); + + // check rendering after changes + assert.strictEqual(form.$('.o_field_phone').text(), NEW_PHONE, + 'Phone text should be updated'); + assert.strictEqual(form.$('.o_field_phone_sms').text(), 'SMS', + 'SMS button label should not be changed'); + + form.destroy(); + }); }); }); diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 93b82312b89..ed7a06aa52d 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1588,6 +1588,7 @@ var FieldEmail = InputField.extend({ */ _renderReadonly: function () { if (this.value) { + this.el.innerHTML = ''; this.el.classList.add("o_form_uri", "o_text_overflow"); const anchorEl = Object.assign(document.createElement('a'), { text: this.value, diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index 768ba833547..c7024e67830 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -1221,6 +1221,48 @@ QUnit.module('basic_fields', { form.destroy(); }); + QUnit.test('readonly email field field is properly rerendered after been changed by onchange', async function (assert) { + assert.expect(2); + + this.data.partner.records[0].foo = 'dolores.abernathy@delos'; + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + // onchange to update mobile in readonly mode directly + '' + // readonly only, we don't want to go through write mode + '' + + '' + + '
', + res_id: 1, + viewOptions: {mode: 'edit'}, + mockRPC: function (route, args) { + if (args.method === 'onchange') { + return Promise.resolve({ + value: { + foo: 'lara.espin@unknown', // onchange to update foo in readonly mode directly + }, + }); + } + return this._super.apply(this, arguments); + }, + }); + // check initial rendering + assert.strictEqual(form.$('.o_field_email').text(), 'dolores.abernathy@delos', + 'Initial email text should be set'); + + // trigger the onchange to update phone field, but still in readonly mode + await testUtils.fields.editInput($('input[name="int_field"]'), '3'); + + // check rendering after changes + assert.strictEqual(form.$('.o_field_email').text(), 'lara.espin@unknown', + 'email text should be updated'); + + form.destroy(); + }); QUnit.module('FieldChar');