', {
+ id: _.uniqueId('oe-editable-row-'),
+ 'class': $(row).attr('class'),
+ click: function (e) {e.stopPropagation();}
+ })
+ .delegate('button.oe-edit-row-save', 'click', function () {
+ self.save_row();
+ })
+ .delegate('button.oe-edit-row-cancel', 'click', function () {
+ self.cancel_edition();
+ })
+ .delegate('button', 'keyup', function (e) {
+ e.stopImmediatePropagation();
+ })
+ .keyup(function (e) {
+ switch (e.which) {
+ case KEY_RETURN:
+ self.save_row(true);
+ break;
+ case KEY_ESCAPE:
+ self.cancel_edition();
+ break;
+ default:
+ return;
+ }
+ });
+ if (row) {
+ $new_row.replaceAll(row);
+ } else if (self.options.editable === 'top') {
+ self.$current.prepend($new_row);
+ } else if (self.options.editable) {
+ self.$current.append($new_row);
+ }
+ self.edition = true;
+ self.edition_index = self.dataset.index;
+ self.edition_form = _.extend(new openerp.base.FormView(
+ null, self.group.view.session, $new_row.attr('id'),
+ self.dataset, false), {
+ template: 'ListView.row.form',
+ registry: openerp.base.list.form.widgets
});
+ $.when(self.edition_form.on_loaded({fields_view: self.get_form_fields_view()})).then(function () {
+ // put in $.when just in case FormView.on_loaded becomes asynchronous
+ $new_row.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();
+ // pad in case of groupby
+ _(self.columns).each(function (column) {
+ if (column.meta) {
+ $new_row.prepend('| ');
+ }
+ });
- self.edition_form.do_show();
+ self.edition_form.do_show();
+ });
});
},
/**
@@ -188,12 +214,7 @@ openerp.base.list.editable = function (openerp) {
save_row: function (edit_next) {
var self = this;
this.edition_form.do_save(function (result) {
- self.reload_record(self.dataset.index, true).then(function () {
- self.edition_form.stop();
- delete self.edition_form;
- delete self.edition_index;
- delete self.edition;
-
+ self.cancel_pending_edition().then(function () {
$(self).trigger('saved', [self.dataset]);
if (!edit_next) {
return;
@@ -230,7 +251,12 @@ openerp.base.list.editable = function (openerp) {
this.render_row_as_form();
}
});
- openerp.base.list = {form: {}};
+ if (!openerp.base.list) {
+ openerp.base.list = {};
+ }
+ if (!openerp.base.list.form) {
+ openerp.base.list.form = {};
+ }
openerp.base.list.form.WidgetFrame = openerp.base.form.WidgetFrame.extend({
template: 'ListView.row.frame'
});
@@ -251,10 +277,12 @@ openerp.base.list.editable = function (openerp) {
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') {
+ if (this.invisible) {
this.$element.children().css('visibility', 'hidden');
} else {
+ this.invisible = !!this.modifiers.tree_invisible;
this._super();
+ this.invisible = false;
}
}
});
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index 62bedf8784d..d64d83329c0 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -1,5 +1,63 @@
openerp.base.list = function (openerp) {
openerp.base.views.add('list', 'openerp.base.ListView');
+openerp.base.list = {
+ /**
+ * Formats the rendring of a given value based on its field type
+ *
+ * @param {Object} row_data record whose values should be displayed in the cell
+ * @param {Object} column column descriptor
+ * @param {"button"|"field"} column.tag base control type
+ * @param {String} column.type widget type for a field control
+ * @param {String} [column.string] button label
+ * @param {String} [column.icon] button icon
+ * @param {String} [value_if_empty=''] what to display if the field's value is ``false``
+ */
+ render_cell: function (row_data, column, value_if_empty) {
+ var attrs = column.modifiers_for(row_data);
+ if (attrs.invisible) { return ''; }
+ if (column.tag === 'button') {
+ return [
+ ''
+ ].join('')
+ }
+
+ var value = row_data[column.id].value;
+
+ // If NaN value, display as with a `false` (empty cell)
+ if (typeof value === 'number' && isNaN(value)) {
+ value = false;
+ }
+ switch (value) {
+ case false:
+ case Infinity:
+ case -Infinity:
+ return value_if_empty === undefined ? '' : value_if_empty;
+ }
+ switch (column.widget || column.type) {
+ case 'integer':
+ return _.sprintf('%d', value);
+ case 'float':
+ var precision = column.digits ? column.digits[1] : 2;
+ return _.sprintf('%.' + precision + 'f', value);
+ case 'float_time':
+ return _.sprintf("%02d:%02d",
+ Math.floor(value),
+ Math.round((value % 1) * 60));
+ case 'progressbar':
+ return _.sprintf(
+ '',
+ value, value);
+ case 'many2one':
+ // name_get value format
+ return value[1];
+ default:
+ return value;
+ }
+ }
+};
openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListView# */ {
defaults: {
// records can be selected one by one
@@ -42,9 +100,10 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
*
* @borrows openerp.base.ActionExecutor#execute_action as #execute_action
*/
- init: function(view_manager, session, element_id, dataset, view_id, options) {
- this._super(session, element_id);
- this.view_manager = view_manager || new openerp.base.NullViewManager();
+ init: function(parent, element_id, dataset, view_id, options) {
+ this._super(parent, element_id);
+ this.set_default_options();
+ this.view_manager = parent || new openerp.base.NullViewManager();
this.dataset = dataset;
this.model = dataset.model;
this.view_id = view_id;
@@ -52,13 +111,30 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
this.columns = [];
this.options = _.extend({}, this.defaults, options || {});
- this.flags = this.view_manager.flags || {};
this.set_groups(new openerp.base.ListView.Groups(this));
-
+
if (this.dataset instanceof openerp.base.DataSetStatic) {
this.groups.datagroup = new openerp.base.StaticDataGroup(this.dataset);
}
+
+ this.page = 0;
+ },
+ /**
+ * Retrieves the view's number of records per page (|| section)
+ *
+ * options > defaults > view_manager.action.limit > indefinite
+ *
+ * @returns {Number|null}
+ */
+ limit: function () {
+ if (this._limit === undefined) {
+ this._limit = (this.options.limit
+ || this.defaults.limit
+ || (this.view_manager.action || {}).limit
+ || null);
+ }
+ return this._limit;
},
/**
* Set a custom Group construct as the root of the List View.
@@ -129,27 +205,103 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
this.setup_columns(this.fields_view.fields, grouped);
- if (!this.fields_view.sorted) { this.fields_view.sorted = {}; }
-
this.$element.html(QWeb.render("ListView", this));
// Head hook
- this.$element.find('#oe-list-add')
+ this.$element.find('.oe-list-add')
.click(this.do_add_record)
.attr('disabled', grouped && this.options.editable);
- this.$element.find('#oe-list-delete')
+ this.$element.find('.oe-list-delete')
.attr('disabled', true)
.click(this.do_delete_selected);
- this.$element.find('thead').delegate('th[data-id]', 'click', function (e) {
+ this.$element.find('thead').delegate('th.oe-sortable[data-id]', 'click', function (e) {
e.stopPropagation();
- self.dataset.sort($(this).data('id'));
+ var $this = $(this);
+ self.dataset.sort($this.data('id'));
+ if ($this.find('span').length) {
+ $this.find('span').toggleClass(
+ 'ui-icon-triangle-1-s ui-icon-triangle-1-n');
+ } else {
+ $this.append('')
+ .siblings('.oe-sortable').find('span').remove();
+ }
- // TODO: should only reload content (and set the right column to a sorted display state)
- self.reload_view();
+ self.reload_content();
});
- this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
+ this.$element.find('.oe-list-pager')
+ .delegate('button', 'click', function () {
+ var $this = $(this);
+ switch ($this.data('pager-action')) {
+ case 'first':
+ self.page = 0; break;
+ case 'last':
+ self.page = Math.floor(
+ self.dataset.ids.length / self.limit());
+ break;
+ case 'next':
+ self.page += 1; break;
+ case 'previous':
+ self.page -= 1; break;
+ }
+ self.reload_content();
+ }).find('.oe-pager-state')
+ .click(function (e) {
+ e.stopPropagation();
+ var $this = $(this);
+
+ var $select = $(' |