Reviewers: ,
Please review this at http://codereview.tryton.org/851002/
Affected files:
M src/screen.js
M src/view.js
M src/window.js
Index: src/screen.js
===================================================================
--- a/src/screen.js
+++ b/src/screen.js
@@ -93,9 +93,9 @@
}
},
load_next_view: function() {
- if (this.view_to_load) {
+ if (!jQuery.isEmptyObject(this.view_to_load)) {
var view_id;
- if (this.view_ids) {
+ if (!jQuery.isEmptyObject(this.view_ids)) {
view_id = this.view_ids.shift();
}
var view_type = this.view_to_load.shift();
@@ -181,7 +181,7 @@
grp_prm.done(this.set_group.bind(this));
grp_prm.done(this.display.bind(this));
jQuery.when(grp_prm, count_prm).done(function (group, count) {
- this.screen_container.but_next.button('option', 'disabled',
+ this.screen_container.but_next.button('option', 'disabled',
!(group.length == this.limit &&
count > this.limit + this.offset));
}.bind(this));
@@ -191,6 +191,7 @@
},
set_group: function(group) {
if (this.group) {
+ jQuery.extend(group.model.fields, this.group.model.fields);
this.group.screens.splice(
this.group.screens.indexOf(this), 1);
}
@@ -211,11 +212,17 @@
},
display: function() {
if (this.views) {
+ // We might not have the view yet but it will arrive and the
+ // display will be triggered again by switch_view
+ if (!this.current_view) {
+ return;
+ }
this.search_active(["tree", "graph", "calendar"].indexOf(
this.current_view.view_type) > -1);
for (var i = 0; i < this.views.length; i++)
- if (this.views[i])
+ if (this.views[i]) {
this.views[i].display();
+ }
}
},
default_row_activate: function() {
Index: src/view.js
===================================================================
--- a/src/view.js
+++ b/src/view.js
@@ -134,7 +134,6 @@
'width': child.getAttribute('width'),
'orientation': child.getAttribute('orientation'),
'float_time': child.getAttribute('float_time'),
- 'pre_validate': child.getAttribute('pre_validate') ==
1,
'completion': child.getAttribute('completion') == 1
};
if (attributes.widget === null) {
@@ -855,6 +854,8 @@
return Sao.View.Form.Text;
case 'many2one':
return Sao.View.Form.Many2One;
+ case 'one2many':
+ return Sao.View.Form.One2Many;
}
};
@@ -1367,4 +1368,182 @@
}
});
+ Sao.View.Form.One2Many = Sao.class_(Sao.View.Form.Widget, {
+ class_: 'form-one2many',
+ init: function(field_name, model, attributes) {
+ Sao.View.Form.Many2One._super.init.call(this, field_name, model,
+ attributes);
+
+ this.el = jQuery('<div/>', {
+ 'class': this.class_
+ });
+ this.menu = jQuery('<div/>', {
+ 'class': this.class_ + '-menu'
+ });
+ this.el.append(this.menu);
+
+ if (attributes.add_remove) {
+ this.wid_text = jQuery('<input/>', {
+ type: 'input'
+ });
+ // TODO add completion
+
+ this.but_add = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-plus'
+ },
+ label: 'Add'
+ });
+ this.but_add.click(this.add.bind(this));
+ this.menu.append(this.but_add);
+
+ this.but_remove = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-minus'
+ },
+ label: 'Remove'
+ });
+ this.but_remove.click(this.remove.bind(this));
+ this.menu.append(this.but_remove);
+ }
+
+ this.but_new = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-document'
+ },
+ label: 'New'
+ });
+ this.but_new.click(this.new_.bind(this));
+ this.menu.append(this.but_new);
+
+ this.but_open = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-folder-open'
+ },
+ label: 'Open'
+ });
+ this.but_open.click(this.open.bind(this));
+ this.menu.append(this.but_open);
+
+ this.but_del = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-trash'
+ },
+ label: 'Delete'
+ });
+ this.but_del.click(this.delete_.bind(this));
+ this.menu.append(this.but_del);
+
+ this.but_undel = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-arrowreturn-1-s'
+ },
+ label: 'Undelete'
+ });
+ this.but_undel.click(this.undelete.bind(this));
+ this.menu.append(this.but_undel);
+
+ this.but_previous = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-arrowthick-1-w'
+ },
+ label: 'Previous'
+ });
+ this.but_previous.click(this.previous.bind(this));
+ this.menu.append(this.but_previous);
+
+ this.label = jQuery('<span/>', {
+ 'class': this.class_ + '-label'
+ });
+ this.label.text('(0, 0)');
+ this.menu.append(this.label);
+
+ this.but_next = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-arrowthick-1-e'
+ },
+ label: 'Next'
+ });
+ this.but_next.click(this.next.bind(this));
+ this.menu.append(this.but_next);
+
+ this.but_switch = jQuery('<button/>').button({
+ icons: {
+ primary: 'ui-icon-newwin'
+ },
+ label: 'Switch'
+ });
+ this.but_switch.click(this.switch_.bind(this));
+ this.menu.append(this.but_switch);
+
+ this.content = jQuery('<div/>', {
+ 'class': this.class_ + '-content'
+ });
+ this.el.append(this.content);
+
+ var modes = (attributes.mode || 'tree,form').split(',');
+ this.screen = new Sao.Screen(attributes.relation, {
+ mode: modes,
+ view_ids: (attributes.view_ids || '').split(','),
+ views_preload: attributes.views || {},
+ row_activate: this.activate.bind(this),
+ exclude_field: attributes.relation_field || null
+ });
+ this.prm = this.screen.switch_view(modes[0]).done(function () {
+ this.content.append(this.screen.current_view.el);
+ }.bind(this));
+ // TODO sensitivity of buttons
+ },
+ display: function(record, field) {
+ Sao.View.Form.One2Many._super.display.call(this, record, field);
+
+ this.prm.done(function() {
+ if (!record) return;
+ if (field === undefined) {
+ this.screen.new_group();
+ this.screen.current_record = null;
+ this.screen.parent = true;
+ this.screen.display();
+ return;
+ }
+
+ var new_group = record.field_get_client(this.field_name);
+ if (new_group != this.screen.group) {
+ this.screen.set_group(new_group);
+ // TODO handle editable tree
+ // TODO set readonly, domain, size_limit
+ }
+ this.screen.display();
+ }.bind(this));
+ },
+ activate: function(event_) {
+ this.edit();
+ },
+ add: function(event_) {
+ },
+ remove: function(event_) {
+ },
+ new_: function(event_) {
+ },
+ open: function(event_) {
+ },
+ delete_: function(event_) {
+ },
+ undelete: function(event_) {
+ },
+ previous: function(event_) {
+ },
+ next: function(event_) {
+ },
+ switch_: function(event_) {
+ },
+ edit: function() {
+ // TODO model access
+ var record = this.screen.current_record;
+ if (record) {
+ var win = new Sao.Window.Form(this.screen);
+ }
+ }
+ });
+
}());
Index: src/window.js
===================================================================
--- a/src/window.js
+++ b/src/window.js
@@ -7,6 +7,7 @@
Sao.Window.Form = Sao.class_(Object, {
init: function(screen, callback, kwargs) {
+ kwargs = kwargs || {};
this.screen = screen;
var view_type = kwargs.view_type || 'form';
var screen_views = [];
@@ -126,7 +127,7 @@
}
closing_prm.done(function() {
- this.callback(result);
+ if (this.callback) this.callback(result);
this.el.dialog('destroy');
}.bind(this));
}
@@ -134,6 +135,7 @@
Sao.Window.Search = Sao.class_(Object, {
init: function(model, callback, kwargs) {
+ kwargs = kwargs || {};
var views_preload = kwargs.views_preload || {};
this.model_name = model;
this.domain = kwargs.domain || [];
@@ -208,7 +210,7 @@
value.push([record.id, record._values.rec_name || '']);
}
}
- this.callback(value);
+ if (this.callback) this.callback(value);
this.el.dialog('destroy');
}
});