summaryrefslogtreecommitdiff
path: root/addons/web/static
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static')
-rw-r--r--addons/web/static/src/js/views/abstract_controller.js3
-rw-r--r--addons/web/static/src/js/views/search_panel.js13
-rw-r--r--addons/web/static/tests/views/search_panel_tests.js34
3 files changed, 49 insertions, 1 deletions
diff --git a/addons/web/static/src/js/views/abstract_controller.js b/addons/web/static/src/js/views/abstract_controller.js
index 58a011599d1..53bcc0d5bad 100644
--- a/addons/web/static/src/js/views/abstract_controller.js
+++ b/addons/web/static/src/js/views/abstract_controller.js
@@ -113,6 +113,9 @@ var AbstractController = mvc.Controller.extend(ActionMixin, {
if (this._controlPanel) {
this._controlPanel.on_attach_callback();
}
+ if (this._searchPanel) {
+ this._searchPanel.on_attach_callback();
+ }
this.renderer.on_attach_callback();
},
/**
diff --git a/addons/web/static/src/js/views/search_panel.js b/addons/web/static/src/js/views/search_panel.js
index 38872e8d381..f09ef071f79 100644
--- a/addons/web/static/src/js/views/search_panel.js
+++ b/addons/web/static/src/js/views/search_panel.js
@@ -95,6 +95,7 @@ var SearchPanel = Widget.extend({
});
this.initialState = params.state;
+ this.scrollTop = this.initialState && this.initialState.scrollTop || null;
this.defaultValues = params.defaultValues || {};
this.fields = params.fields;
this.model = params.model;
@@ -123,6 +124,14 @@ var SearchPanel = Widget.extend({
this._render();
return this._super.apply(this, arguments);
},
+ /**
+ * Called each time the searchPanel is attached into the DOM.
+ */
+ on_attach_callback: function () {
+ if (this.scrollTop !== null) {
+ this.el.scrollTop = this.scrollTop;
+ }
+ },
//--------------------------------------------------------------------------
// Public
@@ -175,6 +184,7 @@ var SearchPanel = Widget.extend({
return {
categories: this.categories,
filters: this.filters,
+ scrollTop: this.el ? this.el.scrollTop : null,
};
},
/**
@@ -192,8 +202,9 @@ var SearchPanel = Widget.extend({
* @param {Object} state.categories
*/
importState: function (state) {
- this.filters = state.filters || this.filters;
this.categories = state.categories || this.categories;
+ this.filters = state.filters || this.filters;
+ this.scrollTop = state.scrollTop;
this._render();
},
/**
diff --git a/addons/web/static/tests/views/search_panel_tests.js b/addons/web/static/tests/views/search_panel_tests.js
index a285c1df81b..0c4ec6fb7bb 100644
--- a/addons/web/static/tests/views/search_panel_tests.js
+++ b/addons/web/static/tests/views/search_panel_tests.js
@@ -2042,6 +2042,40 @@ QUnit.module('Views', {
actionManager.destroy();
});
+ QUnit.test('scroll position is kept when switching between controllers', async function (assert) {
+ assert.expect(6);
+
+ for (var i = 10; i < 20; i++) {
+ this.data.category.records.push({id: i, name: "Cat " + i});
+ }
+
+ var actionManager = await createActionManager({
+ actions: this.actions,
+ archs: this.archs,
+ data: this.data,
+ services: this.services,
+ });
+ actionManager.$el.css('max-height', 300);
+
+ await actionManager.doAction(1);
+ assert.containsOnce(actionManager, '.o_content .o_kanban_view');
+ assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 0);
+
+ // simulate a scroll in the search panel and switch into list
+ actionManager.$('.o_search_panel').scrollTop(50);
+ await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
+ assert.containsOnce(actionManager, '.o_content .o_list_view');
+ assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 50);
+
+ // simulate another scroll and switch back to kanban
+ actionManager.$('.o_search_panel').scrollTop(30);
+ await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
+ assert.containsOnce(actionManager, '.o_content .o_kanban_view');
+ assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 30);
+
+ actionManager.destroy();
+ });
+
QUnit.test('search panel is not instanciated in dialogs', async function (assert) {
assert.expect(2);