diff --git a/addons/web/doc/search_view.rst b/addons/web/doc/search_view.rst index 16a91c5e9ac..12b0eaf3104 100644 --- a/addons/web/doc/search_view.rst +++ b/addons/web/doc/search_view.rst @@ -107,6 +107,12 @@ formatted differently). If an input *may* fetch multiple completion items, it *should* prefix those with a section title using its own name. This has no technical consequence but is clearer for users. +.. note:: + + If a field is :js:func:`invisible + `, its completion function will + *not* be called. + Providing drawer/supplementary UI +++++++++++++++++++++++++++++++++ @@ -145,6 +151,11 @@ started only once (per view). dynamically collects, lays out and renders filters? => exercises drawer thingies +.. note:: + + An :js:func:`invisible ` input + will not be inserted into the drawer. + Converting from facet objects +++++++++++++++++++++++++++++ diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 8391f7a8ca5..8422f4e55fe 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -499,6 +499,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea */ complete_global_search: function (req, resp) { $.when.apply(null, _(this.inputs).chain() + .filter(function (input) { return input.visible(); }) .invoke('complete', req.term) .value()).then(function () { resp(_(_(arguments).compact()).flatten(true)); @@ -903,8 +904,8 @@ instance.web.search.Input = instance.web.search.Widget.extend( /** @lends instan */ init: function (view) { this._super(view); + this.load_attrs({}); this.view.inputs.push(this); - this.style = undefined; }, /** * Fetch auto-completion values for the widget. @@ -952,15 +953,19 @@ instance.web.search.Input = instance.web.search.Widget.extend( /** @lends instan "get_domain not implemented for widget " + this.attrs.type); }, load_attrs: function (attrs) { - if (attrs.modifiers) { - attrs.modifiers = JSON.parse(attrs.modifiers); - attrs.invisible = attrs.modifiers.invisible || false; - if (attrs.invisible) { - this.style = 'display: none;' - } - } + attrs.modifiers = attrs.modifiers ? JSON.parse(attrs.modifiers) : {}; this.attrs = attrs; - } + }, + /** + * Returns whether the input is "visible". The default behavior is to + * query the ``modifiers.invisible`` flag on the input's description or + * view node. + * + * @returns {Boolean} + */ + visible: function () { + return !this.attrs.modifiers.invisible; + }, }); instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends instance.web.search.FilterGroup# */{ template: 'SearchView.filters', diff --git a/addons/web/static/test/search.js b/addons/web/static/test/search.js index 09d135ca203..340784e657d 100644 --- a/addons/web/static/test/search.js +++ b/addons/web/static/test/search.js @@ -1158,3 +1158,52 @@ openerp.testing.section('search.advanced', { }); // TODO: UI tests? }); +openerp.testing.section('search.invisible', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true, +}, function (test) { + // Invisible fields should not auto-complete + test('invisible-no-autocomplete', {asserts: 1}, function (instance, $fix, mock) { + instance.web.search.fields.add('test', 'instance.test.TestWidget'); + instance.test = { + TestWidget: instance.web.search.Field.extend({ + complete: function () { + return $.when([{label: this.attrs.string}]); + }, + }), + }; + var fields = { + field0: {type: 'test', string: 'Field 0'}, + field1: {type: 'test', string: 'Field 1'}, + }; + mock('ir.filters:get_filters', function () { return []; }); + mock('test.model:fields_get', function () { return fields; }); + mock('test.model:fields_view_get', function () { + return { + type: 'search', + fields: fields, + arch: '' + + '' + + '' + + '' + }; + }); + var ds = new instance.web.DataSet(null, 'test.model'); + var view = new instance.web.SearchView(null, ds, false); + return view.appendTo($fix) + .then(function () { + var done = $.Deferred(); + view.complete_global_search({term: 'test'}, function (comps) { + done.resolve(comps); + }); + return done; + }).then(function (completions) { + deepEqual(completions, [{label: 'Field 0'}], + "should only complete the visible field"); + }); + }); + // Invisible filters should not appear in the drawer + // Invisible filter groups should not appear in the drawer + // Group invisibility should be inherited by children +});