summaryrefslogtreecommitdiff
path: root/addons/base/static/src
diff options
context:
space:
mode:
authorXavier Morel <xmo@openerp.com>2011-07-06 10:32:14 +0200
committerXavier Morel <xmo@openerp.com>2011-07-06 10:32:14 +0200
commit1847dbc017ca226ce3e5276489474e686cc2ac8d (patch)
treee9461726041a5465a1c5f12eddcc8968218b89c6 /addons/base/static/src
parentd44af4944d89ed326f5a0257ffe3528c4d1bc61f (diff)
parentfcc0a982f56baab310dfe45278e12da8b87daa7e (diff)
[MERGE] list pagination branch
bzr revid: xmo@openerp.com-20110706083214-1thifexcz5pk0jih
Diffstat (limited to 'addons/base/static/src')
-rw-r--r--addons/base/static/src/css/base.css14
-rw-r--r--addons/base/static/src/js/data.js13
-rw-r--r--addons/base/static/src/js/form.js19
-rw-r--r--addons/base/static/src/js/list-editable.js19
-rw-r--r--addons/base/static/src/js/list.js181
-rw-r--r--addons/base/static/src/xml/base.xml21
6 files changed, 208 insertions, 59 deletions
diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css
index 32a335d7eb8..e91bbd922ec 100644
--- a/addons/base/static/src/css/base.css
+++ b/addons/base/static/src/css/base.css
@@ -606,6 +606,9 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
vertical-align: middle;
text-align: left;
}
+.openerp .oe-listview td.oe-record-delete {
+ text-align: right;
+}
.openerp .oe-listview th.oe-sortable,
.openerp .oe-listview th.oe-sortable .ui-icon {
cursor: pointer;
@@ -636,6 +639,17 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
.openerp .oe-listview th.oe-list-pager {
text-align: right;
}
+.openerp .oe-list-pager .oe-pager-state {
+ cursor: pointer;
+}
+
+.openerp .oe-listview .oe-group-name {
+ padding-right: 1em;
+}
+.openerp .oe-listview .oe-group-name,
+.openerp .oe-listview .oe-group-pagination {
+ white-space: nowrap;
+}
.openerp .oe-listview tfoot td {
padding: 3px 3px 0;
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index 5fc43689709..1eb9c0f0a0d 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -196,7 +196,9 @@ openerp.base.GrouplessDataGroup = openerp.base.DataGroup.extend(
this._super(session, model, domain, context, null, level);
},
list: function (ifGroups, ifRecords) {
- ifRecords(new openerp.base.DataSetSearch(this.session, this.model, this.context, this.domain));
+ ifRecords(_.extend(
+ new openerp.base.DataSetSearch(this.session, this.model),
+ {domain: this.domain, context: this.context}));
}
});
@@ -421,13 +423,10 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
sort: this.sort(),
offset: offset,
limit: limit
- }, function (records) {
- self.ids.splice(0, self.ids.length);
+ }, function (result) {
+ self.ids = result.ids;
self.offset = offset;
- for (var i=0; i < records.length; i++ ) {
- self.ids.push(records[i].id);
- }
- callback(records);
+ callback(result.records);
});
},
/**
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 874ff247a6f..0c2ec73af81 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -166,7 +166,6 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.ready = false;
var onchange = _.trim(widget.node.attrs.on_change);
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
- console.log("Onchange triggered for field '%s' -> %s", widget.name, onchange);
if (call) {
var method = call[1], args = [];
var context_index = null;
@@ -226,14 +225,12 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
on_processed_onchange: function(response, processed) {
var result = response.result;
if (result.value) {
- console.log(" |-> Onchange Response :", result.value);
for (var f in result.value) {
var field = this.fields[f];
if (field) {
var value = result.value[f];
processed.push(field.name);
if (field.get_value() != value) {
- console.log(" |-> Onchange Action : change '%s' value from '%s' to '%s'", field.name, field.get_value(), value);
field.set_value(value);
field.touched = true;
if (_.indexOf(processed, field.name) < 0) {
@@ -242,12 +239,11 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
}
} else {
// this is a common case, the normal behavior should be to ignore it
- console.debug("on_processed_onchange can't find field " + f, result);
}
}
this.on_form_changed();
}
- if (result.warning && !_.isEmpty(result.warning)) {
+ if (!_.isEmpty(result.warning)) {
$(QWeb.render("DialogWarning", result.warning)).dialog({
modal: true,
buttons: {
@@ -396,12 +392,13 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.on_attachments_loaded([]);
} else {
// TODO fme: modify this so it doesn't try to load attachments when there is not sidebar
- /*this.rpc('/base/dataset/search_read', {
- model: 'ir.attachment',
- fields: ['name', 'url', 'type'],
- domain: [['res_model', '=', this.dataset.model], ['res_id', '=', this.datarecord.id], ['type', 'in', ['binary', 'url']]],
- context: this.dataset.get_context()
- }, this.on_attachments_loaded);*/
+ /*(new openerp.base.DataSetSearch(
+ this.session, 'ir.attachment', this.dataset.get_context(),
+ [['res_model', '=', this.dataset.model],
+ ['res_id', '=', this.datarecord.id],
+ ['type', 'in', ['binary', 'url']]])).read_slice(
+ ['name', 'url', 'type'], false, false,
+ this.on_attachments_loaded);*/
}
},
on_attachments_loaded: function(attachments) {
diff --git a/addons/base/static/src/js/list-editable.js b/addons/base/static/src/js/list-editable.js
index b97a35d0612..8b4b16faf04 100644
--- a/addons/base/static/src/js/list-editable.js
+++ b/addons/base/static/src/js/list-editable.js
@@ -116,6 +116,23 @@ openerp.base.list.editable = function (openerp) {
delete this.edition_index;
delete this.edition;
},
+ /**
+ * Adapts this list's view description to be suitable to the inner form view of a row being edited.
+ *
+ * @returns {Object} fields_view_get's view section suitable for putting into form view of editable rows.
+ */
+ get_form_fields_view: function () {
+ // deep copy of view
+ var view = $.extend(true, {}, this.group.view.fields_view);
+ _(view.arch.children).each(function (widget) {
+ widget.attrs.nolabel = true;
+ if (widget.tag === 'button') {
+ delete widget.attrs.string;
+ }
+ });
+ view.arch.attrs.col = 2 * view.arch.children.length;
+ return view;
+ },
render_row_as_form: function (row) {
this.cancel_pending_edition();
@@ -161,7 +178,7 @@ openerp.base.list.editable = function (openerp) {
template: 'ListView.row.form',
registry: openerp.base.list.form.widgets
});
- $.when(this.edition_form.on_loaded({fields_view: this.get_fields_view()})).then(function () {
+ $.when(this.edition_form.on_loaded({fields_view: this.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')
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index 9c68e4f9b78..aa3fe3f658b 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -59,6 +59,24 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
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.
@@ -134,10 +152,10 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
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) {
@@ -149,9 +167,76 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
self.reload_view();
});
+ 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 = $('<select>')
+ .appendTo($this.empty())
+ .click(function (e) {e.stopPropagation();})
+ .append('<option value="80">80</option>' +
+ '<option value="100">100</option>' +
+ '<option value="200">200</option>' +
+ '<option value="500">500</option>' +
+ '<option value="NaN">Unlimited</option>')
+ .change(function () {
+ var val = parseInt($select.val(), 10);
+ self._limit = (isNaN(val) ? null : val);
+ self.page = 0;
+ self.reload_content();
+ })
+ .val(self._limit || 'NaN');
+ });
+
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
},
/**
+ * Configures the ListView pager based on the provided dataset's information
+ *
+ * Horrifying side-effect: sets the dataset's data on this.dataset?
+ *
+ * @param {openerp.base.DataSet} dataset
+ */
+ configure_pager: function (dataset) {
+ this.dataset.ids = dataset.ids;
+
+ var limit = this.limit(),
+ total = dataset.ids.length,
+ first = (this.page * limit),
+ last;
+ if (!limit || (total - first) < limit) {
+ last = total;
+ } else {
+ last = first + limit;
+ }
+ this.$element.find('span.oe-pager-state').empty().text(_.sprintf(
+ "[%d to %d] of %d", first + 1, last, total));
+
+ this.$element
+ .find('button[data-pager-action=first], button[data-pager-action=previous]')
+ .attr('disabled', this.page === 0)
+ .end()
+ .find('button[data-pager-action=last], button[data-pager-action=next]')
+ .attr('disabled', last === total);
+ },
+ /**
* Sets up the listview's columns: merges view and fields data, move
* grouped-by columns to the front of the columns list and make them all
* visible.
@@ -182,7 +267,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
}
return column;
};
-
+
this.columns.splice(0, this.columns.length);
this.columns.push.apply(
this.columns,
@@ -264,10 +349,8 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
*/
reload_view: function (grouped) {
var self = this;
- this.dataset.offset = 0;
- this.dataset.limit = false;
var callback = function (field_view_get) {
- self.on_loaded(field_view_get, grouped);
+ self.on_loaded(field_view_get, grouped);
};
if (this.embedded_view) {
return $.Deferred().then(callback).resolve({fields_view: this.embedded_view});
@@ -346,7 +429,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
* @param {Array} records selected record values
*/
do_select: function (ids, records) {
- this.$element.find('#oe-list-delete')
+ this.$element.find('.oe-list-delete')
.attr('disabled', !ids.length);
if (!records.length) {
@@ -505,6 +588,7 @@ openerp.base.ListView.List = Class.extend( /** @lends openerp.base.ListView.List
init: function (group, opts) {
var self = this;
this.group = group;
+ this.view = group.view;
this.options = opts.options;
this.columns = opts.columns;
@@ -555,18 +639,6 @@ openerp.base.ListView.List = Class.extend( /** @lends openerp.base.ListView.List
this.$current = this.$_element.clone(true);
this.$current.empty().append(QWeb.render('ListView.rows', this));
},
- get_fields_view: function () {
- // deep copy of view
- var view = $.extend(true, {}, this.group.view.fields_view);
- _(view.arch.children).each(function (widget) {
- widget.attrs.nolabel = true;
- if (widget.tag === 'button') {
- delete widget.attrs.string;
- }
- });
- view.arch.attrs.col = 2 * view.arch.children.length;
- return view;
- },
/**
* Gets the ids of all currently selected records, if any
* @returns {Object} object with the keys ``ids`` and ``records``, holding respectively the ids of all selected records and the records themselves.
@@ -715,13 +787,10 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
this.columns = view.columns;
this.datagroup = null;
- this.sections = [];
+ this.$row = null;
this.children = {};
- },
- pad: function ($row) {
- if (this.options.selectable) {
- $row.append('<td>');
- }
+
+ this.page = 0;
},
make_fragment: function () {
return document.createDocumentFragment();
@@ -753,10 +822,35 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
}
return red_letter_tboday;
},
+ make_paginator: function () {
+ var self = this;
+ var $prev = $('<button type="button" data-pager-action="previous">&lt;</button>')
+ .click(function (e) {
+ e.stopPropagation();
+ self.page -= 1;
+
+ self.$row.closest('tbody').next()
+ .replaceWith(self.render());
+ });
+ var $next = $('<button type="button" data-pager-action="next">&gt;</button>')
+ .click(function (e) {
+ e.stopPropagation();
+ self.page += 1;
+
+ self.$row.closest('tbody').next()
+ .replaceWith(self.render());
+ });
+ this.$row.children().last()
+ .append($prev)
+ .append('<span class="oe-pager-state"></span>')
+ .append($next);
+ },
open: function (point_insertion) {
this.render().insertAfter(point_insertion);
+ this.make_paginator();
},
close: function () {
+ this.$row.children().last().empty();
this.apoptosis();
},
/**
@@ -788,7 +882,7 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
self.bind_child_events(child);
child.datagroup = group;
- var $row = $('<tr>');
+ var $row = child.$row = $('<tr>');
if (group.openable) {
$row.click(function (e) {
if (!$row.data('open')) {
@@ -808,7 +902,7 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
}
placeholder.appendChild($row[0]);
- var $group_column = $('<th>').appendTo($row);
+ var $group_column = $('<th class="oe-group-name">').appendTo($row);
if (group.grouped_on) {
// Don't fill this if group_by_no_leaf but no group_by
$group_column
@@ -822,8 +916,10 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
self.indent($group_column, group.level);
// count column
$('<td>').text(group.length).appendTo($row);
-
- self.pad($row);
+
+ if (self.options.selectable) {
+ $row.append('<td>');
+ }
_(self.columns).chain()
.filter(function (column) {return !column.invisible;})
.each(function (column) {
@@ -844,6 +940,9 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
$row.append('<td>');
}
});
+ if (self.options.deletable) {
+ $row.append('<td class="oe-group-pagination">');
+ }
});
return placeholder;
},
@@ -867,6 +966,7 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
},
render_dataset: function (dataset) {
var rows = [],
+ self = this,
list = new openerp.base.ListView.List(this, {
options: this.options,
columns: this.columns,
@@ -875,11 +975,30 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
});
this.bind_child_events(list);
- var d = new $.Deferred();
+ var view = this.view,
+ limit = view.limit(),
+ d = new $.Deferred(),
+ page = this.datagroup.openable ? this.page : view.page;
+
dataset.read_slice(
_.filter(_.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name'), _.identity),
- 0, false,
+ page * limit, limit,
function (records) {
+ if (!self.datagroup.openable) {
+ view.configure_pager(dataset);
+ } else {
+ var pages = Math.ceil(dataset.ids.length / limit);
+ self.$row
+ .find('.oe-pager-state')
+ .text(_.sprintf('%d/%d', page + 1, pages))
+ .end()
+ .find('button[data-pager-action=previous]')
+ .attr('disabled', page === 0)
+ .end()
+ .find('button[data-pager-action=next]')
+ .attr('disabled', page === pages - 1);
+ }
+
var form_records = _(records).map(
$.proxy(list, 'transform_record'));
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index 914233552b2..d37e1ddd958 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -243,11 +243,11 @@
<th t-if="actions_span" t-att-colspan="actions_span"
class="oe-actions">
<t t-if="flags.action_buttons !== false">
- <button type="button" id="oe-list-add"
+ <button type="button" class="oe-list-add"
t-if="options.addable">
<t t-esc="options.addable"/>
</button>
- <button type="button" id="oe-list-delete"
+ <button type="button" class="oe-list-delete"
t-if="options.selectable and options.deletable">
Delete
</button>
@@ -256,16 +256,19 @@
<th t-att-colspan="columns_count - actions_span"
class="oe-list-pager">
<t t-if="flags.pager !== false">
- <button type="button" data-pager-action="first">First</button>
- <button type="button" data-pager-action="previous"
+ <button type="button" disabled="disabled"
+ data-pager-action="first">First</button>
+ <button type="button" disabled="disabled"
+ data-pager-action="previous"
>&lt;&lt;</button>
- <span class="oe-pager-first">1</span>
- to <span class="oe-pager-last">1</span>
- of <span class="oe-pager-total">1</span>
+ <span class="oe-pager-state">
+ </span>
- <button type="button" data-pager-action="next">&gt;&gt;</button>
- <button type="button" data-pager-action="last">Last</button>
+ <button type="button" disabled="disabled"
+ data-pager-action="next">&gt;&gt;</button>
+ <button type="button" disabled="disabled"
+ data-pager-action="last">Last</button>
</t>
</th>
</tr>