[MERGE] behavioral fixes and changes to editable list o2ms
* Correctly propagate current validation status of row being edited * Automatically save row being edited upon leaving it * Replace "Save" button (floppy) by "Cancel" (cross) * Allow easier overriding of Groups and List sub-widgets bzr revid: xmo@openerp.com-20120625070901-4cs6v24exjk5z2fa
This commit is contained in:
commit
942f72b578
|
@ -1346,6 +1346,10 @@ label.error {
|
|||
display: inline;
|
||||
margin: 0 0.5em 0 0;
|
||||
}
|
||||
.openerp .oe_form_field_one2many .oe-listview .oe-edit-row-save,
|
||||
.openerp .oe_form_field_one2many_list .oe-listview .oe-edit-row-save {
|
||||
background-image: url("/web/static/src/img/iconset-b-remove.png");
|
||||
}
|
||||
|
||||
.openerp .oe_forms .oe-listview th.oe-sortable .ui-icon,
|
||||
.openerp .oe_forms .oe-listview th.oe-sortable .ui-icon {
|
||||
|
|
|
@ -42,7 +42,6 @@ openerp.web.core = function(openerp) {
|
|||
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() {
|
||||
|
|
|
@ -52,6 +52,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.mutating_mutex = new $.Mutex();
|
||||
this.on_change_mutex = new $.Mutex();
|
||||
this.reload_mutex = new $.Mutex();
|
||||
|
||||
this.__clicked_inside = false;
|
||||
this.__blur_timeout = null;
|
||||
},
|
||||
start: function() {
|
||||
this._super();
|
||||
|
@ -80,8 +83,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.sidebar.stop();
|
||||
}
|
||||
_.each(this.widgets, function(w) {
|
||||
$(w).unbind('.formBlur');
|
||||
w.stop();
|
||||
});
|
||||
this.$element.unbind('.formBlur');
|
||||
this._super();
|
||||
},
|
||||
reposition: function ($e) {
|
||||
|
@ -98,8 +103,13 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'widget': this });
|
||||
}
|
||||
this.$element.html(this.rendered);
|
||||
this.$element.bind('mousedown.formBlur', function () {
|
||||
self.__clicked_inside = true;
|
||||
});
|
||||
_.each(this.widgets, function(w) {
|
||||
w.start();
|
||||
$(w).bind('widget-focus.formBlur', self.proxy('widgetFocused'))
|
||||
.bind('widget-blur.formBlur', self.proxy('widgetBlurred'));
|
||||
});
|
||||
this.$form_header = this.$element.find('.oe_form_header:first');
|
||||
this.$form_header.find('div.oe_form_pager button[data-pager-action]').click(function() {
|
||||
|
@ -130,6 +140,29 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.has_been_loaded.resolve();
|
||||
},
|
||||
|
||||
widgetFocused: function() {
|
||||
// Clear click flag if used to focus a widget
|
||||
this.__clicked_inside = false;
|
||||
if (this.__blur_timeout) {
|
||||
clearTimeout(this.__blur_timeout);
|
||||
this.__blur_timeout = null;
|
||||
}
|
||||
},
|
||||
widgetBlurred: function() {
|
||||
if (this.__clicked_inside) {
|
||||
// clicked in an other section of the form (than the currently
|
||||
// focused widget) => just ignore the blurring entirely?
|
||||
this.__clicked_inside = false;
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
// clear timeout, if any
|
||||
this.widgetFocused();
|
||||
this.__blur_timeout = setTimeout(function () {
|
||||
$(self).trigger('form-blur');
|
||||
}, 0);
|
||||
},
|
||||
|
||||
do_load_state: function(state, warm) {
|
||||
if (state.id && this.datarecord.id != state.id) {
|
||||
if (!this.dataset.get_id_index(state.id)) {
|
||||
|
@ -549,7 +582,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
return $.Deferred().reject();
|
||||
} else {
|
||||
return $.when(this.reload()).pipe(function () {
|
||||
return $.when(r).then(success); }, null);
|
||||
return r; })
|
||||
.then(success);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
@ -583,8 +617,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
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) {
|
||||
|
@ -924,6 +959,18 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo
|
|||
|
||||
this.width = this.node.attrs.width;
|
||||
},
|
||||
/**
|
||||
* Sets up blur/focus forwarding from DOM elements to a widget (`this`)
|
||||
*
|
||||
* @param {jQuery} $e jQuery object of elements to bind focus/blur on
|
||||
*/
|
||||
setupFocus: function ($e) {
|
||||
var self = this;
|
||||
$e.bind({
|
||||
focus: function () { $(self).trigger('widget-focus'); },
|
||||
blur: function () { $(self).trigger('widget-blur'); }
|
||||
});
|
||||
},
|
||||
start: function() {
|
||||
this.$element = this.view.$element.find(
|
||||
'.' + this.element_class.replace(/[^\r\n\f0-9A-Za-z_-]/g, "\\$&"));
|
||||
|
@ -1210,10 +1257,12 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
|
|||
},
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find("button").click(this.on_click);
|
||||
var $button = this.$element.find('button');
|
||||
$button.click(this.on_click);
|
||||
if (this.help || openerp.connection.debug) {
|
||||
this.do_attach_tooltip();
|
||||
}
|
||||
this.setupFocus($button);
|
||||
},
|
||||
on_click: function() {
|
||||
var self = this;
|
||||
|
@ -1327,11 +1376,13 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
|
|||
if (this['for'] && (this['for'].help || openerp.connection.debug)) {
|
||||
this.do_attach_tooltip(self['for']);
|
||||
}
|
||||
this.$element.find("label").dblclick(function() {
|
||||
var $label = this.$element.find('label');
|
||||
$label.dblclick(function() {
|
||||
var widget = self['for'] || self;
|
||||
openerp.log(widget.element_class , widget);
|
||||
window.w = widget;
|
||||
});
|
||||
this.setupFocus($label);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1458,7 +1509,9 @@ openerp.web.form.FieldChar = openerp.web.form.Field.extend({
|
|||
},
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('input').change(this.on_ui_change);
|
||||
var $input = this.$element.find('input');
|
||||
$input.change(this.on_ui_change);
|
||||
this.setupFocus($input);
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -1499,7 +1552,9 @@ openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({
|
|||
template: 'FieldEmail',
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('button').click(this.on_button_clicked);
|
||||
var $button = this.$element.find('button');
|
||||
$button.click(this.on_button_clicked);
|
||||
this.setupFocus($button);
|
||||
},
|
||||
on_button_clicked: function() {
|
||||
if (!this.value || !this.is_valid()) {
|
||||
|
@ -1514,7 +1569,9 @@ openerp.web.form.FieldUrl = openerp.web.form.FieldChar.extend({
|
|||
template: 'FieldUrl',
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('button').click(this.on_button_clicked);
|
||||
var $button = this.$element.find('button');
|
||||
$button.click(this.on_button_clicked);
|
||||
this.setupFocus($button);
|
||||
},
|
||||
on_button_clicked: function() {
|
||||
if (!this.value) {
|
||||
|
@ -1564,12 +1621,14 @@ openerp.web.DateTimeWidget = openerp.web.OldWidget.extend({
|
|||
showButtonPanel: true
|
||||
});
|
||||
this.$element.find('img.oe_datepicker_trigger').click(function() {
|
||||
if (!self.readonly && !self.picker('widget').is(':visible')) {
|
||||
self.picker('setDate', self.value ? openerp.web.auto_str_to_date(self.value) : new Date());
|
||||
self.$input_picker.show();
|
||||
self.picker('show');
|
||||
self.$input_picker.hide();
|
||||
if (self.readonly || self.picker('widget').is(':visible')) {
|
||||
self.$input.focus();
|
||||
return;
|
||||
}
|
||||
self.picker('setDate', self.value ? openerp.web.auto_str_to_date(self.value) : new Date());
|
||||
self.$input_picker.show();
|
||||
self.picker('show');
|
||||
self.$input_picker.hide();
|
||||
});
|
||||
this.set_readonly(false);
|
||||
this.value = false;
|
||||
|
@ -1579,7 +1638,10 @@ openerp.web.DateTimeWidget = openerp.web.OldWidget.extend({
|
|||
},
|
||||
on_picker_select: function(text, instance) {
|
||||
var date = this.picker('getDate');
|
||||
this.$input.val(date ? this.format_client(date) : '').change();
|
||||
this.$input
|
||||
.val(date ? this.format_client(date) : '')
|
||||
.change()
|
||||
.focus();
|
||||
},
|
||||
set_value: function(value) {
|
||||
this.value = value;
|
||||
|
@ -1639,6 +1701,7 @@ openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({
|
|||
this.datewidget = this.build_widget();
|
||||
this.datewidget.on_change.add_last(this.on_ui_change);
|
||||
this.datewidget.appendTo(this.$element);
|
||||
this.setupFocus(this.datewidget.$input);
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super(value);
|
||||
|
@ -1669,8 +1732,10 @@ openerp.web.form.FieldText = openerp.web.form.Field.extend({
|
|||
template: 'FieldText',
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('textarea').change(this.on_ui_change);
|
||||
var $textarea = this.$element.find('textarea');
|
||||
$textarea.change(this.on_ui_change);
|
||||
this.resized = false;
|
||||
this.setupFocus($textarea);
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -1731,7 +1796,9 @@ openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({
|
|||
start: function() {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('input').click(self.on_ui_change);
|
||||
var $input = this.$element.find('input');
|
||||
$input.click(self.on_ui_change);
|
||||
this.setupFocus($input);
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -1801,7 +1868,8 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
|
|||
// row
|
||||
var ischanging = false;
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('select')
|
||||
var $select = this.$element.find('select');
|
||||
$select
|
||||
.change(this.on_ui_change)
|
||||
.change(function () { ischanging = true; })
|
||||
.click(function () { ischanging = false; })
|
||||
|
@ -1810,6 +1878,7 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
|
|||
e.stopPropagation();
|
||||
ischanging = false;
|
||||
});
|
||||
this.setupFocus($select);
|
||||
},
|
||||
set_value: function(value) {
|
||||
value = value === null ? false : value;
|
||||
|
@ -1920,6 +1989,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
|||
};
|
||||
bindings[self.cm_id + "_open"] = function() {
|
||||
if (!self.value) {
|
||||
self.focus();
|
||||
return;
|
||||
}
|
||||
var pop = new openerp.web.form.FormOpenPopup(self.view);
|
||||
|
@ -1933,6 +2003,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
|||
);
|
||||
pop.on_write_completed.add_last(function() {
|
||||
self.set_value(self.value[0]);
|
||||
self.focus();
|
||||
});
|
||||
};
|
||||
_.each(_.range(self.related_entries.length), function(i) {
|
||||
|
@ -1975,13 +2046,13 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
|||
return;
|
||||
if (self.$input.autocomplete("widget").is(":visible")) {
|
||||
self.$input.autocomplete("close");
|
||||
self.$input.focus();
|
||||
} else {
|
||||
if (self.value) {
|
||||
self.$input.autocomplete("search", "");
|
||||
} else {
|
||||
self.$input.autocomplete("search");
|
||||
}
|
||||
self.$input.focus();
|
||||
}
|
||||
});
|
||||
var anyoneLoosesFocus = function() {
|
||||
|
@ -2020,6 +2091,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
|||
minLength: 0,
|
||||
delay: 0
|
||||
});
|
||||
|
||||
// used to correct a bug when selecting an element by pushing 'enter' in an editable list
|
||||
this.$input.keyup(function(e) {
|
||||
if (e.which === 13) {
|
||||
|
@ -2028,6 +2100,8 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
|||
}
|
||||
isSelecting = false;
|
||||
});
|
||||
|
||||
this.setupFocus(this.$input.add(this.$menu_btn));
|
||||
},
|
||||
// autocomplete component content handling
|
||||
get_search_result: function(request, response) {
|
||||
|
@ -2129,6 +2203,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
|||
var dataset = new openerp.web.DataSetStatic(self, self.field.relation, self.build_context());
|
||||
dataset.name_get([element_ids[0]], function(data) {
|
||||
self._change_int_ext_value(data[0]);
|
||||
self.focus();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -2508,23 +2583,20 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
|||
}, 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 +2628,47 @@ openerp.web.form.One2ManyDataSet = openerp.web.BufferedDataSet.extend({
|
|||
|
||||
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 +2722,7 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
|
|||
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 +2735,37 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
|
|||
return this._super(name, id, _.bind(def.resolve, def));
|
||||
}
|
||||
});
|
||||
openerp.web.form.One2ManyList = openerp.web.ListView.List.extend({
|
||||
KEY_RETURN: 13,
|
||||
// blurring caused by hitting the [Return] key, should skip the
|
||||
// autosave-on-blur and let the handler for [Return] do its thing
|
||||
__return_blur: false,
|
||||
render_row_as_form: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
self.edition_form.$element
|
||||
.undelegate('button.oe-edit-row-save', 'click')
|
||||
.delegate('button.oe-edit-row-save', 'click', function () {
|
||||
self.cancel_pending_edition();
|
||||
});
|
||||
$(self.edition_form).bind('form-blur', function () {
|
||||
if (self.__return_blur) {
|
||||
delete self.__return_blur;
|
||||
return;
|
||||
}
|
||||
if (!self.edition_form.widget_is_stopped) {
|
||||
self.view.ensure_saved();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
on_row_keyup: function (e) {
|
||||
if (e.which === this.KEY_RETURN) {
|
||||
this.__return_blur = true;
|
||||
}
|
||||
this._super(e);
|
||||
}
|
||||
});
|
||||
|
||||
openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
|
||||
form_template: 'One2Many.formview',
|
||||
|
@ -3140,9 +3284,14 @@ openerp.web.form.FieldReference = openerp.web.form.Field.extend({
|
|||
}
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this._super();
|
||||
this.selection.start();
|
||||
this.m2o.start();
|
||||
$(this.selection).add($(this.m2o)).bind({
|
||||
'focus': function () { $(self).trigger('widget-focus'); },
|
||||
'blur': function () { $(self).trigger('widget-blur'); }
|
||||
})
|
||||
},
|
||||
is_valid: function() {
|
||||
return this.required === false || typeof(this.get_value()) === 'string';
|
||||
|
|
|
@ -61,7 +61,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
|||
|
||||
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 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
|||
|
||||
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 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
|||
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 (self.view.options.GroupsType)(self.view, {
|
||||
records: self.records.proxy(group.value),
|
||||
options: self.options,
|
||||
columns: self.columns
|
||||
|
@ -1297,7 +1305,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
|||
},
|
||||
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,
|
||||
|
|
|
@ -124,29 +124,27 @@ openerp.web.list_editable = function (openerp) {
|
|||
* 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 @@ openerp.web.list_editable = function (openerp) {
|
|||
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 @@ openerp.web.list_editable = function (openerp) {
|
|||
},
|
||||
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 @@ openerp.web.list_editable = function (openerp) {
|
|||
})
|
||||
.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 @@ openerp.web.list_editable = function (openerp) {
|
|||
}
|
||||
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 @@ openerp.web.list_editable = function (openerp) {
|
|||
});
|
||||
// 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 @@ openerp.web.list_editable = function (openerp) {
|
|||
*/
|
||||
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 @@ openerp.web.list_editable = function (openerp) {
|
|||
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 @@ openerp.web.list_editable = function (openerp) {
|
|||
[record_id, this.dataset]);
|
||||
},
|
||||
new_record: function () {
|
||||
this.dataset.index = null;
|
||||
this.render_row_as_form();
|
||||
},
|
||||
render_record: function (record) {
|
||||
|
@ -405,12 +423,12 @@ openerp.web.list_editable = function (openerp) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue