diff --git a/addons/web/static/src/js/views/list/list_renderer.js b/addons/web/static/src/js/views/list/list_renderer.js
index 4e5e270eb12..4d651198044 100644
--- a/addons/web/static/src/js/views/list/list_renderer.js
+++ b/addons/web/static/src/js/views/list/list_renderer.js
@@ -6,6 +6,7 @@ var config = require('web.config');
var core = require('web.core');
var Domain = require('web.Domain');
var field_utils = require('web.field_utils');
+var Pager = require('web.Pager');
var session = require('web.session');
var utils = require('web.utils');
@@ -72,6 +73,7 @@ var ListRenderer = BasicRenderer.extend({
}).value();
this.hasSelectors = params.hasSelectors;
this.selection = [];
+ this.pagers = []; // instantiated pagers (only for grouped lists)
},
//--------------------------------------------------------------------------
@@ -350,6 +352,36 @@ var ListRenderer = BasicRenderer.extend({
}
return $('
').append($('').append($cells));
},
+ /**
+ * Renders the pager for a given group
+ *
+ * @private
+ * @param {Object} group
+ * @returns {JQueryElement} the pager's $el
+ */
+ _renderGroupPager: function (group) {
+ var pager = new Pager(this, group.count, group.offset + 1, group.limit);
+ pager.on('pager_changed', this, function (newState) {
+ var self = this;
+ pager.disable();
+ this.trigger_up('load', {
+ id: group.id,
+ limit: newState.limit,
+ offset: newState.current_min - 1,
+ on_success: function (reloadedGroup) {
+ _.extend(group, reloadedGroup);
+ self._renderView();
+ },
+ on_fail: pager.enable.bind(pager),
+ });
+ });
+ // register the pager so that it can be destroyed on next rendering
+ this.pagers.push(pager);
+
+ var fragment = document.createDocumentFragment();
+ pager.appendTo(fragment); // starts the pager
+ return pager.$el;
+ },
/**
* Render the row that represent a group
*
@@ -380,6 +412,11 @@ var ListRenderer = BasicRenderer.extend({
.toggleClass('fa-caret-down', group.isOpen);
$th.prepend($arrow);
}
+ if (group.isOpen && !group.groupedBy.length && (group.count > group.data.length)) {
+ var $pager = this._renderGroupPager(group);
+ var $lastCell = $cells[$cells.length-1];
+ $lastCell.addClass('o_group_pager').append($pager);
+ }
return $('
')
.addClass('o_group_header')
.data('group', group)
@@ -553,6 +590,11 @@ var ListRenderer = BasicRenderer.extend({
*/
_renderView: function () {
var self = this;
+
+ // destroy the previously instantiated pagers, if any
+ _.invoke(this.pagers, 'destroy');
+ this.pagers = [];
+
var $table = $('').addClass('o_list_view table table-condensed table-striped');
this.$el.empty().append($table);
var is_grouped = !!this.state.groupedBy.length;
diff --git a/addons/web/static/src/less/list_view.less b/addons/web/static/src/less/list_view.less
index b80b525bc4b..bad4e370961 100644
--- a/addons/web/static/src/less/list_view.less
+++ b/addons/web/static/src/less/list_view.less
@@ -78,6 +78,8 @@
// Grouped list views
tbody > tr.o_group_header {
+ height: 31px;
+
.o-vertical-gradient(#fcfcfc, #dedede);
.o_group_name {
@@ -87,6 +89,8 @@
cursor: text;
.user-select(none);
text-align: right;
+ padding-top: 0;
+ padding-bottom: 0;
.o_pager_previous, .o_pager_next {
background-color: @odoo-list-group-header-color;
&:hover {
diff --git a/addons/web/static/test/views/list_tests.js b/addons/web/static/test/views/list_tests.js
index 87f361a3456..700d65d6358 100644
--- a/addons/web/static/test/views/list_tests.js
+++ b/addons/web/static/test/views/list_tests.js
@@ -1204,6 +1204,44 @@ QUnit.module('Views', {
list.destroy();
});
+
+ QUnit.test('grouped list with a pager in a group', function (assert) {
+ assert.expect(6);
+ this.data.foo.records[3].bar = true;
+
+ var list = createView({
+ View: ListView,
+ model: 'foo',
+ data: this.data,
+ arch: '',
+ groupBy: ['bar'],
+ viewOptions: {
+ limit: 3,
+ },
+ });
+
+ var headerHeight = list.$('.o_group_header').css('height');
+
+ // basic rendering checks
+ list.$('.o_group_header').click();
+ assert.strictEqual(list.$('.o_group_header').css('height'), headerHeight,
+ "height of group header shouldn't have changed");
+ assert.ok(list.$('.o_group_header td:last').hasClass('o_group_pager'),
+ "last cell of open group header should have classname 'o_group_header'");
+ assert.strictEqual(list.$('.o_pager_value').text(), '1-3',
+ "pager's value should be correct");
+ assert.strictEqual(list.$('.o_data_row').length, 3,
+ "open group should display 3 records");
+
+ // go to next page
+ list.$('.o_pager_next').click();
+ assert.strictEqual(list.$('.o_pager_value').text(), '4-4',
+ "pager's value should be correct");
+ assert.strictEqual(list.$('.o_data_row').length, 1,
+ "open group should display 1 record");
+
+ list.destroy();
+ });
});
});