[FIX] web: modifiers on <footer/> tag in form

Since the new views, buttons were extracted of the <footer/> tags and
placed directly in the buttons area. While this would be a good idea,
this was ignoring the modifiers placed on the <footer/> tags. Multiple
solutions were possible:

1) Leave the <footer/> tag as it is (like before the new views)

    This creates an useless <footer/> element in the DOM most of the
    time.

2) Propagate the <footer/> modifiers to its children.

    This requires some code to do the propagation and a modifier might
    be evaluated multiple times for nothing (for each child).

3) Allow only one <footer/> tag in form views and divide buttons in
   child <div/> elements.

    Only creates the necessary DOM elements and modifiers are evaluated
    only once.

While the third choice is obviously the better one, this commit is
implementing the first solution. Indeed, changing all the XML views
might not be a good idea in the current state.
This commit is contained in:
qsm-odoo
2017-04-19 15:33:40 +02:00
parent 9bf3e2a7fa
commit c33e535707
2 changed files with 47 additions and 4 deletions
@@ -133,13 +133,14 @@ var FormController = BasicController.extend({
* @param {jQueryElement} $node
*/
renderButtons: function ($node) {
var $footer = this.$('footer');
if (!this.defaultButtons && (!this.footerToButtons || !$footer.length)) {
var $footer = this.footerToButtons ? this.$('footer') : null;
var mustRenderFooterButtons = $footer && $footer.length;
if (!this.defaultButtons && !mustRenderFooterButtons) {
return;
}
this.$buttons = $('<div/>');
if (this.footerToButtons && $footer.length) {
this.$buttons.append($footer.detach().contents());
if (mustRenderFooterButtons) {
this.$buttons.append($footer);
} else {
this.$buttons.append(qweb.render("FormView.buttons", {widget: this}));
this.$buttons.on('click', '.o_form_button_edit', this._toEditMode.bind(this));
@@ -3047,5 +3047,47 @@ QUnit.module('Views', {
form.destroy();
});
QUnit.test('modifiers are considered on multiple <footer/> tags', function (assert) {
assert.expect(2);
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch:
'<form>' +
'<field name="bar"/>' +
'<footer attrs="{\'invisible\': [(\'bar\',\'=\',False)]}">' +
'<button>Hello</button>' +
'<button>World</button>' +
'</footer>' +
'<footer attrs="{\'invisible\': [(\'bar\',\'!=\',False)]}">' +
'<button>Foo</button>' +
'</footer>' +
'</form>',
res_id: 1,
viewOptions: {
footer_to_buttons: true,
mode: 'edit',
},
});
assert.deepEqual(getVisibleButtonTexts(), ["Hello", "World"],
"only the first button section should be visible");
form.$(".o_field_boolean input").click();
assert.deepEqual(getVisibleButtonTexts(), ["Foo"],
"only the second button section should be visible");
form.destroy();
function getVisibleButtonTexts() {
var $visibleButtons = form.$buttons.find('button').not('.o_form_invisible *');
return _.map($visibleButtons, function (el) {
return el.innerHTML.trim();
});
}
});
});
});