[FIX] web: unselect current row before changing page

The issue here is quite simple.  If we are editing a multipage one2many
field, then we click on the pager, we need to properly unselect the
current row.

If we do not do that, then we can enter invalid data.  For example,
assume that there is a readonly field. We click on add, it creates a
(virtual) record with no value for that field.  When we click on the
pager, we select the next page, and bypass all validation.
This commit is contained in:
Géry Debongnie
2018-03-14 17:03:18 +01:00
parent 4fd9db52a2
commit 4586b876f2
2 changed files with 84 additions and 2 deletions
@@ -876,10 +876,15 @@ var FieldX2Many = AbstractField.extend({
this.pager = new Pager(this, this.value.count, this.value.offset + 1, this.value.limit, {
single_page_hidden: true,
withAccessKey: false,
validate: function () {
var isList = self.view.arch.tag === 'tree';
// TODO: we should have some common method in the basic renderer...
return isList ? self.renderer.unselectRow() : $.when();
},
});
this.pager.on('pager_changed', this, function (new_state) {
this.trigger_up('load', {
id: this.value.id,
self.trigger_up('load', {
id: self.value.id,
limit: new_state.limit,
offset: new_state.current_min - 1,
on_success: function (value) {
@@ -4361,6 +4361,83 @@ QUnit.module('relational_fields', {
form.destroy();
});
QUnit.test('editable one2many list, required field and pager', function (assert) {
assert.expect(1);
this.data.turtle.records.push({id:4, turtle_foo: 'stephen hawking'});
this.data.turtle.fields.turtle_foo.required = true;
this.data.partner.records[0].turtles = [1,2,3,4];
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<field name="turtles">' +
'<tree editable="bottom" limit="3">' +
'<field name="turtle_foo"/>' +
'</tree>' +
'</field>' +
'</form>',
res_id: 1,
});
// add a (empty) record
form.$buttons.find('.o_form_button_edit').click();
form.$('.o_field_x2many_list_row_add a').click();
// go on next page. The new record is not valid and should be discarded
form.$('.o_pager_next').click();
assert.strictEqual(form.$('tr.o_data_row').length, 1,
"should have 1 data rows");
form.destroy();
});
QUnit.test('editable one2many list, required field, pager and confirm discard', function (assert) {
assert.expect(3);
this.data.turtle.records.push({id:4, turtle_foo: 'stephen hawking'});
this.data.turtle.fields.turtle_foo.required = true;
this.data.partner.records[0].turtles = [1,2,3,4];
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<field name="turtles">' +
'<tree editable="bottom" limit="3">' +
'<field name="turtle_foo"/>' +
'<field name="turtle_int"/>' +
'</tree>' +
'</field>' +
'</form>',
res_id: 1,
});
// add a record with a dirty state, but not valid
form.$buttons.find('.o_form_button_edit').click();
form.$('.o_field_x2many_list_row_add a').click();
form.$('input[name="turtle_int"]').val(4321).trigger('input');
// go to next page. The new record is not valid, but dirty. we should
// see a confirm dialog
form.$('.o_pager_next').click();
assert.strictEqual(form.$('.o_cp_pager').text().trim(), '1-3 / 4',
"pager should still display the correct total");
// click on cancel
$('.modal .modal-footer .btn-default').click(); // click on cancel
assert.strictEqual(form.$('.o_cp_pager').text().trim(), '1-3 / 4',
"pager should again display the correct total");
assert.strictEqual(form.$('.o_field_one2many input.o_field_invalid').length, 1,
"there should be an invalid input in the one2many");
form.destroy();
});
QUnit.test('unselecting a line with missing required data', function (assert) {
assert.expect(5);