[IMP] make openerp.base.ListView.Groups a tree, so it's possible to get a handle on intermediate groups

bzr revid: xmo@openerp.com-20110519092222-g0ggk9didmizc5ch
This commit is contained in:
Xavier Morel 2011-05-19 11:22:22 +02:00
parent 421b139e3f
commit bbdd1c0389
1 changed files with 68 additions and 39 deletions

View File

@ -441,6 +441,13 @@ openerp.base.ListView.List = Class.extend( /** @lends openerp.base.ListView.List
*/ */
row_id: function (row) { row_id: function (row) {
return this.rows[this.row_position(row)].data.id.value; return this.rows[this.row_position(row)].data.id.value;
},
/**
* Death signal, cleans up list
*/
apoptosis: function () {
this.$current.remove();
this.$current = null;
} }
// drag and drop // drag and drop
// editable? // editable?
@ -459,7 +466,8 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
this.columns = opts.columns; this.columns = opts.columns;
this.datagroup = {}; this.datagroup = {};
this.lists = {}; this.sections = [];
this.children = {};
}, },
pad: function ($row) { pad: function ($row) {
if (this.options.selectable) { if (this.options.selectable) {
@ -467,38 +475,49 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
} }
}, },
make_fragment: function () { make_fragment: function () {
return this.$element[0].ownerDocument.createDocumentFragment(); return document.createDocumentFragment();
},
/**
* Returns a DOM node after which a new tbody can be inserted, so that it
* follows the provided row.
*
* Necessary to insert the result of a new group or list view within an
* existing groups render, without losing track of the groups's own
* elements
*
* @param {HTMLTableRowElement} row the row after which the caller wants to insert a body
* @returns {HTMLTableSectionElement} element after which a tbody can be inserted
*/
point_insertion: function (row) {
var $row = $(row);
var red_letter_tbody = $row.closest('tbody')[0];
var $next_siblings = $row.nextAll();
if ($next_siblings.length) {
var $root_kanal = $('<tbody>').insertAfter(red_letter_tbody);
$root_kanal.append($next_siblings);
this.elements.splice(
_.indexOf(this.elements, red_letter_tbody),
0,
$root_kanal[0]);
}
return red_letter_tbody;
}, },
open_group: function (e, group) { open_group: function (e, group) {
var self = this, var row = e.currentTarget;
$row = $(e.currentTarget);
group.list(function (groups) {
$row.parent()[0].insertBefore(
self.render_groups(groups),
$row[0].nextSibling);
}, function (dataset) {
// Now we need to split the current tbody in order to
// insert the list's
// Create new tbody after current one if (this.children[group.value]) {
var $current_body = $row.closest('tbody'); this.children[group.value].apoptosis();
delete this.children[group.value];
var $next_siblings = $row.nextAll(); }
if ($next_siblings.length) { var prospekt = this.children[group.value] = new openerp.base.ListView.Groups(this.view, {
var $split = $('<tbody>').insertAfter($current_body); options: this.options,
// Move all following siblings of current row to split columns: this.columns
$split.append($row.nextAll());
}
// Insert list rendering after current tbody
self.render_dataset(dataset).then(function (list) {
if (self.lists[group.value]) {
self.lists[group.value].$current.remove();
delete self.lists[group.value];
}
self.lists[group.value] = list;
$current_body.after(list.$current);
});
}); });
prospekt.datagroup = group;
prospekt.render().insertAfter(
this.point_insertion(row));
}, },
render_groups: function (datagroups) { render_groups: function (datagroups) {
var self = this; var self = this;
@ -525,10 +544,10 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
}); });
return placeholder; return placeholder;
}, },
bind_list_events: function (list) { bind_child_events: function (child) {
var $this = $(this), var $this = $(this),
self = this; self = this;
$(list).bind('selected', function (e) { $(child).bind('selected', function (e) {
// can have selections spanning multiple links // can have selections spanning multiple links
$this.trigger(e, [self.get_selection()]); $this.trigger(e, [self.get_selection()]);
}).bind('deleted action row_link', function (e) { }).bind('deleted action row_link', function (e) {
@ -549,7 +568,7 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
columns: this.columns, columns: this.columns,
rows: rows rows: rows
}); });
this.bind_list_events(list); this.bind_child_events(list);
var d = new $.Deferred(); var d = new $.Deferred();
this.view.rpc('/base/listview/fill', { this.view.rpc('/base/listview/fill', {
@ -568,27 +587,37 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
}, },
render: function () { render: function () {
var self = this; var self = this;
this.$element = $('<tbody>'); var $element = $('<tbody>');
this.elements = [$element[0]];
this.datagroup.list(function (groups) { this.datagroup.list(function (groups) {
self.$element.empty()[0].appendChild( $element[0].appendChild(
self.render_groups(groups)); self.render_groups(groups));
}, function (dataset) { }, function (dataset) {
self.render_dataset(dataset).then(function (list) { self.render_dataset(dataset).then(function (list) {
self.$element.empty().after(list.$current); self.elements =
[list.$current.replaceAll($element)[0]];
}); });
}); });
return this.$element; return $element;
}, },
/** /**
* Returns the ids of all selected records for this group * Returns the ids of all selected records for this group
*/ */
get_selection: function () { get_selection: function () {
return _(this.lists).chain() return _(this.children).chain()
.map(function (list) { .map(function (child) {
return list.get_selection(); return child.get_selection();
}) })
.flatten() .flatten()
.value(); .value();
},
apoptosis: function () {
_(this.children).each(function (child) {
child.apoptosis();
});
$(this.elements).each(function (i, body) {
$(body).remove();
});
} }
}); });
}; };