Skip to content

Commit

Permalink
Use templatetag to help displaying search options in template
Browse files Browse the repository at this point in the history
  • Loading branch information
ffont committed Mar 5, 2024
1 parent ae4d40b commit e6fbc2a
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 84 deletions.
3 changes: 2 additions & 1 deletion DEVELOPERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ engine backend, this should be done in the `SearchQueryProcessor.as_query_params

Adding a new search option to `SearchQueryProcessor` will make the option work with the search engine backend and with search URLs,
but it will NOT automatically add the option to the form in the search page. This will need to be done manually by adding the
search option in the desired place in `templates/search/search.html` (see how other search options are implemented for inspiration).
search option in the desired place in `templates/search/search.html` (see how other search options are implemented for inspiration,
there is a `display_search_option` templatetag which will facilitate things in most cases).

All this will add the search option to the user interface and send corresponding information to the search backend. For example,
if the new search option should apply a filter in the search backend of some `new_property`, this will be handled by the `SearchQueryProcessor`.
Expand Down
13 changes: 7 additions & 6 deletions freesound/static/bw-frontend/src/pages/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const searchInputBrowse = document.getElementById('search-input-browse');
const searchInputBrowsePlaceholder = searchInputBrowse.getAttribute("placeholder");
const removeSearchInputValueBrowse = document.getElementById('remove-content-search');
const advancedSearchOptionsDiv = document.getElementById('advanced-search-options');
const tagsMode = document.getElementsByName('tm')[0] !== undefined;
const tagsMode = location.pathname.indexOf('/browse/tags/') > -1;

const updateRemoveSearchInputButtonVisibility = (searchInputElement) => {
if (searchInputElement.value.length) {
Expand Down Expand Up @@ -168,11 +168,12 @@ searchFormElement.getElementsByClassName('bw-checkbox').forEach(checkbox => {
checkbox.parentNode.appendChild(hiddenCheckbox);
});


var sortByElement = document.getElementById('sort-by');
sortByElement.addEventListener('change', function() {
searchFormElement.submit();
})
var sortByElement = document.getElementById('id_sort_by');
if (sortByElement !== null){
sortByElement.addEventListener('change', function() {
searchFormElement.submit();
})
}

document.body.addEventListener('keydown', evt => {
const ENTER_KEY = 13
Expand Down
17 changes: 17 additions & 0 deletions freesound/static/bw-frontend/styles/pages/search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,23 @@
}
}

.bw-search_input {
border: 1px solid $border-input;
color: $black;
background-color: $background-input;
padding: 10px 20px;
border-radius: 5px;

&::placeholder {
color: $navy-light-grey;
}

&:focus {
background-color: $white;
border: 1px solid $black;
}
}

.browse__search-overview-sorter {
display: flex;
align-items: center;
Expand Down
16 changes: 16 additions & 0 deletions search/templatetags/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from django.conf import settings

from sounds.models import License
from utils.search import search_query_processor_options
from utils.tags import annotate_tags

register = template.Library()
Expand Down Expand Up @@ -114,3 +115,18 @@ def display_facet(context, facet_name):
element['icon'] = 'fcw'

return {'type': facet_type, 'title': facet_title, 'facet': facet}


@register.inclusion_tag('search/search_option.html', takes_context=True)
def display_search_option(context, option_name, widget=None):
sqp = context['sqp']
option = sqp.options[option_name]
if widget is None:
# If a widget is not provided as a parameter, use a sensible default
widget = {
search_query_processor_options.SearchOptionBool: 'checkbox',
search_query_processor_options.SearchOptionStr: 'text',
search_query_processor_options.SearchOptionChoice: 'select',
}.get(type(option), 'text')
label = option.label if option.label else option_name.capitalize().replace('_', ' ')
return {'option': option, 'option_name': option_name, 'label': label, 'widget': widget}
103 changes: 27 additions & 76 deletions templates/search/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ <h3 class="v-spacing-5 text-light-grey center">Choose a tag to start browsing</h
<span class="bw-search_remove-query" id="remove-content-search">{% bw_icon 'close' %}</span>
</div>
<input type="hidden" name="f" value="{{ sqp.render_filter_for_url|urlencode }}" />
{% if not sqp.options.field_weights.is_default_value %}<input type="hidden" name="{{ sqp.options.field_weights.query_param_name }}" value="{{ sqp.options.field_weights.value_formatted }}" />{% endif %}
{% if not sqp.options.similar_to.is_default_value %}<input type="hidden" name="{{ sqp.options.similar_to.query_param_name }}" value="{{ sqp.options.similar_to.value_formatted }}" />{% endif %}
{% if not sqp.options.field_weights.is_default_value %}{% display_search_option "field_weights" "hidden" %}{% endif %}
{% if not sqp.options.similar_to.is_default_value %}{% display_search_option "similar_to" "hidden" %}{% endif %}
</div>
{% if sqp.tags_mode_active %}
{% comment %}"sounds tagged as" label with follow/unfollow buttons{% endcomment %}
Expand Down Expand Up @@ -86,16 +86,12 @@ <h3>
{% comment %}sorting options{% endcomment %}
<div class="col-4 right browse__search-overview-sorter">
<div class="{% if sqp.map_mode_active %}display-none{% endif %}">
<span class="font-weight-normal text-light-grey d-none d-md-inline">{{ sqp.options.sort_by.label }}:</span>
<select id="sort-by" name="{{ sqp.options.sort_by.query_param_name }}" {% if sqp.options.sort_by.disabled %}disabled{% endif %}>
{% if sqp.similar_to_active %}
<option>Similarity to target</option>
{% else %}
{% for option in sqp.options.sort_by.get_choices_annotated_with_selection %}
<option value="{{option.0}}"{% if option.2 %}selected="selected"{% endif %}>{{option.1}}</option>
{% endfor %}
{% endif %}
</select>
{% if not sqp.similar_to_active %}
{% display_search_option "sort_by" %}
{% else %}
<span class="font-weight-normal text-light-grey d-none d-md-inline">{{ sqp.options.sort_by.label }}:</span>
<span><b>Similarity to target</b></span>
{% endif %}
</div>
</div>
</div>
Expand Down Expand Up @@ -138,66 +134,24 @@ <h3>
Other
</div>
<div class="row no-gutters v-spacing-top-1">
{% with sqp.options.is_geotagged as option %}
<div class="col-6 v-padding-1">
<label class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ option.label }}</div>
</label>
<div class="col-6 v-padding-1">
{% display_search_option "is_geotagged" %}
</div>
{% endwith %}
{% with sqp.options.is_remix as option %}
<div class="col-6 v-padding-1">
<label class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ option.label }}</div>
</label>
<div class="col-6 v-padding-1">
{% display_search_option "is_remix" %}
</div>
{% endwith %}
{% with sqp.options.group_by_pack as option %}
<div class="col-6 v-padding-1">
<label class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ option.label }}</div>
</label>
<div class="col-6 v-padding-1">
{% display_search_option "group_by_pack" %}
</div>
{% endwith %}
{% with sqp.options.display_as_packs as option %}
<div class="col-6 v-padding-1">
<label class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ option.label }}</div>
</label>
<div class="col-6 v-padding-1">
{% display_search_option "display_as_packs" %}
</div>
{% endwith %}
{% with sqp.options.grid_mode as option %}
<div class="col-6 v-padding-1">
<label class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ option.label }}</div>
</label>
<div class="col-6 v-padding-1">
{% display_search_option "grid_mode" %}
</div>
{% endwith %}
{% with sqp.options.map_mode as option %}
<div class="col-6 v-padding-1">
<label class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ option.label }}</div>
</label>
<div class="col-6 v-padding-1">
{% display_search_option "map_mode" %}
</div>
{% endwith %}
</div>
</div>
</div>
Expand All @@ -209,17 +163,12 @@ <h3>
</div>
</div>
</div>
<div class="row v-spacing-top-1">
{% with sqp.options.compute_clusters as option %}
<div class="col-6 v-padding-1">
<label class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ option.label }}</div>
</label>
<div class="row">
<div class="col-6 v-padding-1">
<div class="v-spacing-top-1">{% display_search_option "compute_clusters" %}</div>
<div class="v-spacing-top-1">{% display_search_option "similar_to" %}</div>
</div>
{% endwith %}

</div>
{% endif %}
</div>
Expand All @@ -234,6 +183,7 @@ <h3>
{% if clusters_data %}
{% include 'search/clustering_results.html' %}
{% else %}
{% if get_clusters_url %}
<div class="async-section"
data-async-section-content-url="{{ get_clusters_url }}">
<div class="h-padding-2 v-spacing-top-2">
Expand All @@ -243,6 +193,7 @@ <h3>
</div>
</div>
{% endif %}
{% endif %}
{% endif %}
</div>
</form>
Expand Down
20 changes: 20 additions & 0 deletions templates/search/search_option.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% if widget == 'checkbox' %}
<label for="id_{{ option_name }}" class="between w-100 cursor-pointer {% if option.disabled %}opacity-020{% endif %}">
<div class="bw-search__filter-checkbox">
<input id="id_{{ option_name }}" name="{{ option.query_param_name }}" type="checkbox" class="bw-checkbox" {% if option.value %}checked{% endif %} {% if option.disabled %}disabled{% endif %}/>
</div>
<div class="bw-search__filter-name">{{ label }}</div>
</label>
{% elif widget == 'text' %}
<label for="id_{{ option_name }}" class="{% if option.disabled %}opacity-020{% endif %}">{{ label }}</label>:
<input id="id_{{ option_name }}" name="{{ option.query_param_name }}" class="bw-search_input" type="text" value="{{ option.value_formatted }}" {% if option.disabled %}disabled{% endif %}/>
{% elif widget == 'select' %}
<span class="font-weight-normal text-light-grey d-none d-md-inline">{{ label }}:</span>
<select id="id_{{ option_name }}" name="{{ option.query_param_name }}" {% if option.disabled %}disabled{% endif %}>
{% for choice in option.get_choices_annotated_with_selection %}
<option value="{{choice.0}}"{% if choice.2 %}selected="selected"{% endif %}>{{choice.1}}</option>
{% endfor %}
</select>
{% elif widget == 'hidden' %}
<input type="hidden" name="{{ option.query_param_name }}" value="{{ option.value_formatted }}" />
{% endif %}
2 changes: 1 addition & 1 deletion utils/search/search_query_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class SearchQueryProcessor(object):
query_param_name='st')
compute_clusters = SearchOptionBool(
query_param_name='cc',
label='Cluster results by similarity')
label='Cluster results by sound similarity')
cluster_id = SearchOptionInt(
advanced=False,
query_param_name='cid',
Expand Down

0 comments on commit e6fbc2a

Please sign in to comment.