[FIX] web: Allow TempusDominus to parse its own values

Before this commit, in other numbering systems than "latn", the time
pickers did not allow to select hours/minutes/seconds. This was because
the lib (TempusDominus) would use `parseInt` internally to retrieve the
selected value, which was not a latin number in other numbering systems.

This commit changes 2 things directly in the lib file:

- allow the internal `getMoment` function to accept a second 'format'
parameter;

- use that same `getMoment` function to parse the text of the selected
value, effectively using moment to both parse and format the values
displayed in the picker and ensuring consistency.

OPW-3258034

closes odoo/odoo#126711

X-original-commit: de6bc96afdc61b57493bcbde0b8f3479cc6ebd71
Signed-off-by: Bruno Boi (boi) <boi@odoo.com>
Signed-off-by: Julien Mougenot (jum) <jum@odoo.com>
This commit is contained in:
Julien Mougenot
2023-06-30 13:08:23 +02:00
parent 3a661beb3a
commit a540f0f53c
2 changed files with 40 additions and 6 deletions
@@ -802,17 +802,22 @@ var DateTimePicker = function ($, moment) {
//public
DateTimePicker.prototype.getMoment = function getMoment(d) {
DateTimePicker.prototype.getMoment = function getMoment(d, f) { // ODOO FIX: give optional format
var returnMoment = void 0;
// ODOO FIX: default to original `parseFormats` attribute
if (!f) {
f = this.parseFormats;
}
if (d === undefined || d === null) {
returnMoment = moment(); //TODO should this use format? and locale?
} else if (this._hasTimeZone()) {
// There is a string to parse and a default time zone
// parse with the tz function which takes a default time zone if it is not in the format string
returnMoment = moment.tz(d, this.parseFormats, this._options.locale, this._options.useStrict, this._options.timeZone);
returnMoment = moment.tz(d, f, this._options.locale, this._options.useStrict, this._options.timeZone); // ODOO FIX: use format argument
} else {
returnMoment = moment(d, this.parseFormats, this._options.locale, this._options.useStrict);
returnMoment = moment(d, f, this._options.locale, this._options.useStrict); // ODOO FIX: use format argument
}
if (this._hasTimeZone()) {
@@ -2434,7 +2439,7 @@ var TempusDominusBootstrap4 = function ($) {
break;
case 'selectHour':
{
var hour = parseInt($(e.target).text(), 10);
var hour = this.getMoment($(e.target).text(), this.use24Hours ? 'HH' : 'hh').hour(); // ODOO FIX: use moment format to get the proper value (not necessarily latn numbers)
if (!this.use24Hours) {
if (lastPicked.hours() >= 12) {
@@ -2456,7 +2461,7 @@ var TempusDominusBootstrap4 = function ($) {
break;
}
case 'selectMinute':
this._setValue(lastPicked.clone().minutes(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex());
this._setValue(lastPicked.clone().minutes(this.getMoment($(e.target).text(), 'mm').minute()), this._getLastPickedDateIndex()); // ODOO FIX: use moment format to get the proper value (not necessarily latn numbers)
if (!this._isEnabled('a') && !this._isEnabled('s') && !this._options.keepOpen && !this._options.inline) {
this.hide();
} else {
@@ -2464,7 +2469,7 @@ var TempusDominusBootstrap4 = function ($) {
}
break;
case 'selectSecond':
this._setValue(lastPicked.clone().seconds(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex());
this._setValue(lastPicked.clone().seconds(this.getMoment($(e.target).text(), 'ss').second()), this._getLastPickedDateIndex()); // ODOO FIX: use moment format to get the proper value (not necessarily latn numbers)
if (!this._isEnabled('a') && !this._options.keepOpen && !this._options.inline) {
this.hide();
} else {
@@ -14,6 +14,7 @@ import {
editSelect,
getFixture,
patchTimeZone,
patchWithCleanup,
triggerEvent,
triggerEvents,
} from "@web/../tests/helpers/utils";
@@ -544,4 +545,32 @@ QUnit.module("Fields", (hooks) => {
await click(target.querySelector("label.o_form_label"));
assert.containsOnce(target, ".o_datetime_picker", "datepicker should be opened");
});
QUnit.test("datetime field: use picker with arabic numbering system", async (assert) => {
patchWithCleanup(luxon.Settings, {
defaultLocale: "ar-001",
defaultNumberingSystem: "arab",
});
await makeView({
type: "form",
resModel: "partner",
resId: 1,
serverData,
arch: /* xml */ `
<form string="Partners">
<field name="datetime" />
</form>
`,
});
const getInput = () => target.querySelector("[name=datetime] input");
assert.strictEqual(getInput().value, "٠٢/٠٨/٢٠١٧ ١١:٠٠:٠٠");
await click(getInput());
await editSelect(getTimePickers()[0][1], null, 45);
assert.strictEqual(getInput().value, "٠٢/٠٨/٢٠١٧ ١١:٤٥:٠٠");
});
});