summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2015-09-07 10:06:58 +0200
committerqsm-odoo <qsm@odoo.com>2015-09-08 14:14:31 +0200
commit3f7d350fe21d9e2afb359ce3e2652940e3f259d1 (patch)
tree5c51369c04ae7dcbcd2fd15b847f8eb240f2d735 /addons/web/static/src/js
parent4932bb13f30dc589dd9253bd74d4fc3faaf9852d (diff)
[FIX] web: Listview editable
(backport of enterprise version) Fix various problems with list view editable : * Click outside which should discard/save the line in edition * Warnings which should not appear when line is being discarded/saved * JS test + JS code refactoring
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/views/form_relational_widgets.js107
-rw-r--r--addons/web/static/src/js/views/list_view_editable.js33
2 files changed, 67 insertions, 73 deletions
diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js
index 425da11c03b..5788b3b333e 100644
--- a/addons/web/static/src/js/views/form_relational_widgets.js
+++ b/addons/web/static/src/js/views/form_relational_widgets.js
@@ -14,7 +14,6 @@ var utils = require('web.utils');
var ViewManager = require('web.ViewManager');
var formats = require('web.formats');
-
var _t = core._t;
var QWeb = core.qweb;
var COMMANDS = common.commands;
@@ -854,7 +853,7 @@ var FieldX2Many = AbstractManyField.extend({
var view = this.get_active_view();
if (view && view.type === "list" && view.controller.__focus) {
var def = $.Deferred();
- view.controller._on_blur_one2many(true).always(function () {
+ view.controller._on_blur_one2many().always(function () {
def.resolve();
});
return def;
@@ -904,7 +903,6 @@ var X2ManyViewManager = ViewManager.extend({
this.set_cp_bus(this.control_panel.get_bus());
this._super(parent, dataset, views, flags);
this.registry = core.view_registry.extend(x2many_views);
- this.__ignore_blur = false;
},
start: function() {
this.control_panel.prependTo(this.$el);
@@ -1004,12 +1002,6 @@ var X2ManyList = ListView.List.extend({
'class': 'oe_form_field_x2many_list_row_add'
}).append(
$('<a>', {href: '#'}).text(_t("Add an item"))
- .mousedown(function () {
- // FIXME: needs to be an official API somehow
- if (self.view.editor.is_editing()) {
- self.view.__ignore_blur = true;
- }
- })
.click(function (e) {
e.preventDefault();
e.stopPropagation();
@@ -1018,7 +1010,7 @@ var X2ManyList = ListView.List.extend({
clearTimeout(self.view.editor.form.__blur_timeout);
self.view.editor.form.__blur_timeout = false;
}
- self.view.ensure_saved().done(function () {
+ self.view.save_edition().done(function () {
self.view.do_add_record();
});
}));
@@ -1045,23 +1037,17 @@ var One2ManyListView = X2ManyListView.extend({
this.on('save:before cancel:before', this, this.proxy('_before_unedit'));
/* detect if the user try to exit the one2many widget */
- var self = this;
- this._mousedown_blur_line = function (event) {
- if (self.__focus) {
- self.__ignore_blur = true;
- if ($(event.target).closest("button, *:not(.oe_form_field_x2many_list_row_add) > a").length ||
- (!$(event.target).closest(self.editor.$el[0]).length && !$(event.target).closest(self.$el[0]).length)) {
- self.__ignore_blur = false;
- }
- }
- };
- $(document).on('mousedown', this._mousedown_blur_line);
+ core.bus.on('click', this, this._on_click_outside);
this.dataset.on('dataset_changed', this, function () {
- self._dataset_changed = true;
+ this._dataset_changed = true;
});
this.dataset.x2m.on('load_record', this, function () {
- self._dataset_changed = false;
+ this._dataset_changed = false;
+ });
+
+ this.on('warning', this, function(e) { // In case of a one2many, we do not want any warning which comes from the editor
+ e.stop_propagation();
});
},
do_add_record: function () {
@@ -1121,11 +1107,12 @@ var One2ManyListView = X2ManyListView.extend({
}
var parent_form = this.x2m.view;
var self = this;
- this.ensure_saved().then(function () {
- if (parent_form)
+ this.save_edition().then(function () {
+ if (parent_form) {
return parent_form.save();
- else
+ } else {
return $.when();
+ }
}).done(function () {
var ds = self.x2m.dataset;
var changed_records = _.find(ds.cache, function(record) {
@@ -1133,7 +1120,7 @@ var One2ManyListView = X2ManyListView.extend({
});
if (!self.x2m.options.reload_on_button && !changed_records) {
self.handle_button(name, id, callback);
- }else {
+ } else {
self.handle_button(name, id, function(){
self.x2m.view.reload();
});
@@ -1149,9 +1136,12 @@ var One2ManyListView = X2ManyListView.extend({
reload_content: function () {
var self = this;
if (self.__focus) {
- self._on_blur_one2many(true);
+ self._on_blur_one2many();
return this._super().then(function () {
- self.start_edition(self.records.get(self.editor.form.datarecord.id));
+ var record_being_edited = self.records.get(self.editor.form.datarecord.id);
+ if (record_being_edited) {
+ self.start_edition(record_being_edited);
+ }
});
}
return this._super();
@@ -1161,31 +1151,52 @@ var One2ManyListView = X2ManyListView.extend({
this._dataset_changed = false;
this.__focus = true;
},
- _on_blur_one2many: function (force) {
- var self = this;
- var def = $.when();
-
- if (this.__ignore_blur && !force) {
- this.__ignore_blur = false;
+ _on_click_outside: function(e) {
+ if(this.__ignore_blur || !this.editor.is_editing()) {
return;
}
- this.__focus = false;
- this.dataset.x2m.internal_dataset_changed = false;
+ var $target = $(e.target);
+
+ // If click on a button, a ui-autocomplete dropdown or modal-backdrop, it is not considered as a click outside
+ var click_outside = ($target.closest('.ui-autocomplete,.btn,.modal-backdrop').length === 0);
+
+ // Check if click inside the current list editable
+ var $o2m = $target.closest(".oe_list_editable");
+ if($o2m.length && $o2m[0] === this.el) {
+ click_outside = false;
+ }
- if (this.editor.form.is_dirty()) {
- def = this.ensure_saved();
- } else if (this.editor.record) {
- def = this.cancel_edition();
+ // Check if click inside a modal which is on top of the current list editable
+ var $modal = $target.closest(".modal");
+ if($modal.length) {
+ var $currentModal = this.$el.closest(".modal");
+ if($currentModal.length === 0 || $currentModal[0] !== $modal[0]) {
+ click_outside = false;
+ }
}
- def.then(function () {
+ if (click_outside) {
+ this._on_blur_one2many();
+ }
+ },
+ _on_blur_one2many: function() {
+ if(this.__ignore_blur) {
+ return $.when();
+ }
+
+ this.__ignore_blur = true;
+ this.__focus = false;
+ this.dataset.x2m.internal_dataset_changed = false;
+
+ var self = this;
+ return this.save_edition().done(function () {
if (self._dataset_changed) {
self.dataset.trigger('dataset_changed');
}
- });
-
- return def;
+ }).always(function() {
+ self.__ignore_blur = false;
+ });
},
_after_edit: function () {
this.editor.form.on('blurred', this, this._on_blur_one2many);
@@ -1215,10 +1226,6 @@ var One2ManyListView = X2ManyListView.extend({
return this._super(record);
},
- destroy: function () {
- this._super();
- $(document).off('mousedown', this._mousedown_blur_line);
- }
});
var One2ManyGroups = ListView.Groups.extend({
@@ -1656,7 +1663,6 @@ var FieldMany2ManyCheckBoxes = AbstractManyField.extend(common.ReinitializeField
}
});
-
core.form_widget_registry
.add('many2one', FieldMany2One)
.add('many2many', FieldMany2Many)
@@ -1673,3 +1679,4 @@ return {
};
});
+
diff --git a/addons/web/static/src/js/views/list_view_editable.js b/addons/web/static/src/js/views/list_view_editable.js
index a746a0d1ab3..9360da466b2 100644
--- a/addons/web/static/src/js/views/list_view_editable.js
+++ b/addons/web/static/src/js/views/list_view_editable.js
@@ -47,11 +47,6 @@ var Editor = Widget.extend({
$buttons: $(),
$pager: $(),
});
-
- // FIXME
- // this.on('warning', this, function(e) {
- // e.stop_propagation();
- // });
},
start: function () {
var self = this;
@@ -115,7 +110,7 @@ var Editor = Widget.extend({
if(result.created && !self.record.id) {
self.record.id = result.result;
}
- return self.cancel();
+ return self.record;
});
},
cancel: function (force) {
@@ -305,7 +300,7 @@ ListView.include(/** @lends instance.web.ListView# */{
},
do_button_action: function (name, id, callback) {
var self = this;
- this.ensure_saved().done(function (data) {
+ this.save_edition().done(function (data) {
if(!id && data.created) {
id = data.record.get('id');
}
@@ -313,17 +308,6 @@ ListView.include(/** @lends instance.web.ListView# */{
});
},
/**
- * Ensures the editable list is saved (saves any pending edition if
- * needed, or tries to)
- *
- * Returns a deferred to the end of the saving.
- *
- * @returns {$.Deferred}
- */
- ensure_saved: function () {
- return this.save_edition();
- },
- /**
* Builds a record with the provided id (``false`` for a creation),
* setting all columns with ``false`` value so code which relies on
* having an actual value behaves correctly
@@ -358,10 +342,8 @@ ListView.include(/** @lends instance.web.ListView# */{
this.records.add(record, {at: (this.prepends_on_create())? 0 : null});
}
- return this.ensure_saved().then(function() {
+ return this.save_edition().then(function() {
return $.when.apply($, self.editor.form.render_value_defs);
- }, function() {
- return self.cancel_edition();
}).then(function () {
var $recordRow = self.groups.get_row_for(record);
var cells = self.get_cells_for($recordRow);
@@ -406,7 +388,7 @@ ListView.include(/** @lends instance.web.ListView# */{
}
});
}, function() {
- return $.Deferred().resolve(); // Here the cancel edition failed so the start_edition is considered as done and succeeded
+ return $.Deferred().resolve(); // Here the save/cancel edition failed so the start_edition is considered as done and succeeded
});
},
get_cells_for: function ($row) {
@@ -478,13 +460,18 @@ ListView.include(/** @lends instance.web.ListView# */{
// onwrite callback could be altering & reloading the
// record which has *just* been saved, so first perform all
// onwrites then do a final reload of the record
- return self.handle_onwrite(record)
+ return self.cancel_edition(true)
+ .then(function() {
+ return self.handle_onwrite(record);
+ })
.then(function () {
return self.reload_record(record);
})
.then(function () {
return {created: created, record: record};
});
+ }, function() {
+ return self.cancel_edition();
});
});
});