Theme: implement search_on_category_select as a preference

The implementation is change to work without javascript:
When enabled, the HTML page contains buttons instead of checkboxes.

* Related to https://github.com/searxng/searxng/issues/769#issuecomment-1132481995
* Fix https://github.com/searxng/searxng/issues/854
This commit is contained in:
Alexandre Flament 2022-07-02 21:09:26 +02:00
parent 69a6d994e1
commit 3de28b283a
9 changed files with 87 additions and 55 deletions

View file

@ -1,24 +0,0 @@
'''
searx is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
searx 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. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with searx. If not, see < http://www.gnu.org/licenses/ >.
(C) 2015 by Adam Tauber, <asciimoo@gmail.com>
'''
from flask_babel import gettext
name = gettext('Search on category select')
description = gettext(
'Perform search immediately if a category selected. Disable to select multiple categories. (JavaScript required)'
)
default_on = True
preference_section = 'ui'

View file

@ -408,6 +408,17 @@ class Preferences:
'False': False
}
),
'search_on_category_select': MapSetting(
settings['ui']['search_on_category_select'],
locked=is_locked('search_on_category_select'),
map={
'': settings['ui']['search_on_category_select'],
'0': False,
'1': True,
'True': True,
'False': False
}
),
# fmt: on
}

View file

@ -90,6 +90,9 @@ ui:
default_locale: ""
# Open result links in a new tab by default
# results_on_new_tab: false
# Search when the user clicks category name
# false to allow the user to select multiple categories
search_on_category_select: true
theme_args:
# style of simple theme: auto, light, dark
simple_style: auto

View file

@ -189,6 +189,7 @@ SCHEMA = {
'advanced_search': SettingsValue(bool, False),
'query_in_title': SettingsValue(bool, False),
'infinite_scroll': SettingsValue(bool, False),
'search_on_category_select': SettingsValue(bool, True),
},
'preferences': {
'lock': SettingsValue(list, []),

View file

@ -73,24 +73,9 @@
}
}
// vanilla js version of search_on_category_select.js
if (qinput !== null && d.querySelector('.help') != null && searxng.settings.search_on_category_select) {
d.querySelector('.help').className = 'invisible';
searxng.on('#categories input', 'change', function () {
var i, categories = d.querySelectorAll('#categories input[type="checkbox"]');
for (i = 0; i < categories.length; i++) {
if (categories[i] !== this && categories[i].checked) {
categories[i].click();
}
}
if (! this.checked) {
this.click();
}
submitIfQuery();
return false;
});
// when search_on_category_select is enabled, autosubmit the query when the user
// change the filters (safesearch, time_range, language)
if (qinput !== null && searxng.settings.search_on_category_select) {
searxng.on(d.getElementById('safesearch'), 'change', submitIfQuery);
searxng.on(d.getElementById('time_range'), 'change', submitIfQuery);
searxng.on(d.getElementById('language'), 'change', submitIfQuery);

View file

@ -23,12 +23,15 @@
"spacer categories";
}
.category {
.category_checkbox,
.category_button {
display: inline-block;
position: relative;
.ltr-margin-right(1rem);
padding: 0;
}
.category_checkbox {
input {
display: none;
}
@ -57,6 +60,33 @@
}
}
button.category_button {
background-color: inherit;
color: var(--color-base-font);
cursor: pointer;
padding: 0.2rem 0;
display: inline-flex;
align-items: center;
text-transform: capitalize;
font-size: 0.9em;
border: none;
border-bottom: 2px solid transparent;
svg {
padding-right: 0.2rem;
}
&:focus-within {
outline: 2px solid blue;
}
&.selected,
&:active {
color: var(--color-categories-item-selected-font);
border-bottom: 2px solid var(--color-categories-item-border-selected);
}
}
#search_logo {
grid-area: logo;
display: flex;
@ -205,11 +235,6 @@ html.no-js #clear_search.hide_if_nojs {
#categories {
font-size: 90%;
clear: both;
.checkbox_container {
margin: auto;
margin-top: 2px;
}
}
}
@ -219,7 +244,7 @@ html.no-js #clear_search.hide_if_nojs {
#categories_container {
width: max-content;
.category {
.category_checkbox {
display: inline-block;
width: auto;
}
@ -271,14 +296,21 @@ html.no-js #clear_search.hide_if_nojs {
width: auto;
margin: 0;
label {
padding: 1rem !important;
margin: 0 !important;
svg {
display: none;
}
}
.category_checkbox {
label {
padding: 1rem !important;
margin: 0 !important;
}
}
.category_button {
padding: 1rem !important;
margin: 0 !important;
}
#search_view:focus-within {

View file

@ -13,8 +13,10 @@
} -%}
<div id="categories" class="search_categories">{{- '' -}}
<div id="categories_container">
{%- if not search_on_category_select or not display_tooltip -%}
{%- for category in categories_as_tabs -%}
<div class="category"><input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}"{% if category in selected_categories %} checked="checked"{% endif %}/>
<div class="category category_checkbox">{{- '' -}}
<input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}"{% if category in selected_categories %} checked="checked"{% endif %}/>
<label for="checkbox_{{ category|replace(' ', '_') }}" class="tooltips">
{{- icon_big(category_icons[category]) if category in category_icons else icon_big('globe-outline') -}}
<div class="category_name">{{- _(category) -}}</div>
@ -22,5 +24,14 @@
</div>
{%- endfor -%}
{%- if display_tooltip %}<div class="help">{{ _('Click on the magnifier to perform search') }}</div>{% endif -%}
{%- else -%}
{%- for category in categories_as_tabs -%}{{- '\n' -}}
<button type="submit" name="category_{{ category|replace(' ', '_') }}" value="on" class="category category_button {% if category in selected_categories %}selected{% endif %}">
{{- icon_big(category_icons[category]) if category in category_icons else icon_big('globe-outline') -}}
<div class="category_name">{{- _(category) -}}</div>{{- '' -}}
</button>{{- '' -}}
{%- endfor -%}
{{- '\n' -}}
{%- endif -%}
</div>{{- '' -}}
</div>

