[FIX] web: explicit color attribute for m2m_tags

Before this fix, the field 'color' was hardcoded in the m2m_tags widget,
which means that:
 - one couldn't specify another field (problem for custom models, with x_...)
 - if the related model didn't have the field 'color', a warning was raised
   by the server

Now, the color attribute needs to be specified on the widget options if one
wants to display colored tags.

If the color is not specified, the tags will be displayed in grey.
This commit is contained in:
Martin Geubelle
2017-07-07 13:40:36 +02:00
parent 56dae80994
commit e26ccdd0b6
5 changed files with 61 additions and 15 deletions
@@ -1367,7 +1367,6 @@ var FieldMany2ManyTags = AbstractField.extend({
'click .o_delete': '_onDeleteTag',
}),
fieldsToFetch: {
color: {type: 'integer'},
display_name: {type: 'char'},
},
@@ -1380,6 +1379,8 @@ var FieldMany2ManyTags = AbstractField.extend({
if (this.mode === 'edit') {
this.className += ' o_input';
}
this.colorField = this.nodeOptions.color_field;
},
//--------------------------------------------------------------------------
@@ -1444,6 +1445,7 @@ var FieldMany2ManyTags = AbstractField.extend({
_getRenderTagsContext: function () {
var elements = this.value ? _.pluck(this.value.data, 'data') : [];
return {
colorField: this.colorField,
elements: elements,
readonly: this.mode === "readonly",
};
@@ -1571,7 +1573,7 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({
_onOpenColorPicker: function (event) {
var tag_id = $(event.currentTarget).data('id');
var tag = _.findWhere(this.value.data, { res_id: tag_id });
if (tag && 'color' in tag.data) { // if there is a color field on the related model
if (tag && this.colorField in tag.data) { // if there is a color field on the related model
this.$color_picker = $(qweb.render('FieldMany2ManyTag.colorpicker', {
'widget': this,
'tag_id': tag_id,
@@ -1596,11 +1598,11 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({
if (color === current_color) { return; }
var changes = {};
changes[this.colorField] = color;
this.trigger_up('field_changed', {
dataPointID: _.findWhere(this.value.data, {res_id: id}).id,
changes: {
color: color,
},
changes: changes,
force_save: true,
});
},
@@ -1611,12 +1613,19 @@ var KanbanFieldMany2ManyTags = FieldMany2ManyTags.extend({
var self = this;
this.$el.empty().addClass('o_field_many2manytags o_kanban_tags');
_.each(this.value.data, function (m2m) {
// 10th color is invisible
if ('color' in m2m.data && m2m.data.color !== 10) {
$('<span>')
.addClass('o_tag o_tag_color_' + m2m.data.color)
var $tag = $('<span>')
.attr('title', _.str.escapeHTML(m2m.data.display_name))
.appendTo(self.$el);
if (self.colorField in m2m.data) {
if (m2m.data[self.colorField] === 10) {
// 10th color is invisible
$tag.hide();
} else {
$tag.addClass('o_tag o_tag_color_' + m2m.data[self.colorField]);
}
} else {
// display tags in grey by default
$tag.addClass('o_tag o_tag_color_0');
}
});
},
@@ -355,6 +355,11 @@ return core.Class.extend({
return {};
}),
};
if (attrs.options.color_field) {
// used by m2m tags
attrs.relatedFields[attrs.options.color_field] = { type: 'integer' };
attrs.fieldsInfo.default[attrs.options.color_field] = {};
}
}
}
return attrs;
+1 -1
View File
@@ -759,7 +759,7 @@
</t>
<t t-name="FieldMany2ManyTag">
<t t-foreach="elements" t-as="el">
<span t-attf-class="badge dropdown o_tag_color_#{el.color || 10}" t-att-data-color="el.color || 10" t-att-data-index="el_index" t-att-data-id="el.id">
<span t-attf-class="badge dropdown o_tag_color_#{el[colorField] || 10}" t-att-data-color="el[colorField] || 10" t-att-data-index="el_index" t-att-data-id="el.id">
<span class="o_badge_text"><t t-raw="el.display_name"/></span>
<span t-if="!readonly" class="fa fa-times o_delete"/>
</span>
@@ -6017,8 +6017,37 @@ QUnit.module('relational_fields', {
QUnit.module('FieldMany2ManyTags');
QUnit.test('fieldmany2many tags: rendering and edition', function (assert) {
assert.expect(17);
QUnit.test('fieldmany2many tags without color', function (assert) {
assert.expect(4);
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch:'<form string="Partners">' +
'<field name="timmy" widget="many2many_tags"/>' +
'</form>',
mockRPC: function (route, args) {
if (args.method ==='read' && args.model === 'partner_type') {
assert.deepEqual(args.args , [[12], ['display_name']], "should not read any color field");
}
return this._super.apply(this, arguments);
}
});
var $input = form.$('.o_field_many2manytags input');
$input.click(); // opens the dropdown
assert.strictEqual($input.autocomplete('widget').find('li').length, 3,
"autocomplete dropdown should have 3 entries (2 values + 'Search and Edit...')");
$input.autocomplete('widget').find('li:first()').click(); // adds a tag
assert.strictEqual(form.$('.o_field_many2manytags > span').length, 1,
"should contain 1 tag");
assert.ok(form.$('.o_field_many2manytags > span:contains("gold")').length,
"should contain newly added tag 'gold'");
form.destroy();
});
QUnit.test('fieldmany2many tags with color: rendering and edition', function (assert) {
assert.expect(20);
this.data.partner.records[0].timmy = [12, 14];
this.data.partner_type.records.push({id: 13, display_name: "red", color: 8});
@@ -6027,7 +6056,7 @@ QUnit.module('relational_fields', {
model: 'partner',
data: this.data,
arch:'<form string="Partners">' +
'<field name="timmy" widget="many2many_tags" options="{\'no_create_edit\': True}"/>' +
'<field name="timmy" widget="many2many_tags" options="{\'color_field\': \'color\', \'no_create_edit\': True}"/>' +
'</form>',
res_id: 1,
mockRPC: function (route, args) {
@@ -6038,6 +6067,9 @@ QUnit.module('relational_fields', {
assert.ok(_.isEqual(_.sortBy(commands[0][2], _.identity.bind(_)), [12, 13]),
"new value should be [12, 13]");
}
if (args.method ==='read' && args.model === 'partner_type') {
assert.deepEqual(args.args[1], ['display_name', 'color'], "should read the color field");
}
return this._super.apply(this, arguments);
},
});
@@ -6183,7 +6215,7 @@ QUnit.module('relational_fields', {
model: 'partner',
data: this.data,
arch:'<form string="Partners">' +
'<field name="timmy" widget="many2many_tags"/>' +
'<field name="timmy" widget="many2many_tags" options="{\'color_field\': \'color\'}"/>' +
'</form>',
res_id: 1,
});
@@ -445,7 +445,7 @@ QUnit.module('Views', {
arch: '<kanban class="o_kanban_test">' +
'<templates><t t-name="kanban-box">' +
'<div>' +
'<field name="category_ids"/>' +
'<field name="category_ids" widget="many2many_tags" options="{\'color_field\': \'color\'}"/>' +
'<field name="foo"/>' +
'<field name="state" widget="priority"/>' +
'</div>' +