Xavier (Open ERP) has proposed merging
lp:~openerp-dev/openerp-web/6.1-o2m-nosuck-xmo into lp:openerp-web/6.1.
Requested reviews:
Xavier (Open ERP) (xmo)
For more details, see:
https://code.launchpad.net/~openerp-dev/openerp-web/6.1-o2m-nosuck-xmo/+merge/110522
--
https://code.launchpad.net/~openerp-dev/openerp-web/6.1-o2m-nosuck-xmo/+merge/110522
Your team OpenERP R&D Team is subscribed to branch
lp:~openerp-dev/openerp-web/6.1-o2m-nosuck-xmo.
=== modified file 'addons/web/static/src/css/base.css'
--- addons/web/static/src/css/base.css 2012-06-07 11:11:49 +0000
+++ addons/web/static/src/css/base.css 2012-06-15 13:15:26 +0000
@@ -1346,6 +1346,9 @@
display: inline;
margin: 0 0.5em 0 0;
}
+.openerp .oe_form_field_one2many .oe-listview .oe-edit-row-save {
+ visibility: hidden;
+}
.openerp .oe_forms .oe-listview th.oe-sortable .ui-icon,
.openerp .oe_forms .oe-listview th.oe-sortable .ui-icon {
=== modified file 'addons/web/static/src/js/core.js'
--- addons/web/static/src/js/core.js 2012-05-31 13:20:20 +0000
+++ addons/web/static/src/js/core.js 2012-06-15 13:15:26 +0000
@@ -42,7 +42,6 @@
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
- typeof _super[name] == "function" &&
fnTest.test(prop[name]) ?
(function(name, fn) {
return function() {
=== modified file 'addons/web/static/src/js/view_form.js'
--- addons/web/static/src/js/view_form.js 2012-06-14 08:40:09 +0000
+++ addons/web/static/src/js/view_form.js 2012-06-15 13:15:26 +0000
@@ -549,7 +549,8 @@
return $.Deferred().reject();
} else {
return $.when(this.reload()).pipe(function () {
- return $.when(r).then(success); }, null);
+ return r; })
+ .then(success);
}
},
/**
@@ -583,8 +584,9 @@
this.sidebar.attachments.do_update();
}
//openerp.log("The record has been created with id #" + this.datarecord.id);
- this.reload();
- return $.when(_.extend(r, {created: true})).then(success);
+ return $.when(this.reload()).pipe(function () {
+ return _.extend(r, {created: true}); })
+ .then(success);
}
},
on_action: function (action) {
@@ -2508,23 +2510,20 @@
}, this));
},
is_valid: function() {
- this.validate();
- return this._super();
- },
- validate: function() {
- this.invalid = false;
if (!this.viewmanager.views[this.viewmanager.active_view])
- return;
+ return true;
var view = this.viewmanager.views[this.viewmanager.active_view].controller;
- if (this.viewmanager.active_view === "form") {
- for (var f in view.fields) {
- f = view.fields[f];
- if (!f.is_valid()) {
- this.invalid = true;
- return;
- }
- }
+ switch (this.viewmanager.active_view) {
+ case 'form':
+ return _(view.fields).chain()
+ .invoke('is_valid')
+ .all(_.identity)
+ .value();
+ break;
+ case 'list':
+ return view.is_valid();
}
+ return true;
},
is_dirty: function() {
this.save_any_view();
@@ -2556,6 +2555,47 @@
openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
_template: 'One2Many.listview',
+ init: function (parent, dataset, view_id, options) {
+ this._super(parent, dataset, view_id, _.extend(options || {}, {
+ ListType: openerp.web.form.One2ManyList
+ }));
+ },
+ is_valid: function () {
+ var form;
+ // A list not being edited is always valid
+ if (!(form = this.first_edition_form())) {
+ return true;
+ }
+ // If the form has not been modified, the view can only be valid
+ // NB: is_dirty will also be set on defaults/onchanges/whatever?
+ // oe_form_dirty seems to only be set on actual user actions
+ if (!form.$element.is('.oe_form_dirty')) {
+ return true;
+ }
+
+ // Otherwise validate internal form
+ return _(form.fields).chain()
+ .invoke(function () {
+ this.validate();
+ this.update_dom(true);
+ return this.is_valid();
+ })
+ .all(_.identity)
+ .value();
+ },
+ first_edition_form: function () {
+ var get_form = function (group_or_list) {
+ if (group_or_list.edition) {
+ return group_or_list.edition_form;
+ }
+ return _(group_or_list.children).chain()
+ .map(get_form)
+ .compact()
+ .first()
+ .value();
+ };
+ return get_form(this.groups);
+ },
do_add_record: function () {
if (this.options.editable) {
this._super.apply(this, arguments);
@@ -2609,7 +2649,7 @@
var button_result = self.o2m.dataset.call_button.apply(self.o2m.dataset, arguments);
self.o2m.reload_current_view();
return button_result;
- }
+ };
pop.on_write.add(function(id, data) {
self.o2m.dataset.write(id, data, {}, function(r) {
self.o2m.reload_current_view();
@@ -2622,6 +2662,39 @@
return this._super(name, id, _.bind(def.resolve, def));
}
});
+openerp.web.form.One2ManyList = openerp.web.ListView.List.extend({
+ render_row_as_form: function () {
+ var self = this;
+ return this._super.apply(this, arguments).then(function () {
+ self.setup_save_on_row_blur();
+ });
+ },
+ bind_blur_focus: function (new_row, onblur, onfocus) {
+ if (new_row.addEventListener) {
+ new_row.addEventListener('blur', onblur, true);
+ new_row.addEventListener('focus', onfocus, true);
+ } else {
+ new_row.onfocusout = onblur;
+ new_row.onfocusin = onfocus;
+ }
+ },
+ setup_save_on_row_blur: function () {
+ var self = this;
+ var form = this.edition_form;
+ this.bind_blur_focus(this.edition_form.$element[0], function () {
+ self._save_row_timeout = setTimeout(function () {
+ if (form.widget_is_stopped) {
+ // Saved or cancelled already, maybe?
+ return;
+ }
+ self.view.ensure_saved();
+ }, 0);
+ }, function () {
+ clearTimeout(self._save_row_timeout);
+ delete self._save_row_timeout;
+ });
+ }
+});
openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
form_template: 'One2Many.formview',
=== modified file 'addons/web/static/src/js/view_list.js'
--- addons/web/static/src/js/view_list.js 2012-06-06 12:31:15 +0000
+++ addons/web/static/src/js/view_list.js 2012-06-15 13:15:26 +0000
@@ -61,7 +61,7 @@
this.records = new Collection();
- this.set_groups(new openerp.web.ListView.Groups(this));
+ this.set_groups(new (this.options.GroupsType)(this));
if (this.dataset instanceof openerp.web.DataSetStatic) {
this.groups.datagroup = new openerp.web.StaticDataGroup(this.dataset);
@@ -85,6 +85,14 @@
this.no_leaf = false;
},
+ set_default_options: function (options) {
+ this._super(options);
+ _.defaults(this.options, {
+ GroupsType: openerp.web.ListView.Groups,
+ ListType: openerp.web.ListView.List
+ });
+ },
+
/**
* Retrieves the view's number of records per page (|| section)
*
@@ -1191,7 +1199,7 @@
self.records.proxy(group.value).reset();
delete self.children[group.value];
}
- var child = self.children[group.value] = new openerp.web.ListView.Groups(self.view, {
+ var child = self.children[group.value] = new (this.view.options.GroupsType)(self.view, {
records: self.records.proxy(group.value),
options: self.options,
columns: self.columns
@@ -1297,7 +1305,7 @@
},
render_dataset: function (dataset) {
var self = this,
- list = new openerp.web.ListView.List(this, {
+ list = new (this.view.options.ListType)(this, {
options: this.options,
columns: this.columns,
dataset: dataset,
=== modified file 'addons/web/static/src/js/view_list_editable.js'
--- addons/web/static/src/js/view_list_editable.js 2012-05-11 11:15:27 +0000
+++ addons/web/static/src/js/view_list_editable.js 2012-06-15 13:15:26 +0000
@@ -124,29 +124,27 @@
* Checks if a record is being edited, and if so cancels it
*/
cancel_pending_edition: function () {
- var self = this, cancelled = $.Deferred();
+ var self = this, cancelled;
if (!this.edition) {
- cancelled.resolve();
- return cancelled.promise();
+ return $.when();
}
- if (this.edition_id != null) {
- this.reload_record(self.records.get(this.edition_id)).then(function () {
- cancelled.resolve();
- });
+ if (this.edition_id) {
+ cancelled = this.reload_record(this.records.get(this.edition_id));
} else {
- cancelled.resolve();
+ cancelled = $.when();
}
cancelled.then(function () {
self.view.unpad_columns();
self.edition_form.stop();
self.edition_form.$element.remove();
delete self.edition_form;
+ self.dataset.index = null;
delete self.edition_id;
delete self.edition;
});
this.pad_table_to(5);
- return cancelled.promise();
+ return cancelled;
},
/**
* Adapts this list's view description to be suitable to the inner form
@@ -170,24 +168,29 @@
var self = this;
switch (e.which) {
case KEY_RETURN:
- this.save_row().then(function (result) {
- if (result.created) {
- self.new_record();
- return;
- }
+ $(e.target).blur();
+ e.preventDefault();
+ //e.stopImmediatePropagation();
+ setTimeout(function () {
+ self.save_row().then(function (result) {
+ if (result.created) {
+ self.new_record();
+ return;
+ }
- var next_record_id,
- next_record = self.records.at(
- self.records.indexOf(result.edited_record) + 1);
- if (next_record) {
- next_record_id = next_record.get('id');
- self.dataset.index = _(self.dataset.ids)
- .indexOf(next_record_id);
- } else {
- self.dataset.index = 0;
- next_record_id = self.records.at(0).get('id');
- }
- self.edit_record(next_record_id);
+ var next_record_id,
+ next_record = self.records.at(
+ self.records.indexOf(result.edited_record) + 1);
+ if (next_record) {
+ next_record_id = next_record.get('id');
+ self.dataset.index = _(self.dataset.ids)
+ .indexOf(next_record_id);
+ } else {
+ self.dataset.index = 0;
+ next_record_id = self.records.at(0).get('id');
+ }
+ self.edit_record(next_record_id);
+ }, 0);
});
break;
case KEY_ESCAPE:
@@ -197,7 +200,7 @@
},
render_row_as_form: function (row) {
var self = this;
- this.cancel_pending_edition().then(function () {
+ return this.ensure_saved().pipe(function () {
var record_id = $(row).data('id');
var $new_row = $('<tr>', {
id: _.uniqueId('oe-editable-row-'),
@@ -213,7 +216,13 @@
})
.keyup(function () {
return self.on_row_keyup.apply(self, arguments); })
- .keydown(function (e) { e.stopPropagation(); });
+ .keydown(function (e) { e.stopPropagation(); })
+ .keypress(function (e) {
+ if (e.which === KEY_RETURN) {
+ return false;
+ }
+ });
+
if (row) {
$new_row.replaceAll(row);
} else if (self.options.editable) {
@@ -235,6 +244,10 @@
}
self.edition = true;
self.edition_id = record_id;
+ self.dataset.index = _(self.dataset.ids).indexOf(record_id);
+ if (self.dataset.index === -1) {
+ self.dataset.index = null;
+ }
self.edition_form = _.extend(new openerp.web.ListEditableFormView(self.view, self.dataset, false), {
form_template: 'ListView.row.form',
registry: openerp.web.list.form.widgets,
@@ -242,8 +255,8 @@
});
// HA HA
self.edition_form.appendTo();
- $.when(self.edition_form.on_loaded(self.get_form_fields_view())).then(function () {
- // put in $.when just in case FormView.on_loaded becomes asynchronous
+ // put in $.when just in case FormView.on_loaded becomes asynchronous
+ return $.when(self.edition_form.on_loaded(self.get_form_fields_view())).then(function () {
$new_row.find('> td')
.addClass('oe-field-cell')
.removeAttr('width')
@@ -307,7 +320,7 @@
*/
save_row: function () {
//noinspection JSPotentiallyInvalidConstructorUsage
- var self = this, done = $.Deferred();
+ var self = this;
return this.edition_form
.do_save(null, this.options.editable === 'top')
.pipe(function (result) {
@@ -327,18 +340,24 @@
created: result.created || false,
edited_record: edited_record
};
- }, null);
- }, null);
+ });
+ });
},
/**
* If the current list is being edited, ensures it's saved
*/
ensure_saved: function () {
if (this.edition) {
- return this.save_row();
+ // kinda-hack-ish: if the user has entered data in a field,
+ // oe_form_dirty will be set on the form so save, otherwise
+ // discard the current (entirely empty) line
+ if (this.edition_form.$element.is('.oe_form_dirty')) {
+ return this.save_row();
+ }
+ return this.cancel_pending_edition();
}
//noinspection JSPotentiallyInvalidConstructorUsage
- return $.Deferred().resolve().promise();
+ return $.when();
},
/**
* Cancels the edition of the row for the current dataset index
@@ -357,7 +376,6 @@
[record_id, this.dataset]);
},
new_record: function () {
- this.dataset.index = null;
this.render_row_as_form();
},
render_record: function (record) {
@@ -405,12 +423,12 @@
if (this.modifiers.tree_invisible) {
var old_invisible = this.invisible;
this.invisible = true;
- this._super();
+ this._super.apply(this, arguments);
this.invisible = old_invisible;
} else if (this.invisible) {
this.$element.children().css('visibility', 'hidden');
} else {
- this._super();
+ this._super.apply(this, arguments);
}
}
});
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp