diff options
| author | Xavier Morel <xmo@openerp.com> | 2011-07-06 10:32:14 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@openerp.com> | 2011-07-06 10:32:14 +0200 |
| commit | 1847dbc017ca226ce3e5276489474e686cc2ac8d (patch) | |
| tree | e9461726041a5465a1c5f12eddcc8968218b89c6 /addons/base/static/src | |
| parent | d44af4944d89ed326f5a0257ffe3528c4d1bc61f (diff) | |
| parent | fcc0a982f56baab310dfe45278e12da8b87daa7e (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.css | 14 | ||||
| -rw-r--r-- | addons/base/static/src/js/data.js | 13 | ||||
| -rw-r--r-- | addons/base/static/src/js/form.js | 19 | ||||
| -rw-r--r-- | addons/base/static/src/js/list-editable.js | 19 | ||||
| -rw-r--r-- | addons/base/static/src/js/list.js | 181 | ||||
| -rw-r--r-- | addons/base/static/src/xml/base.xml | 21 |
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"><</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">></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" ><<</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">>></button> - <button type="button" data-pager-action="last">Last</button> + <button type="button" disabled="disabled" + data-pager-action="next">>></button> + <button type="button" disabled="disabled" + data-pager-action="last">Last</button> </t> </th> </tr> |
