diff --git a/addons/web/static/src/views/fields/ace/ace_field.js b/addons/web/static/src/views/fields/ace/ace_field.js index e7c87b0e443..561792652dd 100644 --- a/addons/web/static/src/views/fields/ace/ace_field.js +++ b/addons/web/static/src/views/fields/ace/ace_field.js @@ -7,7 +7,7 @@ import { registry } from "@web/core/registry"; import { formatText } from "../formatters"; import { standardFieldProps } from "../standard_field_props"; -const { Component, onWillStart, useEffect, useRef } = owl; +const { Component, onWillStart, onWillUpdateProps, useEffect, useRef } = owl; export class AceField extends Component { setup() { @@ -25,9 +25,12 @@ export class AceField extends Component { return Promise.all(proms); }); + onWillUpdateProps(this.updateAce); + useEffect( () => { this.setupAce(); + this.updateAce(this.props); return () => this.destroyAce(); }, () => [this.editorRef.el] @@ -52,31 +55,35 @@ export class AceField extends Component { useSoftTabs: true, }); + this.aceEditor.on("blur", this.onBlur.bind(this)); + } + + updateAce({ mode, readonly, value }) { + if (!this.aceEditor) { + return; + } + this.aceSession.setOptions({ - mode: `ace/mode/${this.props.mode === "xml" ? "qweb" : this.props.mode}`, + mode: `ace/mode/${mode === "xml" ? "qweb" : mode}`, }); this.aceEditor.setOptions({ - readOnly: this.props.readonly, - highlightActiveLine: !this.props.readonly, - highlightGutterLine: !this.props.readonly, + readOnly: readonly, + highlightActiveLine: !readonly, + highlightGutterLine: !readonly, }); this.aceEditor.renderer.setOptions({ - displayIndentGuides: !this.props.readonly, - showGutter: !this.props.readonly, + displayIndentGuides: !readonly, + showGutter: !readonly, }); - this.aceEditor.renderer.$cursorLayer.element.style.display = this.props.readonly - ? "none" - : "block"; + this.aceEditor.renderer.$cursorLayer.element.style.display = readonly ? "none" : "block"; - const formattedValue = formatText(this.props.value); + const formattedValue = formatText(value); if (this.aceSession.getValue() !== formattedValue) { this.aceSession.setValue(formattedValue); } - - this.aceEditor.on("blur", this.onBlur.bind(this)); } destroyAce() { diff --git a/addons/web/static/tests/views/fields/ace_editor_field_tests.js b/addons/web/static/tests/views/fields/ace_editor_field_tests.js index d3c4f84a57f..7e45300da30 100644 --- a/addons/web/static/tests/views/fields/ace_editor_field_tests.js +++ b/addons/web/static/tests/views/fields/ace_editor_field_tests.js @@ -1,6 +1,7 @@ /** @odoo-module **/ -import { getFixture, clickEdit, triggerEvents } from "@web/../tests/helpers/utils"; +import { clickEdit, getFixture, triggerEvents } from "@web/../tests/helpers/utils"; +import { pagerNext } from "@web/../tests/search/helpers"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -22,10 +23,8 @@ QUnit.module("Fields", (hooks) => { }, }, records: [ - { - id: 1, - foo: `yop`, - }, + { id: 1, foo: `yop` }, + { id: 2, foo: `blip` }, ], }, }, @@ -75,4 +74,24 @@ QUnit.module("Fields", (hooks) => { await triggerEvents(target, ".ace-view-editor textarea", ["focus", "click"]); assert.hasClass(target.querySelector(".ace-view-editor"), "ace_focus"); }); + + QUnit.test("AceEditorField is updated on value change", async (assert) => { + await makeView({ + type: "form", + resModel: "partner", + resId: 1, + resIds: [1, 2], + serverData, + arch: /* xml */ ` +
+ + `, + }); + + assert.ok(target.querySelector(".o_field_ace").textContent.includes("yop")); + + await pagerNext(target); + + assert.ok(target.querySelector(".o_field_ace").textContent.includes("blip")); + }); });