[FIX] attempt to make editability handling more logical and simpler to manage.
Also less buggy, with a bit o' luck bzr revid: xmo@openerp.com-20120724170550-150vimuk6bvzh8y8
This commit is contained in:
parent
da361d1042
commit
38cb3de518
|
@ -3027,8 +3027,11 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
|
||||||
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
|
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
|
||||||
controller.o2m = self;
|
controller.o2m = self;
|
||||||
if (view_type == "list") {
|
if (view_type == "list") {
|
||||||
if (self.get("effective_readonly"))
|
if (self.get("effective_readonly")) {
|
||||||
controller.set_editable(false);
|
controller.on('edit:before', self, function (e) {
|
||||||
|
e.cancel = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
} else if (view_type === "form") {
|
} else if (view_type === "form") {
|
||||||
if (self.get("effective_readonly")) {
|
if (self.get("effective_readonly")) {
|
||||||
$(".oe_form_buttons", controller.$element).children().remove();
|
$(".oe_form_buttons", controller.$element).children().remove();
|
||||||
|
@ -3301,7 +3304,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
|
||||||
.value();
|
.value();
|
||||||
},
|
},
|
||||||
do_add_record: function () {
|
do_add_record: function () {
|
||||||
if (this.options.editable) {
|
if (this.editable()) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
} else {
|
} else {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -4108,10 +4111,12 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
|
||||||
self.dataset, false,
|
self.dataset, false,
|
||||||
_.extend({'deletable': false,
|
_.extend({'deletable': false,
|
||||||
'selectable': !self.options.disable_multiple_selection,
|
'selectable': !self.options.disable_multiple_selection,
|
||||||
'read_only': true,
|
|
||||||
'import_enabled': false,
|
'import_enabled': false,
|
||||||
'$buttons': self.$buttonpane,
|
'$buttons': self.$buttonpane,
|
||||||
}, self.options.list_view_options || {}));
|
}, self.options.list_view_options || {}));
|
||||||
|
self.view_list.on('edit:before', self, function (e) {
|
||||||
|
e.cancel = true;
|
||||||
|
});
|
||||||
self.view_list.popup = self;
|
self.view_list.popup = self;
|
||||||
self.view_list.appendTo($(".oe_popup_list", self.$element)).pipe(function() {
|
self.view_list.appendTo($(".oe_popup_list", self.$element)).pipe(function() {
|
||||||
self.view_list.do_show();
|
self.view_list.do_show();
|
||||||
|
|
|
@ -21,9 +21,6 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
|
||||||
// whether the view rows can be reordered (via vertical drag & drop)
|
// whether the view rows can be reordered (via vertical drag & drop)
|
||||||
'reorderable': true,
|
'reorderable': true,
|
||||||
'action_buttons': true,
|
'action_buttons': true,
|
||||||
// if true, the view can't be editable, ignoring the view's and the context's
|
|
||||||
// instructions
|
|
||||||
'read_only': false,
|
|
||||||
// if true, the 'Import', 'Export', etc... buttons will be shown
|
// if true, the 'Import', 'Export', etc... buttons will be shown
|
||||||
'import_enabled': true,
|
'import_enabled': true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,6 +12,8 @@ openerp.web.list_editable = function (instance) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
this._force_editability = null;
|
||||||
|
this._context_editable = false;
|
||||||
this.editor = this.make_editor();
|
this.editor = this.make_editor();
|
||||||
// Stores records of {field, cell}, allows for re-rendering fields
|
// Stores records of {field, cell}, allows for re-rendering fields
|
||||||
// depending on cell state during and after resize events
|
// depending on cell state during and after resize events
|
||||||
|
@ -37,6 +39,11 @@ openerp.web.list_editable = function (instance) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.on('edit:before', this, function (event) {
|
||||||
|
if (!self.editable() || self.editor.is_editing()) {
|
||||||
|
event.cancel = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
this.on('edit:after', this, function () {
|
this.on('edit:after', this, function () {
|
||||||
self.$element.add(self.$buttons).addClass('oe_editing');
|
self.$element.add(self.$buttons).addClass('oe_editing');
|
||||||
});
|
});
|
||||||
|
@ -62,26 +69,18 @@ openerp.web.list_editable = function (instance) {
|
||||||
do_edit: function (index, id, dataset) {
|
do_edit: function (index, id, dataset) {
|
||||||
_.extend(this.dataset, dataset);
|
_.extend(this.dataset, dataset);
|
||||||
},
|
},
|
||||||
/**
|
editable: function () {
|
||||||
* Sets editability status for the list, based on defaults, view
|
if (this.fields_view.arch.attrs.editable || this._context_editable) {
|
||||||
* architecture and the provided flag, if any.
|
return true;
|
||||||
*
|
}
|
||||||
* @param {Boolean} [force] forces the list to editability. Sets new row edition status to "bottom".
|
|
||||||
*/
|
return this.options.editable;
|
||||||
set_editable: function (force) {
|
|
||||||
// TODO: fix handling of editability status to be simpler & clearer & more coherent
|
|
||||||
// If ``force``, set editability to bottom
|
|
||||||
// otherwise rely on view default
|
|
||||||
// view' @editable is handled separately as we have not yet
|
|
||||||
// fetched and processed the view at this point.
|
|
||||||
this.options.editable = (
|
|
||||||
! this.options.read_only && ((force && "bottom") || this.defaults.editable));
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Replace do_search to handle editability process
|
* Replace do_search to handle editability process
|
||||||
*/
|
*/
|
||||||
do_search: function(domain, context, group_by) {
|
do_search: function(domain, context, group_by) {
|
||||||
this.set_editable(context['set_editable']);
|
this._context_editable = !!context.set_editable;
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -89,7 +88,7 @@ openerp.web.list_editable = function (instance) {
|
||||||
* as an editable row at the top or bottom of the list)
|
* as an editable row at the top or bottom of the list)
|
||||||
*/
|
*/
|
||||||
do_add_record: function () {
|
do_add_record: function () {
|
||||||
if (this.options.editable) {
|
if (this.editable()) {
|
||||||
this.$element.find('table:first').show();
|
this.$element.find('table:first').show();
|
||||||
this.$element.find('.oe_view_nocontent').remove();
|
this.$element.find('.oe_view_nocontent').remove();
|
||||||
this.start_edition();
|
this.start_edition();
|
||||||
|
@ -103,9 +102,8 @@ openerp.web.list_editable = function (instance) {
|
||||||
this.editor.destroy();
|
this.editor.destroy();
|
||||||
}
|
}
|
||||||
// tree/@editable takes priority on everything else if present.
|
// tree/@editable takes priority on everything else if present.
|
||||||
this.options.editable = ! this.options.read_only && (data.arch.attrs.editable || this.options.editable);
|
|
||||||
var result = this._super(data, grouped);
|
var result = this._super(data, grouped);
|
||||||
if (this.options.editable) {
|
if (this.editable()) {
|
||||||
// FIXME: any hook available to ensure this is only done once?
|
// FIXME: any hook available to ensure this is only done once?
|
||||||
this.$buttons
|
this.$buttons
|
||||||
.off('click', '.oe_list_save')
|
.off('click', '.oe_list_save')
|
||||||
|
@ -210,6 +208,12 @@ openerp.web.list_editable = function (instance) {
|
||||||
self.resize_fields();
|
self.resize_fields();
|
||||||
return record.attributes;
|
return record.attributes;
|
||||||
});
|
});
|
||||||
|
}).fail(function () {
|
||||||
|
// if the start_edition event is cancelled and it was a
|
||||||
|
// creation, remove the newly-created empty record
|
||||||
|
if (!record.get('id')) {
|
||||||
|
self.records.remove(record);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -379,7 +383,7 @@ openerp.web.list_editable = function (instance) {
|
||||||
return this.reload_record(record);
|
return this.reload_record(record);
|
||||||
},
|
},
|
||||||
prepends_on_create: function () {
|
prepends_on_create: function () {
|
||||||
return this.options.editable === 'top';
|
return this.editable() === 'top';
|
||||||
},
|
},
|
||||||
setup_events: function () {
|
setup_events: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -701,7 +705,7 @@ openerp.web.list_editable = function (instance) {
|
||||||
|
|
||||||
instance.web.ListView.List.include(/** @lends instance.web.ListView.List# */{
|
instance.web.ListView.List.include(/** @lends instance.web.ListView.List# */{
|
||||||
row_clicked: function (event) {
|
row_clicked: function (event) {
|
||||||
if (!this.options.editable) {
|
if (!this.view.editable()) {
|
||||||
return this._super.apply(this, arguments);
|
return this._super.apply(this, arguments);
|
||||||
}
|
}
|
||||||
var record_id = $(event.currentTarget).data('id');
|
var record_id = $(event.currentTarget).data('id');
|
||||||
|
|
|
@ -87,34 +87,37 @@ List view edition is an extension to the base listview providing the
|
||||||
capability of inline record edition by delegating to an embedded form
|
capability of inline record edition by delegating to an embedded form
|
||||||
view.
|
view.
|
||||||
|
|
||||||
.. todo::
|
Editability status
|
||||||
|
++++++++++++++++++
|
||||||
|
|
||||||
cleanup options and settings for editability configuration. Right
|
The editability status of a list view can be queried through the
|
||||||
now there are:
|
:js:func:`~openerp.web.ListView.editable` method, will return a falsy
|
||||||
|
value if the listview is not currently editable.
|
||||||
|
|
||||||
``defaults.editable``
|
The editability status is based on three flags:
|
||||||
|
|
||||||
``null``, ``"top"`` or ``"bottom"``, generally broken and
|
``tree/@editable``
|
||||||
useless
|
|
||||||
|
|
||||||
``context.set_editable``
|
If present, can be either ``"top"`` or ``"bottom"``. Either will
|
||||||
|
make the list view editable, with new records being respectively
|
||||||
|
created at the top or at the bottom of the view.
|
||||||
|
|
||||||
forces ``options.editable`` to ``"bottom"``
|
``context.set_editable``
|
||||||
|
|
||||||
``view.arch.attrs.editable``
|
Boolean flag extracted from a search context (during the
|
||||||
|
:js:func:`~openerp.web.ListView.do_search`` handler), ``true``
|
||||||
|
will make the view editable (from the top), ``false`` or the
|
||||||
|
absence of the flag is a noop.
|
||||||
|
|
||||||
same as ``defaults.editable``, but applied separately (after
|
``defaults.editable``
|
||||||
reloading the view), if absent delegates to
|
|
||||||
``options.editable`` which may have been set previously.
|
|
||||||
|
|
||||||
``options.read_only``
|
Like ``tree/@editable``, one of absent (``null``)), ``"top"`` or
|
||||||
|
``"bottom"``, fallback for the list view if none of the previous
|
||||||
|
two flags are set.
|
||||||
|
|
||||||
force options.editable to false, or something?
|
These three flags can only *make* a listview editable, they can *not*
|
||||||
|
override a previously set flag. To do that, a listview user should
|
||||||
.. note:: can probably be replaced by cancelling ``edit:before``
|
instead cancel :ref:`the edit:before event <listview-edit-before>`.
|
||||||
|
|
||||||
and :js:func:`~openerp.web.ListView.set_editable` which
|
|
||||||
ultimately behaves weird-as-fuck-ly.
|
|
||||||
|
|
||||||
The editable list view module adds a number of methods to the list
|
The editable list view module adds a number of methods to the list
|
||||||
view, on top of implementing the :js:class:`EditorDelegate` protocol:
|
view, on top of implementing the :js:class:`EditorDelegate` protocol:
|
||||||
|
@ -219,6 +222,14 @@ view provides a number of dedicated events to its lifecycle.
|
||||||
abort its current behavior as soon as possible, and rollback
|
abort its current behavior as soon as possible, and rollback
|
||||||
any state modification.
|
any state modification.
|
||||||
|
|
||||||
|
Generally speaking, an event should only be cancelled (by
|
||||||
|
setting the ``cancel`` flag to ``true``), uncancelling an
|
||||||
|
event is undefined as event handlers are executed on a
|
||||||
|
first-come-first-serve basis and later handlers may
|
||||||
|
re-cancel an uncancelled event.
|
||||||
|
|
||||||
|
.. _listview-edit-before:
|
||||||
|
|
||||||
``edit:before`` *cancellable*
|
``edit:before`` *cancellable*
|
||||||
|
|
||||||
Invoked before the list view starts editing a record.
|
Invoked before the list view starts editing a record.
|
||||||
|
|
Loading…
Reference in New Issue