diff --git a/addons/web/static/src/js/views/basic/basic_view.js b/addons/web/static/src/js/views/basic/basic_view.js index ad15931c6c6..22900e12d6b 100644 --- a/addons/web/static/src/js/views/basic/basic_view.js +++ b/addons/web/static/src/js/views/basic/basic_view.js @@ -276,33 +276,7 @@ var BasicView = AbstractView.extend({ attrs.mode = mode; if (mode in attrs.views) { var view = attrs.views[mode]; - var defaultOrder = view.arch.attrs.default_order; - if (defaultOrder) { - // process the default_order, which is like 'name,id desc' - // but we need it like [{name: 'name', asc: true}, {name: 'id', asc: false}] - attrs.orderedBy = _.map(defaultOrder.split(','), function (order) { - order = order.trim().split(' '); - return {name: order[0], asc: order[1] !== 'desc'}; - }); - } else { - // if there is a field with widget `handle`, the x2many - // needs to be ordered by this field to correctly display - // the records - var handleField = _.find(view.arch.children, function (child) { - return child.attrs && child.attrs.widget === 'handle'; - }); - if (handleField) { - attrs.orderedBy = [{name: handleField.attrs.name, asc: true}]; - } - } - - attrs.columnInvisibleFields = {}; - _.each(view.arch.children, function (child) { - if (child.attrs && child.attrs.modifiers) { - attrs.columnInvisibleFields[child.attrs.name] = - child.attrs.modifiers.column_invisible || false; - } - }); + this._processSubViewAttrs(view, attrs); } } if (attrs.Widget.prototype.fieldsToFetch) { @@ -398,6 +372,43 @@ var BasicView = AbstractView.extend({ } return node.tag !== 'arch'; }, + /** + * Processes in place the subview attributes (in particular, + * `default_order``and `column_invisible`). + * + * @private + * @param {Object} view - the field subview + * @param {Object} attrs - the field attributes (from the xml) + */ + _processSubViewAttrs: function (view, attrs) { + var defaultOrder = view.arch.attrs.default_order; + if (defaultOrder) { + // process the default_order, which is like 'name,id desc' + // but we need it like [{name: 'name', asc: true}, {name: 'id', asc: false}] + attrs.orderedBy = _.map(defaultOrder.split(','), function (order) { + order = order.trim().split(' '); + return {name: order[0], asc: order[1] !== 'desc'}; + }); + } else { + // if there is a field with widget `handle`, the x2many + // needs to be ordered by this field to correctly display + // the records + var handleField = _.find(view.arch.children, function (child) { + return child.attrs && child.attrs.widget === 'handle'; + }); + if (handleField) { + attrs.orderedBy = [{name: handleField.attrs.name, asc: true}]; + } + } + + attrs.columnInvisibleFields = {}; + _.each(view.arch.children, function (child) { + if (child.attrs && child.attrs.modifiers) { + attrs.columnInvisibleFields[child.attrs.name] = + child.attrs.modifiers.column_invisible || false; + } + }); + }, }); return BasicView; diff --git a/addons/web/static/src/js/views/form/form_view.js b/addons/web/static/src/js/views/form/form_view.js index 10fc9a12b20..607f9f54a89 100644 --- a/addons/web/static/src/js/views/form/form_view.js +++ b/addons/web/static/src/js/views/form/form_view.js @@ -92,6 +92,7 @@ var FormView = BasicView.extend({ for (var viewName in views) { // clone to make runbot green? attrs.views[viewName] = self._processFieldsView(views[viewName], viewName); + self._processSubViewAttrs(attrs.views[viewName], attrs); } self._setSubViewLimit(attrs); })); diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index d5b23955bde..b16d812993e 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -2595,6 +2595,36 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('one2many with default_order on view not inline', function (assert) { + assert.expect(1); + + this.data.partner.records[0].turtles = [1,2,3]; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
', + archs: { + 'turtle,false,list': '' + + '' + + '' + + '', + }, + res_id: 1, + }); + assert.strictEqual(form.$('.o_field_one2many .o_list_view .o_data_row').text(), "9blip21kawa0yop", + "the default order should be correctly applied"); + form.destroy(); + }); + QUnit.test('embedded one2many with widget', function (assert) { assert.expect(1); @@ -11623,6 +11653,51 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('one2many column_invisible on view not inline', function (assert) { + assert.expect(4); + + this.data.partner.records[0].p = [2]; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + archs: { + 'partner,false,list': '' + + '' + + '' + + '', + }, + }); + assert.strictEqual(form.$('th').length, 2, + "should be 2 columns in the one2many"); + form.$buttons.find('.o_form_button_edit').click(); + form.$('.o_field_many2one[name="product_id"] input').click(); + $('li.ui-menu-item a:contains(xpad)').trigger('mouseenter').click(); + assert.strictEqual(form.$('th').length, 1, + "should be 1 column when the product_id is set"); + form.$('.o_field_many2one[name="product_id"] input').val('').trigger('keyup'); + assert.strictEqual(form.$('th').length, 2, + "should be 2 columns in the one2many when product_id is not set"); + form.$('.o_field_boolean[name="bar"] input').click(); + assert.strictEqual(form.$('th').length, 1, + "should be 1 column after the value change"); + form.destroy(); + }); + QUnit.module('TabNavigation'); QUnit.test('when Navigating to a many to one with tabs, it receives the focus on the add new line link', function (assert) {