View file

@ -248,6 +248,18 @@
<div class="description">{{ _('Automatically load next page when scrolling to bottom of current page') }}</div>
</fieldset>
{% endif %}
{% if 'search_on_category_select' not in locked_preferences %}
<fieldset>
<legend>{{ _('Search on category select') }}</legend>
<p class="value">
<select name='search_on_category_select'>
<option value="1" {% if search_on_category_select %}selected="selected"{% endif %}>{{ _('On') }}</option>
<option value="0" {% if not search_on_category_select %}selected="selected"{% endif %}>{{ _('Off')}}</option>
</select>
</p>
<div class="description">{{ _('Perform search immediately if a category selected. Disable to select multiple categories. (JavaScript required)') }}</div>
</fieldset>
{% endif %}
{{ plugin_preferences('ui') }}
{{ tab_footer() }}

View file

@ -395,7 +395,7 @@ def get_client_settings():
'http_method': req_pref.get_value('method'),
'infinite_scroll': req_pref.get_value('infinite_scroll'),
'translations': get_translations(),
'search_on_category_select': req_pref.plugins.choices['searx.plugins.search_on_category_select'],
'search_on_category_select': req_pref.get_value('search_on_category_select'),
'hotkeys': req_pref.plugins.choices['searx.plugins.vim_hotkeys'],
'theme_static_path': custom_url_for('static', filename='themes/simple'),
}
@ -422,6 +422,7 @@ def render(template_name: str, **kwargs):
kwargs['preferences'] = request.preferences
kwargs['autocomplete'] = request.preferences.get_value('autocomplete')
kwargs['infinite_scroll'] = request.preferences.get_value('infinite_scroll')
kwargs['search_on_category_select'] = request.preferences.get_value('search_on_category_select')
kwargs['results_on_new_tab'] = request.preferences.get_value('results_on_new_tab')
kwargs['advanced_search'] = request.preferences.get_value('advanced_search')
kwargs['query_in_title'] = request.preferences.get_value('query_in_title')