3
0
Fork 0

Merge pull request #333 from hbrunn/8.0-web_widget_one2many_tags-refactor

[RFR] in order to work properly, we need to use FieldOne2Many's caching logic
8.0
Pedro M. Baeza 2016-04-02 18:05:08 +02:00
commit 148220cb75
4 changed files with 199 additions and 70 deletions

View File

@ -29,6 +29,16 @@ In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/web/issues/new?body=module:%20web_widget_one2many_tags%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. `here <https://github.com/OCA/web/issues/new?body=module:%20web_widget_one2many_tags%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Known issues / Roadmap
======================
* as one2many fields are cached on the client side until the user hits `Save`
on the main form, no ``name_get`` can be called on those records, which is
why changes that update the display name are not reflected until saving, and
new records are displayed as `New record` until then. If you don't like this,
add the field `display_name` to your form and have it recomputed in an
@onchange handler.
Credits Credits
======= =======

View File

@ -15,4 +15,7 @@
"data": [ "data": [
'views/templates.xml', 'views/templates.xml',
], ],
"qweb": [
'static/src/xml/web_widget_one2many_tags.xml',
],
} }

View File

@ -4,73 +4,142 @@
openerp.web_widget_one2many_tags = function(instance) openerp.web_widget_one2many_tags = function(instance)
{ {
openerp.web_widget_one2many_tags.FieldOne2ManyTags = instance.web_widget_one2many_tags.FieldOne2ManyTags =
instance.web.form.FieldMany2ManyTags.extend({ instance.web.form.FieldOne2Many.extend(instance.web.form.ReinitializeFieldMixin, {
template: "FieldOne2ManyTags",
tag_template: "FieldOne2ManyTag",
disable_utility_classes: false,
initialize_texttext: function() initialize_texttext: function()
{ {
var self = this, var self = this;
result = this._super.apply(this, arguments), return {
removeTag = result.ext.tags.removeTag; plugins: 'tags arrow filter',
result.plugins = 'tags arrow filter'; ext: {
result.ext.core.onSetInputData = function(e, data) itemManager: {
{ itemToString: function(item) {
this.input().val(data); return item.name;
}; },
result.filter = { },
items: [] arrow: {
};
result.ext.arrow = {
onArrowClick: function(e) onArrowClick: function(e)
{ {
var context = self.build_context(), var list_view = new instance.web.form.One2ManyListView(
key = _.str.sprintf( self, self.dataset);
'default_%s', self.field.relation_field) list_view.o2m = self;
context.add({[key]: self.field_manager.datarecord.id}); list_view.editable = function() { return false };
self._search_create_popup('form', undefined, context); list_view.do_add_record();
}, },
} },
result.ext.tags.removeTag = function(tag) tags: {
isTagAllowed: function(tag) {
return tag.name;
},
removeTag: function(tag)
{ {
var id = tag.data("id"), self.dataset.unlink([tag.data('id')]);
dataset = new instance.web.DataSet( return $.fn.textext.TextExtTags.prototype.removeTag
self, self.field.relation, self.build_context()); .call(this, tag);
dataset.unlink([id]); },
return removeTag(tag); renderTag: function(tag) {
return $.fn.textext.TextExtTags.prototype.renderTag
.call(this, tag).data("id", tag.id);
},
},
},
filter: {
items: []
},
}; };
return result;
}, },
initialize_content: function() build_context: function()
{ {
var self = this, var context = this._super.apply(this, arguments),
result = this._super.apply(this, arguments); key = _.str.sprintf('default_%s', this.field.relation_field);
if(!this.$text) if(this.field_manager.datarecord.id)
{ {
return result; context.add({[key]: this.field_manager.datarecord.id});
} }
this.$text.bind('tagClick', function(e, tag, value, callback) return context;
},
reload_current_view: function()
{ {
var popup = new instance.web.form.FormOpenPopup(self); var self = this;
popup.show_element( if(!self.$el.length)
self.field.relation, value.id, self.build_context(),
{ {
title: instance.web._t("Open: ") + value.name, return jQuery.when();
readonly: self.get("effective_readonly"), }
if(!self.get("effective_readonly"))
{
self.ignore_blur = false;
if(self.tags)
{
self.tags.tagElements().remove();
}
if(!self.$text || !self.$text.length)
{
self.$text = this.$("textarea");
self.$text.textext(self.initialize_texttext());
self.$text.bind('tagClick', function(e, tag, value, callback)
{
var list_view = new instance.web.form.One2ManyViewManager(
self, self.dataset);
list_view.o2m = self;
self.dataset.select_id(value.id);
list_view.switch_mode('form');
}); });
popup.on('write_completed', self, function() }
if(self.$text.textext().length)
{ {
popup.dataset.name_get(popup.dataset.ids) self.tags = self.$text.textext()[0].tags();
}
}
else
{
self.tags = null;
self.$text = null;
}
return self.dataset.read_ids(self.dataset.ids, ['display_name'])
.then(function(names) .then(function(names)
{ {
_(names).each(function(name) if(self.get("effective_readonly"))
{ {
value.name = name[1]; self.$el.html(instance.web.qweb.render(
callback(value, true); self.tag_template,
{
elements: _(names).map(function(name)
{
return [name.id, name.display_name];
}) })
}
));
}
else if(self.$text.textext().length)
{
self.tags.addTags(_(names).map(function(name)
{
return {
name: name.display_name || instance.web._t('New record'),
id: name.id,
}
}));
}
}); });
}); },
}); reinitialize: function()
{
var result = instance.web.form.ReinitializeFieldMixin.reinitialize.call(this);
this.reload_current_view();
return result; return result;
}, },
// defuse some functions we don't need
get_active_view: function()
{
return false;
},
load_views: function()
{
return jQuery.when();
},
}); });
instance.web.form.widgets.add( instance.web.form.widgets.add(
@ -78,23 +147,65 @@ openerp.web_widget_one2many_tags = function(instance)
'instance.web_widget_one2many_tags.FieldOne2ManyTags' 'instance.web_widget_one2many_tags.FieldOne2ManyTags'
); );
instance.web.list.One2ManyTags = instance.web.list.Many2Many.extend({ instance.web.list.One2ManyTags = instance.web.list.Column.extend({
init: function () { _format: function (row_data, options)
this._super.apply(this, arguments); {
// Treat it as many2many to trick odoo into populating '__display'. if(!_.isEmpty(row_data[this.id].value) && row_data[this.id + '__display'])
// note: this has been fixed in core OCB recently {
this.type = 'many2many'; row_data[this.id] = row_data[this.id + '__display'];
},
_format: function (row_data, options) {
if (_.isEmpty(row_data[this.id].value)) {
row_data[this.id] = {'value': false};
} }
return this._super(row_data, options); return this._super(row_data, options);
} },
}); });
instance.web.list.columns.add( instance.web.list.columns.add(
'field.one2many_tags', 'field.one2many_tags',
'instance.web.list.One2ManyTags' 'instance.web.list.One2ManyTags'
); );
instance.web.ListView.List.include({
render_cell: function (record, column)
{
if(column.widget == 'one2many_tags')
{
var dataset = new instance.web.form.One2ManyDataSet(
this, column.relation),
fake_widget = {
dataset: dataset,
trigger_on_change: function() {},
get_active_view: function () {},
_super: function() {},
set: function() {},
build_context: function()
{
return column.context;
},
},
value = record.get(column.id);
dataset.o2m = fake_widget;
openerp.web_widget_one2many_tags.FieldOne2ManyTags
.prototype.set_value.apply(fake_widget, [value])
dataset.read_ids(dataset.ids, ['display_name'])
.then(function(names) {
if(!names.length)
{
return;
}
record.set(
column.id + '__display',
_(names)
.map(function(name)
{
return name.display_name ||
instance.web._t('New record');
})
.join(', ')
);
console.log(record.get(column.id + '__display'));
});
column = _(column).extend({type: 'one2many_tags'});
}
return this._super(record, column);
},
});
} }

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="FieldOne2ManyTags" t-extend="FieldMany2ManyTags" />
<t t-name="FieldOne2ManyTag" t-extend="FieldMany2ManyTag" />
</templates>