[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) {
|
||||
controller.o2m = self;
|
||||
if (view_type == "list") {
|
||||
if (self.get("effective_readonly"))
|
||||
controller.set_editable(false);
|
||||
if (self.get("effective_readonly")) {
|
||||
controller.on('edit:before', self, function (e) {
|
||||
e.cancel = true;
|
||||
});
|
||||
}
|
||||
} else if (view_type === "form") {
|
||||
if (self.get("effective_readonly")) {
|
||||
$(".oe_form_buttons", controller.$element).children().remove();
|
||||
|
@ -3301,7 +3304,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
|
|||
.value();
|
||||
},
|
||||
do_add_record: function () {
|
||||
if (this.options.editable) {
|
||||
if (this.editable()) {
|
||||
this._super.apply(this, arguments);
|
||||
} else {
|
||||
var self = this;
|
||||
|
@ -4108,10 +4111,12 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
|
|||
self.dataset, false,
|
||||
_.extend({'deletable': false,
|
||||
'selectable': !self.options.disable_multiple_selection,
|
||||
'read_only': true,
|
||||
'import_enabled': false,
|
||||
'$buttons': self.$buttonpane,
|
||||
}, 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.appendTo($(".oe_popup_list", self.$element)).pipe(function() {
|
||||
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)
|
||||
'reorderable': 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
|
||||
'import_enabled': true,
|
||||
},
|
||||
|
|
|
@ -12,6 +12,8 @@ openerp.web.list_editable = function (instance) {
|
|||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this._force_editability = null;
|
||||
this._context_editable = false;
|
||||
this.editor = this.make_editor();
|
||||
// Stores records of {field, cell}, allows for re-rendering fields
|
||||
// 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 () {
|
||||
self.$element.add(self.$buttons).addClass('oe_editing');
|
||||
});
|
||||
|
@ -62,26 +69,18 @@ openerp.web.list_editable = function (instance) {
|
|||
do_edit: function (index, id, dataset) {
|
||||
_.extend(this.dataset, dataset);
|
||||
},
|
||||
/**
|
||||
* Sets editability status for the list, based on defaults, view
|
||||
* architecture and the provided flag, if any.
|
||||
*
|
||||
* @param {Boolean} [force] forces the list to editability. Sets new row edition status to "bottom".
|
||||
*/
|
||||
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));
|
||||
editable: function () {
|
||||
if (this.fields_view.arch.attrs.editable || this._context_editable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.options.editable;
|
||||
},
|
||||
/**
|
||||
* Replace do_search to handle editability process
|
||||
*/
|
||||
do_search: function(domain, context, group_by) {
|
||||
this.set_editable(context['set_editable']);
|
||||
this._context_editable = !!context.set_editable;
|
||||
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)
|
||||
*/
|
||||
do_add_record: function () {
|
||||
if (this.options.editable) {
|
||||
if (this.editable()) {
|
||||
this.$element.find('table:first').show();
|
||||
this.$element.find('.oe_view_nocontent').remove();
|
||||
this.start_edition();
|
||||
|
@ -103,9 +102,8 @@ openerp.web.list_editable = function (instance) {
|
|||
this.editor.destroy();
|
||||
}
|
||||
// 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);
|
||||
if (this.options.editable) {
|
||||
if (this.editable()) {
|
||||
// FIXME: any hook available to ensure this is only done once?
|
||||
this.$buttons
|
||||
.off('click', '.oe_list_save')
|
||||
|
@ -210,6 +208,12 @@ openerp.web.list_editable = function (instance) {
|
|||
self.resize_fields();
|
||||
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);
|
||||
},
|
||||
prepends_on_create: function () {
|
||||
return this.options.editable === 'top';
|
||||
return this.editable() === 'top';
|
||||
},
|
||||
setup_events: function () {
|
||||
var self = this;
|
||||
|
@ -701,7 +705,7 @@ openerp.web.list_editable = function (instance) {
|
|||
|
||||
instance.web.ListView.List.include(/** @lends instance.web.ListView.List# */{
|
||||
row_clicked: function (event) {
|
||||
if (!this.options.editable) {
|
||||
if (!this.view.editable()) {
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
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
|
||||
view.
|
||||
|
||||
.. todo::
|
||||
Editability status
|
||||
++++++++++++++++++
|
||||
|
||||
cleanup options and settings for editability configuration. Right
|
||||
now there are:
|
||||
The editability status of a list view can be queried through the
|
||||
: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
|
||||
useless
|
||||
``tree/@editable``
|
||||
|
||||
``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
|
||||
reloading the view), if absent delegates to
|
||||
``options.editable`` which may have been set previously.
|
||||
``defaults.editable``
|
||||
|
||||
``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?
|
||||
|
||||
.. note:: can probably be replaced by cancelling ``edit:before``
|
||||
|
||||
and :js:func:`~openerp.web.ListView.set_editable` which
|
||||
ultimately behaves weird-as-fuck-ly.
|
||||
These three flags can only *make* a listview editable, they can *not*
|
||||
override a previously set flag. To do that, a listview user should
|
||||
instead cancel :ref:`the edit:before event <listview-edit-before>`.
|
||||
|
||||
The editable list view module adds a number of methods to the list
|
||||
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
|
||||
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*
|
||||
|
||||
Invoked before the list view starts editing a record.
|
||||
|
|
Loading…
Reference in New Issue