[FIX] web: crash in editable lists with date field
Assume an editable list view with a date(time) widget, click to edit a line, focus the date field (the datepicker opens), press ESC: there is a crash in the lib, and the datepicker remains open forever. This fix is twofold: - we added a check in the lib to prevent it from crashing (it is easily reproducible: it crashes when an opened datepicker is removed from the DOM). - we added an event handler of ESC keydown event to hide the datepicker before the field is removed from the DOM.
This commit is contained in:
@@ -2754,7 +2754,8 @@ var TempusDominusBootstrap4 = function ($) {
|
|||||||
if ($target.length === 0) {
|
if ($target.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (config._options.debug || window.debug) {
|
// /!\ ODOO FIX: check on 'config' existence added by odoo
|
||||||
|
if (config && config._options.debug || window.debug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TempusDominusBootstrap4._jQueryInterface.call($target, 'hide', event);
|
TempusDominusBootstrap4._jQueryInterface.call($target, 'hide', event);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ var DateWidget = Widget.extend({
|
|||||||
'change.datetimepicker': 'changeDatetime',
|
'change.datetimepicker': 'changeDatetime',
|
||||||
'change .o_datepicker_input': 'changeDatetime',
|
'change .o_datepicker_input': 'changeDatetime',
|
||||||
'input input': '_onInput',
|
'input input': '_onInput',
|
||||||
|
'keydown': '_onKeydown',
|
||||||
'show.datetimepicker': '_onDateTimePickerShow',
|
'show.datetimepicker': '_onDateTimePickerShow',
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -239,6 +240,17 @@ var DateWidget = Widget.extend({
|
|||||||
this.$input.select();
|
this.$input.select();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {KeyEvent} ev
|
||||||
|
*/
|
||||||
|
_onKeydown: function (ev) {
|
||||||
|
if (ev.which === $.ui.keyCode.ESCAPE) {
|
||||||
|
this.__libInput++;
|
||||||
|
this.$el.datetimepicker('hide');
|
||||||
|
this.__libInput--;
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Prevents 'input' events triggered by the library to bubble up, as they
|
* Prevents 'input' events triggered by the library to bubble up, as they
|
||||||
* might have unwanted effects (like triggering 'field_changed' events in
|
* might have unwanted effects (like triggering 'field_changed' events in
|
||||||
|
|||||||
@@ -298,7 +298,42 @@ QUnit.module('Views', {
|
|||||||
list.destroy();
|
list.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('editable list datetimepicker destroy widget', async function (assert) {
|
QUnit.test('editable list datetimepicker destroy widget (edition)', async function (assert) {
|
||||||
|
assert.expect(6);
|
||||||
|
var eventPromise = testUtils.makeTestPromise();
|
||||||
|
|
||||||
|
var list = await createView({
|
||||||
|
View: ListView,
|
||||||
|
model: 'foo',
|
||||||
|
data: this.data,
|
||||||
|
arch: '<tree editable="top">' +
|
||||||
|
'<field name="date"/>' +
|
||||||
|
'</tree>',
|
||||||
|
});
|
||||||
|
list.$el.on({
|
||||||
|
'show.datetimepicker': async function () {
|
||||||
|
assert.containsOnce(list, '.o_selected_row');
|
||||||
|
assert.containsOnce($('body'), '.bootstrap-datetimepicker-widget');
|
||||||
|
|
||||||
|
await testUtils.fields.triggerKeydown(list.$('.o_datepicker_input'), 'escape');
|
||||||
|
|
||||||
|
assert.containsNone(list, '.o_selected_row');
|
||||||
|
assert.containsNone($('body'), '.bootstrap-datetimepicker-widget');
|
||||||
|
|
||||||
|
eventPromise.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.containsN(list, '.o_data_row', 4);
|
||||||
|
assert.containsNone(list, '.o_selected_row');
|
||||||
|
|
||||||
|
await testUtils.dom.click(list.$('.o_data_cell:first'));
|
||||||
|
|
||||||
|
await eventPromise;
|
||||||
|
list.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('editable list datetimepicker destroy widget (new line)', async function (assert) {
|
||||||
assert.expect(7);
|
assert.expect(7);
|
||||||
var eventPromise = testUtils.makeTestPromise();
|
var eventPromise = testUtils.makeTestPromise();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user