[ADD] sorting support in list views

* Fix sorting in DataSet.do_search_read (would not fix ordering of read results, yielding a semi-random order instead of the one returned by search)
* Add sort parameter support to ListView.fill()
* Improve handling of sort parameter on DataSetSearch
  - Queue up fields to sort on (most important last) by calling 'dataset.sort(fieldname)' repeatedly
  - Get back a sort string fit for sending to OpenERP (server) by calling 'dataset.sort()' (without arguments)
* Adds sorting on list view by clicking on headers

bzr revid: xmo@openerp.com-20110504140535-ydj8zs33lt0dgcwy
This commit is contained in:
Xavier Morel 2011-05-04 16:05:35 +02:00
parent e47ab260de
commit ff691a34b5
4 changed files with 52 additions and 9 deletions

View File

@ -346,12 +346,17 @@ class DataSet(openerpweb.Controller):
:rtype: list
"""
Model = request.session.model(model)
ids = Model.search(domain or [], offset or 0, limit or False,
sort or False, request.context)
if fields and fields == ['id']:
# shortcut read if we only want the ids
return map(lambda id: {'id': id}, ids)
return Model.read(ids, fields or False, request.context)
reads = Model.read(ids, fields or False, request.context)
reads.sort(key=lambda obj: ids.index(obj['id']))
return reads
@openerpweb.jsonrequest
def get(self, request, model, ids, fields=False):
@ -556,11 +561,11 @@ class ListView(View):
@openerpweb.jsonrequest
def fill(self, request, model, id, domain,
offset=0, limit=False):
return self.do_fill(request, model, id, domain, offset, limit)
offset=0, limit=False, sort=None):
return self.do_fill(request, model, id, domain, offset, limit, sort)
def do_fill(self, request, model, id, domain,
offset=0, limit=False):
offset=0, limit=False, sort=None):
""" Returns all information needed to fill a table:
* view with processed ``editable`` flag
@ -580,9 +585,10 @@ class ListView(View):
"""
view = self.fields_view_get(request, model, id, toolbar=True)
print sort
rows = DataSet().do_search_read(request, model,
offset=offset, limit=limit,
domain=domain)
domain=domain, sort=sort)
eval_context = request.session.evaluation_context(
request.context)
return {

View File

@ -144,7 +144,7 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
init: function(session, model) {
this._super(session, model);
this.domain = [];
this.sort = [];
this._sort = [];
this.offset = 0;
// subset records[offset:offset+limit]
// is it necessary ?
@ -166,7 +166,7 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
fields: fields,
domain: this.domain,
context: this.context,
sort: this.sort,
sort: this.sort(),
offset: offset,
limit: limit
}, function (records) {
@ -177,6 +177,35 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
}
callback(records);
});
},
/**
* Reads or changes sort criteria on the dataset.
*
* If not provided with any argument, serializes the sort criteria to
* an SQL-like form usable by OpenERP's ORM.
*
* If given a field, will set that field as first sorting criteria or,
* if the field is already the first sorting criteria, will reverse it.
*
* @param {String} [field] field to sort on, reverses it (toggle from ASC to DESC) if already the main sort criteria
* @param {Boolean} [force_reverse=false] forces inserting the field as DESC
* @returns {String|undefined}
*/
sort: function (field, force_reverse) {
if (!field) {
return _.map(this._sort, function (criteria) {
if (criteria[0] === '-') {
return criteria.slice(1) + ' DESC';
}
return criteria;
}).join(', ');
}
var reverse = force_reverse || (this._sort[0] === field);
this._sort = _.without(this._sort, field, '-' + field);
this._sort.unshift((reverse ? '-' : '') + field);
return undefined;
}
});

View File

@ -130,6 +130,13 @@ openerp.base.ListView = openerp.base.Controller.extend(
this.$element.find('#oe-list-delete')
.hide()
.click(this.do_delete_selected);
this.$element.find('thead').delegate('th[data-id]', 'click', function (e) {
e.stopPropagation();
self.dataset.sort($(this).data('id'));
self.do_reload();
});
var $table = this.$element.find('table');
// Cell events
@ -318,7 +325,8 @@ openerp.base.ListView = openerp.base.Controller.extend(
'model': this.dataset.model,
'id': this.view_id,
'context': this.dataset.context,
'domain': this.dataset.domain
'domain': this.dataset.domain,
'sort': this.dataset.sort && this.dataset.sort()
}, this.do_fill_table);
},
/**

View File

@ -181,7 +181,7 @@
<tr t-if="options.header">
<th t-if="options.selectable"/>
<t t-foreach="columns" t-as="column">
<th t-if="column.invisible !== '1'">
<th t-if="column.invisible !== '1'" t-att-data-id="column.id">
<t t-if="column.tag !== 'button'">
<t t-esc="column.string"/>
</t>