diff --git a/beat/web/search/static/search/js/controls.js b/beat/web/search/static/search/js/controls.js index 9b11a55835cdad6003e30fdfe16b0410523007ec..69133772fb9f7162677481000137a13309bf0f64 100644 --- a/beat/web/search/static/search/js/controls.js +++ b/beat/web/search/static/search/js/controls.js @@ -1,21 +1,21 @@ /* * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ * Contact: beat.support@idiap.ch - * + * * This file is part of the beat.web module of the BEAT platform. - * + * * Commercial License Usage * Licensees holding valid commercial BEAT licenses may use this file in * accordance with the terms contained in a written agreement between you * and Idiap. For further information contact tto@idiap.ch - * + * * Alternatively, this file may be used under the terms of the GNU Affero * Public License version 3 as published by the Free Software and appearing * in the file LICENSE.AGPL included in the packaging of this file. * The BEAT platform is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. - * + * * You should have received a copy of the GNU Affero Public License along * with the BEAT platform. If not, see http://www.gnu.org/licenses/. */ @@ -223,8 +223,10 @@ beat.search.controls.DisplaySettings.prototype.scrape = function() { * * container (Object): A jQuery object at which we'll attach ourselves * options (Array): A preset array of options from the user (maybe empty) + * fun (Function): A function to hook the ENTER button press on added text + * inputs (normally meaning "submit" the form) */ -beat.search.controls.SimpleFilter = function(container, options) { +beat.search.controls.SimpleFilter = function(container, options, fun) { this.container = container; @@ -250,6 +252,10 @@ beat.search.controls.SimpleFilter = function(container, options) { this.text_input = $(document.createElement('input')); this.text_input.attr('type', 'text'); this.text_input.addClass('form-control'); + this.text_input.keydown(function (event) { + var keypressed = event.keyCode || event.which; + if (keypressed == 13) fun(); + }); this.dom_element.append($(document.createElement('label')).addClass('sr-only').text('Value')); this.dom_element.append(this.text_input); @@ -345,8 +351,10 @@ beat.search.controls.SimpleFilter.prototype.scrape = function() { * * container (Object): A jQuery object at which we'll attach ourselves * options (Array): A preset array of options from the user (maybe empty) + * fun (Function): A function to hook the ENTER button press on added text + * inputs (normally meaning "submit" the form) */ -beat.search.controls.ExperimentFilter = function(container, options) { +beat.search.controls.ExperimentFilter = function(container, options, fun) { this.container = container; @@ -374,6 +382,10 @@ beat.search.controls.ExperimentFilter = function(container, options) { this.text_input = $(document.createElement('input')); this.text_input.attr('type', 'text'); this.text_input.addClass('form-control'); + this.text_input.keydown(function (event) { + var keypressed = event.keyCode || event.which; + if (keypressed == 13) fun(); + }); this.dom_element.append($(document.createElement('label')).addClass('sr-only').text('Value')); this.dom_element.append(this.text_input); @@ -500,8 +512,10 @@ beat.search.controls.ExperimentFilter.prototype.scrape = function() { * * container (Object): A jQuery object at which we'll attach ourselves * options (Array): A preset array of options from the user (maybe empty) + * fun (Function): A function to hook the ENTER button press on added text + * inputs (normally meaning "submit" the form) */ -beat.search.controls.ExperimentDateFilter = function(container, options) { +beat.search.controls.ExperimentDateFilter = function(container, options, fun) { this.container = container; @@ -526,6 +540,10 @@ beat.search.controls.ExperimentDateFilter = function(container, options) { this.text_input = $(document.createElement('input')); this.text_input.attr('type', 'text'); this.text_input.addClass('form-control'); + this.text_input.keydown(function (event) { + var keypressed = event.keyCode || event.which; + if (keypressed == 13) fun(); + }); input_group.append($(document.createElement('label')).addClass('sr-only').text('Date')); input_group.append(this.text_input); var icon = $(document.createElement('div')).addClass('input-group-addon'); @@ -636,8 +654,10 @@ beat.search.controls.ExperimentDateFilter.prototype.scrape = function() { * * container (Object): A jQuery object at which we'll attach ourselves * options (Array): A preset array of options from the user (maybe empty) + * fun (Function): A function to hook the ENTER button press on added text + * inputs (normally meaning "submit" the form) */ -beat.search.controls.ResultFilter = function(container, options) { +beat.search.controls.ResultFilter = function(container, options, fun) { this.container = container; @@ -668,6 +688,10 @@ beat.search.controls.ResultFilter = function(container, options) { this.text_input.addClass('form-control result-filter'); this.text_input.attr('placeholder', 'Choose a value...'); this.dom_element.append(this.text_input); + this.text_input.keydown(function (event) { + var keypressed = event.keyCode || event.which; + if (keypressed == 13) fun(); + }); if (options === undefined) return; @@ -746,8 +770,10 @@ beat.search.controls.ResultFilter.prototype.scrape = function() { * * container (Object): A jQuery object at which we'll attach ourselves * options (Array): A preset array of options from the user (maybe empty) + * fun (Function): A function to hook the ENTER button press on added text + * inputs (normally meaning "submit" the form) */ -beat.search.controls.Filters = function(container, options) { +beat.search.controls.Filters = function(container, options, fun) { var forms = []; //all form rows var master_selectors = []; //controls for the type of filter @@ -824,25 +850,25 @@ beat.search.controls.Filters = function(container, options) { if (opt !== undefined) { if (simple_types.indexOf(opt.context) >= 0) { master_select.val(opt.context); - controller = new beat.search.controls.SimpleFilter(form, opt); + controller = new beat.search.controls.SimpleFilter(form, opt, fun); } else if (opt.context == 'experiment') { master_select.val(opt.context); - controller = new beat.search.controls.ExperimentFilter(form, opt); + controller = new beat.search.controls.ExperimentFilter(form, opt, fun); } else if (opt.context == 'experiment-date') { master_select.val(opt.context); - controller = new beat.search.controls.ExperimentDateFilter(form, opt); + controller = new beat.search.controls.ExperimentDateFilter(form, opt, fun); } else if (opt.context == 'experiment-result') { master_select.val(opt.context); - controller = new beat.search.controls.ResultFilter(form, opt); + controller = new beat.search.controls.ResultFilter(form, opt, fun); } } else { //the default master_select.val('any-field'); - controller = new beat.search.controls.SimpleFilter(form); + controller = new beat.search.controls.SimpleFilter(form, [], fun); } //rig master select boxes - on change, fix controller @@ -851,16 +877,16 @@ beat.search.controls.Filters = function(container, options) { var ind = $(this).parent().parent().index(); //form-inline index controllers[ind].remove(); //remove DOM elements if (simple_types.indexOf(val) >= 0) { - controllers[ind] = new beat.search.controls.SimpleFilter(form, opt); + controllers[ind] = new beat.search.controls.SimpleFilter(form, opt, fun); } else if (val == 'experiment') { - controllers[ind] = new beat.search.controls.ExperimentFilter(form, opt); + controllers[ind] = new beat.search.controls.ExperimentFilter(form, opt, fun); } else if (val == 'experiment-date') { - controllers[ind] = new beat.search.controls.ExperimentDateFilter(form, opt); + controllers[ind] = new beat.search.controls.ExperimentDateFilter(form, opt, fun); } else if (val == 'experiment-result') { - controllers[ind] = new beat.search.controls.ResultFilter(form, opt); + controllers[ind] = new beat.search.controls.ResultFilter(form, opt, fun); } }); diff --git a/beat/web/search/templates/search/panels/viewer.html b/beat/web/search/templates/search/panels/viewer.html index c73fcbf58eef76ede78077070bf09216905f4f8c..0115fb9de119524f28fa43711a09338a56c3e1c7 100644 --- a/beat/web/search/templates/search/panels/viewer.html +++ b/beat/web/search/templates/search/panels/viewer.html @@ -1,21 +1,21 @@ {% comment %} * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ * Contact: beat.support@idiap.ch - * + * * This file is part of the beat.web module of the BEAT platform. - * + * * Commercial License Usage * Licensees holding valid commercial BEAT licenses may use this file in * accordance with the terms contained in a written agreement between you * and Idiap. For further information contact tto@idiap.ch - * + * * Alternatively, this file may be used under the terms of the GNU Affero * Public License version 3 as published by the Free Software and appearing * in the file LICENSE.AGPL included in the packaging of this file. * The BEAT platform is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. - * + * * You should have received a copy of the GNU Affero Public License along * with the BEAT platform. If not, see http://www.gnu.org/licenses/. {% endcomment %} @@ -43,10 +43,10 @@ to the text boxes separated by a single comma. E.g.: "eigenface,fisherface" (meaning search for eigenface OR fisherface). Click on the <i class="fa fa-times"></i> buttons to - remove a given search criteria. Click on the "Update" button to - update the result display. If you're logged in, you may also hit on - "Save" to save your search filters and re-run this search again on - the future. + remove a given search criteria. Click on the "Update" button (or + hit Enter on your keyboard) to update the result display. If you're + logged in, you may also hit on "Save" to save your search filters + and re-run this search again on the future. </p> <div id="filters"> {# Filters (controller) will load contents #} @@ -126,16 +126,8 @@ $(document).ready(function(){ } }); - var filters_controller = new beat.search.controls.Filters($('#filters'), - {% if filters %}{{ filters|safe }}{% else %}[]{% endif %}); - - var settings_controller = new beat.search.controls.DisplaySettings( - 'select#display-selector', '#results-table table', - {% if settings %}{{ settings|safe }}{% else %}[]{% endif %}); - - //rigs the "Update" button - $('#update').on('click', function() { - $(this).children('i').addClass('fa-spin'); + function update_search() { + $('#update').children('i').addClass('fa-spin'); $('#update').addClass('disabled'); //collects the settings and makes a new POST request to the same URL, but //overriding filters and display settings @@ -151,7 +143,17 @@ $(document).ready(function(){ document.close(); }); d.fail(process_error); - }); + } + + var filters_controller = new beat.search.controls.Filters($('#filters'), + {% if filters %}{{ filters|safe }}{% else %}[]{% endif %}, update_search); + + var settings_controller = new beat.search.controls.DisplaySettings( + 'select#display-selector', '#results-table table', + {% if settings %}{{ settings|safe }}{% else %}[]{% endif %}); + + //rigs the "Update" button + $('#update').on('click', update_search); $('#update').removeClass('disabled'); {% if not request.user.is_anonymous %} diff --git a/beat/web/search/views.py b/beat/web/search/views.py index 5ee8945d86735985c264e05b25cbc7b3b0dd872a..5099c5f2330dd4dd4bf076a8203562976490ef1d 100644 --- a/beat/web/search/views.py +++ b/beat/web/search/views.py @@ -226,12 +226,15 @@ def filters_from_query(query): 'name': None, } - for keyword in map(lambda x: x.strip(), query.split(' ')): + keywords = [x.strip() for x in query.split() if x.strip()] + + for keyword in keywords: offset = keyword.find(':') if offset != -1: command = keyword[:offset] - entries = keyword[offset+1:].split(',') + entries = [x.strip() for x in keyword[offset+1:].split(',')] + entries = [x for x in entries if x] if command in ['db', 'database']: filters.append(_make_context('database-name', entries)) elif command in ['tc', 'toolchain']: