2011-06-03 09:36:06 +00:00
|
|
|
/**
|
|
|
|
* @namespace handles editability case for lists, because it depends on form and forms already depends on lists it had to be split out
|
|
|
|
*/
|
|
|
|
openerp.base.list.editable = function (openerp) {
|
2011-06-03 14:16:38 +00:00
|
|
|
var KEY_RETURN = 13,
|
|
|
|
KEY_ESCAPE = 27;
|
|
|
|
|
2011-06-03 09:36:06 +00:00
|
|
|
// editability status of list rows
|
|
|
|
openerp.base.ListView.prototype.defaults.editable = null;
|
|
|
|
|
|
|
|
var old_actual_search = openerp.base.ListView.prototype.do_actual_search;
|
2011-06-06 09:59:18 +00:00
|
|
|
var old_add_record = openerp.base.ListView.prototype.do_add_record;
|
|
|
|
var old_on_loaded = openerp.base.ListView.prototype.on_loaded;
|
2011-06-03 09:36:06 +00:00
|
|
|
_.extend(openerp.base.ListView.prototype, {
|
|
|
|
/**
|
|
|
|
* 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) {
|
|
|
|
// If ``force``, set editability to bottom
|
|
|
|
// otherwise rely on view default
|
2011-06-06 09:59:18 +00:00
|
|
|
// view' @editable is handled separately as we have not yet
|
|
|
|
// fetched and processed the view at this point.
|
2011-06-03 09:36:06 +00:00
|
|
|
this.options.editable = (
|
|
|
|
(force && "bottom")
|
|
|
|
|| this.defaults.editable);
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Replace do_actual_search to handle editability process
|
|
|
|
*/
|
|
|
|
do_actual_search: function (results) {
|
|
|
|
this.set_editable(results.context['set_editable']);
|
|
|
|
old_actual_search.call(this, results);
|
2011-06-06 09:59:18 +00:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Replace do_add_record to handle editability (and adding new record
|
|
|
|
* as an editable row at the top or bottom of the list)
|
|
|
|
*/
|
|
|
|
do_add_record: function () {
|
|
|
|
if (this.options.editable) {
|
|
|
|
this.groups.new_record();
|
|
|
|
} else {
|
|
|
|
old_add_record.call(this);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
on_loaded: function (data, grouped) {
|
|
|
|
// tree/@editable takes priority on everything else if present.
|
|
|
|
this.options.editable = data.fields_view.arch.editable || this.options.editable;
|
|
|
|
return old_on_loaded.call(this, data, grouped);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
_.extend(openerp.base.ListView.Groups.prototype, {
|
|
|
|
new_record: function () {
|
|
|
|
// TODO: handle multiple children
|
|
|
|
this.children[null].new_record();
|
2011-06-03 09:36:06 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
var old_list_row_clicked = openerp.base.ListView.List.prototype.row_clicked;
|
|
|
|
_.extend(openerp.base.ListView.List.prototype, {
|
|
|
|
row_clicked: function (event, index) {
|
|
|
|
if (!this.options.editable) {
|
|
|
|
return old_list_row_clicked.call(this, event, index);
|
|
|
|
}
|
|
|
|
this.render_row_as_form(index, event.currentTarget);
|
|
|
|
},
|
|
|
|
render_row_as_form: function (row_num, row) {
|
2011-06-03 12:24:43 +00:00
|
|
|
var self = this;
|
2011-06-03 09:36:06 +00:00
|
|
|
var $new_row = $('<tr>', {
|
|
|
|
id: _.uniqueId('oe-editable-row-'),
|
|
|
|
'class': $(row).attr('class'),
|
|
|
|
onclick: function (e) {e.stopPropagation();}
|
2011-06-06 09:59:18 +00:00
|
|
|
})
|
2011-06-03 12:24:43 +00:00
|
|
|
.keyup(function (e) {
|
2011-06-03 14:16:38 +00:00
|
|
|
switch (e.which) {
|
|
|
|
case KEY_RETURN:
|
|
|
|
self.save_row(row_num, true);
|
|
|
|
break;
|
|
|
|
case KEY_ESCAPE:
|
|
|
|
self.cancel_edition(row_num);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
2011-06-03 12:24:43 +00:00
|
|
|
}
|
|
|
|
})
|
2011-06-03 14:16:38 +00:00
|
|
|
.delegate('button.oe-edit-row-save', 'click', function () {
|
2011-06-03 12:24:43 +00:00
|
|
|
self.save_row(row_num);
|
2011-06-03 14:16:38 +00:00
|
|
|
})
|
|
|
|
.delegate('button.oe-edit-row-cancel', 'click', function () {
|
|
|
|
self.cancel_edition(row_num);
|
2011-06-03 12:24:43 +00:00
|
|
|
});
|
2011-06-06 09:59:18 +00:00
|
|
|
if (row) {
|
|
|
|
$new_row.replaceAll(row);
|
|
|
|
} else if (this.options.editable === 'top') {
|
|
|
|
this.$current.prepend($new_row);
|
|
|
|
} else if (this.options.editable) {
|
|
|
|
this.$current.append($new_row);
|
|
|
|
}
|
2011-06-03 12:24:43 +00:00
|
|
|
this.edition_form = _.extend(new openerp.base.FormView(
|
2011-06-03 09:36:06 +00:00
|
|
|
null, this.group.view.session, $new_row.attr('id'),
|
2011-06-03 10:31:00 +00:00
|
|
|
this.dataset, false), {
|
|
|
|
template: 'ListView.row.form',
|
|
|
|
registry: openerp.base.list.form.widgets
|
|
|
|
});
|
2011-06-03 12:24:43 +00:00
|
|
|
this.edition_form.on_loaded({fields_view: this.get_fields_view()});
|
|
|
|
this.edition_form.on_record_loaded.add({
|
2011-06-03 09:36:06 +00:00
|
|
|
position: 'last',
|
|
|
|
unique: true,
|
|
|
|
callback: function () {
|
2011-06-03 12:24:43 +00:00
|
|
|
self.edition_form.$element
|
|
|
|
.find('td')
|
|
|
|
.addClass('oe-field-cell')
|
|
|
|
.removeAttr('width')
|
|
|
|
.end()
|
|
|
|
.find('td:first').removeClass('oe-field-cell').end()
|
|
|
|
.find('td:last').removeClass('oe-field-cell').end();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.edition_form.do_show();
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Saves the current row, and triggers the edition of its following
|
|
|
|
* sibling if asked.
|
|
|
|
*
|
|
|
|
* @param {Number} row_num the row to save
|
|
|
|
* @param {Boolean} [edit_next=false] should the next row become editable
|
|
|
|
*/
|
|
|
|
save_row: function (row_num, edit_next) {
|
|
|
|
var self = this;
|
|
|
|
this.edition_form.do_save(function () {
|
2011-06-03 14:37:23 +00:00
|
|
|
self.reload_record(row_num, true).then(function () {
|
|
|
|
self.edition_form.stop();
|
|
|
|
delete self.edition_form;
|
|
|
|
if (edit_next && self.rows.length > row_num + 1) {
|
|
|
|
self.dataset.index++;
|
|
|
|
self.row_clicked({
|
|
|
|
currentTarget: self.$current.children().eq(row_num + 1)
|
|
|
|
}, row_num + 1);
|
2011-06-03 13:24:38 +00:00
|
|
|
}
|
2011-06-03 14:37:23 +00:00
|
|
|
});
|
2011-06-03 09:36:06 +00:00
|
|
|
});
|
2011-06-03 14:16:38 +00:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Cancels the edition of the row at index ``row_num``.
|
|
|
|
*
|
|
|
|
* @param {Number} row_num index of the row being edited
|
|
|
|
*/
|
|
|
|
cancel_edition: function (row_num) {
|
|
|
|
this.reload_record(row_num);
|
|
|
|
this.edition_form.stop();
|
|
|
|
delete this.edition_form;
|
2011-06-06 09:59:18 +00:00
|
|
|
},
|
|
|
|
new_record: function () {
|
|
|
|
this.dataset.index = null;
|
|
|
|
this.render_row_as_form(-1, null);
|
2011-06-03 09:36:06 +00:00
|
|
|
}
|
|
|
|
});
|
2011-06-03 10:31:00 +00:00
|
|
|
openerp.base.list = {form: {}};
|
|
|
|
openerp.base.list.form.WidgetFrame = openerp.base.form.WidgetFrame.extend({
|
|
|
|
template: 'ListView.row.frame'
|
|
|
|
});
|
2011-06-03 11:57:57 +00:00
|
|
|
var form_widgets = openerp.base.form.widgets;
|
|
|
|
openerp.base.list.form.widgets = form_widgets.clone({
|
2011-06-03 10:31:00 +00:00
|
|
|
'frame': 'openerp.base.list.form.WidgetFrame'
|
|
|
|
});
|
2011-06-03 11:57:57 +00:00
|
|
|
// All form widgets inherit a problematic behavior from
|
|
|
|
// openerp.base.form.WidgetFrame: the cell itself is removed when invisible
|
|
|
|
// whether it's @invisible or @attrs[invisible]. In list view, only the
|
|
|
|
// former should completely remove the cell. We need to override update_dom
|
|
|
|
// on all widgets since we can't just hit on widget itself (I think)
|
|
|
|
var list_form_widgets = openerp.base.list.form.widgets;
|
|
|
|
_(list_form_widgets.map).each(function (widget_path, key) {
|
|
|
|
if (key === 'frame') { return; }
|
|
|
|
var new_path = 'openerp.base.list.form.' + key;
|
|
|
|
|
|
|
|
openerp.base.list.form[key] = (form_widgets.get_object(key)).extend({
|
|
|
|
update_dom: function () {
|
|
|
|
this.$element.children().css('visibility', '');
|
|
|
|
if (this.invisible && this.node.attrs.invisible !== '1') {
|
|
|
|
this.$element.children().css('visibility', 'hidden');
|
|
|
|
} else {
|
|
|
|
this._super();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
list_form_widgets.add(key, new_path);
|
|
|
|
});
|
2011-06-03 09:36:06 +00:00
|
|
|
};
|