[FIX] web: fix reactivity in custom filter menu

Before: On a map view, a bunch of points get loaded one by one. Each of
them triggering a new render of the controller. Currently, the useModel
hook does a deep render no matter what. If you are trying to set a
custom filter un the filter menu in the control panel, the content would
systematically diseapear (rerendered) when a new map point loaded.

After: To prevent this, setting the input node as t-model is a solution.
It allows owl to keep track of the value of the input and correctly
set it back when a render occurs.

closes odoo/odoo#100421

Signed-off-by: Géry Debongnie <ged@odoo.com>
This commit is contained in:
Simon Genin (ges)
2022-09-26 15:47:44 +02:00
parent 5e7da9c8ca
commit 66289abd5e
3 changed files with 35 additions and 5 deletions
@@ -65,20 +65,20 @@
t-att-type="DECIMAL_POINT === '.' ? 'number' : 'text'"
t-attf-title="Number using {{ DECIMAL_POINT }} as decimal separator."
t-attf-pattern="[0-9]+([\\{{ DECIMAL_POINT }}][0-9]+)?"
t-att-value="condition.displayedValue"
t-model="condition.displayedValue"
t-on-change="ev => this.onValueChange(condition, ev)"
/>
<input t-elif="['integer', 'id'].includes(fieldType)"
class="o_input"
step="1"
type="number"
t-att-value="condition.displayedValue"
t-model="condition.displayedValue"
t-on-change="ev => this.onValueChange(condition, ev)"
/>
<input t-else=""
type="text"
class="o_input"
t-att-value="condition.displayedValue"
t-model="condition.displayedValue"
t-on-change="ev => this.onValueChange(condition, ev)"
/>
</span>
@@ -3,6 +3,7 @@
import {
click,
getFixture,
nextTick,
patchDate,
patchTimeZone,
patchWithCleanup,
@@ -743,4 +744,29 @@ QUnit.module("Search", (hooks) => {
"The delete button is shown as a trash icon"
);
});
QUnit.test("condition value is not lost on deep render", async function (assert) {
const component = await makeWithSearch({
serverData,
resModel: "foo",
Component: ControlPanel,
searchViewId: false,
searchMenuTypes: ["filter"],
});
await toggleFilterMenu(target);
await toggleAddCustomFilter(target);
await editConditionField(target, 0, "char_field");
await editConditionValue(target, 0, "Coucou", 0, false);
let charInput = target.querySelector(".o_generator_menu_value .o_input");
assert.strictEqual(charInput.value, "Coucou");
component.render(true);
await nextTick();
charInput = target.querySelector(".o_generator_menu_value .o_input");
assert.strictEqual(charInput.value, "Coucou");
});
});
+6 -2
View File
@@ -7,6 +7,7 @@ import {
getFixture,
mount,
mouseEnter,
nextTick,
triggerEvent,
} from "@web/../tests/helpers/utils";
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
@@ -175,7 +176,7 @@ export async function editConditionOperator(el, index, operator) {
await triggerEvent(select, null, "change");
}
export async function editConditionValue(el, index, value, valueIndex = 0) {
export async function editConditionValue(el, index, value, valueIndex = 0, triggerChange = true) {
const condition = findItem(el, `.o_filter_condition`, index);
const target = findItem(
condition,
@@ -183,7 +184,10 @@ export async function editConditionValue(el, index, value, valueIndex = 0) {
valueIndex
);
target.value = value;
await triggerEvent(target, null, "change");
if (triggerChange) {
triggerEvent(target, null, "change");
}
await nextTick();
}
export async function applyFilter(el) {