[FIX] web: keep searchview floating content on update
In a search view, write text in the input, then hit enter to select the facet. Before this commit, the search view was detached and then reattached when the control panel was refreshed. This led to loosing the focus momentarily and erasing any supplementary input one might have typed *during* the rpc call. After this commit, if the search view is the same as before, we don't detach it in the first place. Thus, the input is conserved in this situation. OPW 1861941 OPW 185614t closes #25546
This commit is contained in:
@@ -148,15 +148,25 @@ var ControlPanel = Widget.extend({
|
||||
}
|
||||
|
||||
// Detach control_panel old content and attach new elements
|
||||
var toDetach = this.nodes;
|
||||
if (status.searchview && this.searchview === status.searchview) {
|
||||
// If the searchview is the same as before, don't detach it s.t.
|
||||
// we don't loose any floating content, nor the focus
|
||||
toDetach = _.omit(toDetach, '$searchview');
|
||||
new_cp_content = _.omit(new_cp_content, '$searchview');
|
||||
}
|
||||
if (options.clear) {
|
||||
this._detach_content(this.nodes);
|
||||
this._detach_content(toDetach);
|
||||
// Show the searchview buttons area, which might have been hidden by
|
||||
// the searchview, as client actions may insert elements into it
|
||||
this.nodes.$searchview_buttons.show();
|
||||
} else {
|
||||
this._detach_content(_.pick(this.nodes, _.keys(new_cp_content)));
|
||||
this._detach_content(_.pick(toDetach, _.keys(new_cp_content)));
|
||||
}
|
||||
this._attach_content(new_cp_content);
|
||||
if (options.clear || status.searchview) {
|
||||
this.searchview = status.searchview;
|
||||
}
|
||||
|
||||
// Update the searchview and switch buttons
|
||||
if (status.searchview || options.clear) {
|
||||
|
||||
@@ -3119,6 +3119,62 @@ QUnit.module('ActionManager', {
|
||||
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('Search View Action');
|
||||
|
||||
QUnit.test('search view should keep focus during do_search', function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
/* One should be able to type something in the search view, press on enter to
|
||||
* make the facet and trigger the search, then do this process
|
||||
* over and over again seamlessly.
|
||||
* Verifying the input's value is a lot trickier than verifying the search_read
|
||||
* because of how native events are handled in tests
|
||||
*/
|
||||
|
||||
var searchDeferred = $.Deferred();
|
||||
|
||||
var actionManager = createActionManager({
|
||||
actions: this.actions,
|
||||
archs: this.archs,
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/search_read') {
|
||||
assert.step('search_read ' + args.domain);
|
||||
if ( _.isEqual(args.domain, [['foo', 'ilike', 'm']])) {
|
||||
return searchDeferred.then(this._super.bind(this, route, args));
|
||||
}
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
actionManager.doAction(3);
|
||||
|
||||
var $searchInput = $('.o_searchview input');
|
||||
$searchInput.trigger($.Event('keypress', {key: 'm', which: 109, keyCode: 109}));
|
||||
$searchInput.trigger($.Event('keydown', {key: 'Enter', which: 13, keyCode: 13}));
|
||||
|
||||
assert.verifySteps(["search_read ",
|
||||
"search_read foo,ilike,m"]);
|
||||
|
||||
// Triggering the do_search above will kill the current searchview Input
|
||||
$searchInput = $('.o_searchview input');
|
||||
$searchInput.trigger($.Event('keypress', {key: 'o', which: 111, keyCode: 111}));
|
||||
|
||||
// We have something in the input of the search view. Making the search_read
|
||||
// return at this point will trigger the redraw of the view.
|
||||
// However we want to hold on to what we just typed
|
||||
searchDeferred.resolve();
|
||||
|
||||
$searchInput.trigger($.Event('keydown', {key: 'Enter', which: 13, keyCode: 13}));
|
||||
|
||||
assert.verifySteps(["search_read ",
|
||||
"search_read foo,ilike,m",
|
||||
"search_read |,foo,ilike,m,foo,ilike,o"]);
|
||||
|
||||
actionManager.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user