[FIX] web: FormStatusIndicator flickering
Purpose:
--------
Before this commit, if you edit a char field with an onchange in
an x2many, the FormStatusIndicator buttons will flicker.
How to reproduce:
-----------------
- Go to a form view with an x2many field in list mode
- Type a char in the char field of a record
- The FormStatusIndicator buttons are visible
- Click outside the char field
- An onchange is triggered
Before this commit:
The FormStatusIndicator buttons will disappear until the onchange returns.
After this commit:
The FormStatusIndicator buttons remain visible.
closes odoo/odoo#140179
Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
This commit is contained in:
@@ -53,7 +53,7 @@ export function useInputField(params) {
|
||||
* On blur, we consider the field no longer dirty, even if it were to be invalid.
|
||||
* However, if the field is invalid, the new value will not be committed to the model.
|
||||
*/
|
||||
function onChange(ev) {
|
||||
async function onChange(ev) {
|
||||
if (isDirty) {
|
||||
isDirty = false;
|
||||
let isInvalid = false;
|
||||
@@ -69,15 +69,12 @@ export function useInputField(params) {
|
||||
|
||||
if (!isInvalid) {
|
||||
pendingUpdate = true;
|
||||
Promise.resolve(
|
||||
component.props.record.update({ [component.props.name]: val })
|
||||
).then(() => {
|
||||
pendingUpdate = false;
|
||||
});
|
||||
lastSetValue = ev.target.value;
|
||||
}
|
||||
lastSetValue = inputRef.el.value;
|
||||
|
||||
component.props.record.model.bus.trigger("FIELD_IS_DIRTY", isDirty);
|
||||
await component.props.record.update({ [component.props.name]: val });
|
||||
pendingUpdate = false;
|
||||
component.props.record.model.bus.trigger("FIELD_IS_DIRTY", isDirty);
|
||||
}
|
||||
}
|
||||
}
|
||||
function onKeydown(ev) {
|
||||
|
||||
@@ -1110,4 +1110,58 @@ QUnit.module("Fields", (hooks) => {
|
||||
assert.containsNone(target, "[name='display_name'] input");
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test(
|
||||
"edit a char field should display the status indicator buttons without flickering",
|
||||
async function (assert) {
|
||||
serverData.models.partner.records[0].p = [2];
|
||||
serverData.models.partner.onchanges = {
|
||||
foo() {},
|
||||
};
|
||||
|
||||
const def = makeDeferred();
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="p">
|
||||
<tree editable="bottom">
|
||||
<field name="foo"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>`,
|
||||
async mockRPC(route, { method }) {
|
||||
if (method === "onchange") {
|
||||
assert.step("onchange");
|
||||
await def;
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".o_form_status_indicator_buttons.invisible",
|
||||
"form view is not dirty"
|
||||
);
|
||||
|
||||
await click(target, ".o_data_cell");
|
||||
await editInput(target, "[name='foo'] input", "a");
|
||||
assert.verifySteps(["onchange"]);
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".o_form_status_indicator_buttons:not(.invisible)",
|
||||
"form view is dirty"
|
||||
);
|
||||
|
||||
def.resolve();
|
||||
await nextTick();
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".o_form_status_indicator_buttons:not(.invisible)",
|
||||
"form view is dirty"
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user