[FIX] web: don't update related daterange field when not in the DOM

This commit avoids to update the related daterange field (aka. end date
when changing start date, and vice-versa) when this field is not present
in the DOM (could be 'invisible' field or hidden column in list).

Steps to reproduce:
- Open Field Service
- Switch to list view
- hide the End date column
- select record(s) to enter multi edit mode
- click on the Start date of the selected record to open the date range
  picker
- select a new range
- click Apply
==> Error saying that cannot read setStartDate from undefined

task-3200845

closes odoo/odoo#115766

X-original-commit: 9e00bd26ac43bfdaacd74de324ead84e4154a912
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Pierre Paridans
2023-03-20 09:03:46 +01:00
parent 10f0b2ef77
commit 1ea7a3d6ad
2 changed files with 157 additions and 0 deletions
@@ -139,6 +139,10 @@ export class DateRangeField extends Component {
const input = document.querySelector(
`.o_field_daterange[name='${this.relatedDateRangeField}'] input`
);
if (!input) {
// Don't attempt to update the related daterange field if not present in the DOM
return;
}
const target = window.$(input).data("daterangepicker");
target.setStartDate(picker.startDate);
target.setEndDate(picker.endDate);
@@ -815,4 +815,157 @@ QUnit.module("Fields", (hooks) => {
);
}
);
QUnit.test(
"Render with one visible field: start date [REQUIRE FOCUS]",
async function (assert) {
serverData.models.partner.fields.date_end = { string: "Date End", type: "date" };
serverData.models.partner.records[0].date_end = "2017-02-08";
await makeView({
type: "form",
resModel: "partner",
resId: 1,
serverData,
arch: `
<form>
<field name="date" widget="daterange" options="{'related_end_date': 'date_end'}"/>
<field name="date_end" widget="daterange" options="{'related_start_date': 'date'}" invisible="1"/>
</form>`,
});
let fields = target.querySelectorAll(".o_field_daterange");
// Check date range picker initialization
assert.containsOnce(
document.body,
".daterangepicker",
"should initialize 1 date range picker"
);
// open the start date
await click(fields[0].querySelector("input"));
const datepicker = document.querySelector(
`.daterangepicker[data-name="${fields[0].getAttribute("name")}"]`
);
assert.isVisible(datepicker, "date range picker should be opened");
assert.strictEqual(
datepicker.querySelector(".active.start-date").textContent,
"3",
"active start date should be '3' in date range picker"
);
assert.strictEqual(
datepicker.querySelector(".active.end-date").textContent,
"8",
"active end date should be '8' in date range picker"
);
// Change date
await triggerEvent(
datepicker,
".drp-calendar.left .available[data-title='r2c4']",
"mousedown"
);
await triggerEvent(
datepicker,
".drp-calendar.right .available[data-title='r2c0']",
"mousedown"
);
await click(datepicker.querySelector(".applyBtn"));
// Check date after change
assert.isNotVisible(datepicker, "date range picker should be closed");
assert.strictEqual(
fields[0].querySelector("input").value,
"02/16/2017",
"the date should be '02/16/2017'"
);
// Save
await clickSave(target);
fields = target.querySelectorAll(".o_field_daterange");
// Check date after save
assert.strictEqual(
fields[0].querySelector("input").value,
"02/16/2017",
"the start date should be '02/16/2017' after save"
);
}
);
QUnit.test("Render with one visible field: end date [REQUIRE FOCUS]", async function (assert) {
serverData.models.partner.fields.date_end = { string: "Date End", type: "date" };
serverData.models.partner.records[0].date_end = "2017-02-08";
await makeView({
type: "form",
resModel: "partner",
resId: 1,
serverData,
arch: `
<form>
<field name="date" widget="daterange" options="{'related_end_date': 'date_end'}" invisible="1"/>
<field name="date_end" widget="daterange" options="{'related_start_date': 'date'}"/>
</form>`,
});
let fields = target.querySelectorAll(".o_field_daterange");
// Check date range picker initialization
assert.containsOnce(
document.body,
".daterangepicker",
"should initialize 1 date range picker"
);
// open the end date
await click(fields[0].querySelector("input"));
const datepicker = document.querySelector(
`.daterangepicker[data-name="${fields[0].getAttribute("name")}"]`
);
assert.isVisible(datepicker, "date range picker should be opened");
assert.strictEqual(
datepicker.querySelector(".active.start-date").textContent,
"3",
"active start date should be '3' in date range picker"
);
assert.strictEqual(
datepicker.querySelector(".active.end-date").textContent,
"8",
"active end date should be '8' in date range picker"
);
// Change date
await triggerEvent(
datepicker,
".drp-calendar.left .available[data-title='r2c4']",
"mousedown"
);
await triggerEvent(
datepicker,
".drp-calendar.right .available[data-title='r2c0']",
"mousedown"
);
await click(datepicker.querySelector(".applyBtn"));
// Check date after change
assert.isNotVisible(datepicker, "date range picker should be closed");
assert.strictEqual(
fields[0].querySelector("input").value,
"03/12/2017",
"the date should be '03/12/2017'"
);
// Save
await clickSave(target);
fields = target.querySelectorAll(".o_field_daterange");
// Check date after save
assert.strictEqual(
fields[0].querySelector("input").value,
"03/12/2017",
"the end date should be '02/13/2017' after save"
);
});
});