Multiple HubDB filters working at the same time?

Hi community! I’m creating a directory using HubDB and a custom module to display that director on a page.

I have 4 filters I’m using for my directory: Industry, Neighborhood, Language, and Content Type all of which are multi-select columns in my HubDB table. Right now, all of my filters work fine but they only work one at a time. I can filter by Industry OR language, etc. But I can’t filter by Industry AND language.

Wondering if anyone has any thoughts? Here is my code:

{% set selectedIndustry = request.query_dict.industry|int %}
{% set selectedLanguage = request.query_dict.language|int %}
{% set selectedNeighborhood = request.query_dict.neighborhood|int %}
{% set selectedContent = request.query_dict.content_rating|int %}

<div class="row-fluid resources-container">
 <!-- FILTERS SIDEBAR -->
 <div class="span3 widget-span resources-sidebar-container">
 <div class="sidebar-filters">
 <aside class="filters-content">
 <h2>Filter Directory</h2>
 <!--Filter by Industry. -->
 <form id="form_id" method="get">
 <div class="filter-group"> 
 <h4>Industry:</h4>
 <select name="industry" form="form_id" onChange="this.form.submit()">
 <option value="0">Show All</option>
 {% set industries = hubdb_table_column(2686809, "industry").options %}
 {% for choice in industries %}
 {% set industry_list = industry_list~choice.id|list%}
 {% if choice.id == selectedIndustry %}
 <option selected="selected" value="{{ choice.id }}">{{ choice.name }}</option>
 {% else %}
 <option value="{{ choice.id }}">{{ choice.name }}</option>
 {% endif %}
 {% endfor %}
 </select> 
 </div>
 </form> 
 <!--Filter by Language. --> 
 <form id="form_id2" method="get">
 <div class="filter-group">
 <h4>Language:</h4>
 <select name="language" form="form_id2" onChange="this.form.submit()">
 <option value="0">Show All</option>
 {% set languages = hubdb_table_column(2686809, "language").options %}
 {% for choice in languages %}
 {% set language_list = language_list~choice.id|list%}
 {% if choice.id == selectedLanguage %}
 <option selected="selected" value="{{ choice.id }}">{{ choice.name }}</option>
 {% else %}
 <option value="{{ choice.id }}">{{ choice.name }}</option>
 {% endif %}
 {% endfor %}
 </select> 
 </div>
 </form> 
 <!--Filter by Neighborhood. -->
 <form id="form_id3" method="get">
 <div class="filter-group">
 <h4>Neighborhood:</h4>
 <select name="neighborhood" form="form_id3" onChange="this.form.submit()">
 <option value="0">Show All</option>
 {% set neighborhoods = hubdb_table_column(2686809, "neighborhood").options %}
 {% for choice in neighborhoods %}
 {% set neighborhood_list = neighborhood_list~choice.id|list%}
 {% if choice.id == selectedNeighborhood %}
 <option selected="selected" value="{{ choice.id }}">{{ choice.name }}</option>
 {% else %}
 <option value="{{ choice.id }}">{{ choice.name }}</option>
 {% endif %}
 {% endfor %}
 </select> 
 </div>
 </form> 

 <!--Filter by Content Rating. -->
 <form id="form_id4" method="get">
 <div class="filter-group">
 <h4>Content Rating:</h4>
 <select name="content_rating" form="form_id4" onChange="this.form.submit()">
 <option value="0">Show All</option>
 {% set content_ratings = hubdb_table_column(2686809, "content_rating").options %}
 {% for choice in content_ratings %}
 {% set content_rating_list = content_rating_list~choice.id|list%}
 {% if choice.id == selectedContent %}
 <option selected="selected" value="{{ choice.id }}">{{ choice.name }}</option>
 {% else %}
 <option value="{{ choice.id }}">{{ choice.name }}</option>
 {% endif %}
 {% endfor %}
 </select> 
 </div> 
 </form> 
 <input name="page" type="hidden" id="page" class="autocomplete" placeholder="page">
 </aside>
 </div>
 </div>

{% set queryparam = "" %}
{% if selectedIndustry %}
 {% set queryparam = queryparam ~ "&industry__contains=" ~ selectedIndustry|urlencode %}
{% endif %}
{% if selectedLanguage %}
 {% set queryparam = queryparam ~ "&language__icontains="~selectedLanguage|urlencode %}
{% endif %} 
{% if selectedNeighborhood %}
 {% set queryparam = queryparam ~ "&neighborhood__icontains="~selectedNeighborhood|urlencode %}
{% endif %}
{% if selectedContent %}
 {% set queryparam = queryparam ~ "&content_rating__icontains="~selectedContent|urlencode %}
{% endif %}

Hi @arodriguez219,

Can you link to the page please? It’ll help to understand what happens when an option in each select is chosen and the form is submitted; I think that’s where your problem lies, because it looks like your HubL query parameters are set up correctly to chain together. When you make a selection is the new selection parameter added to the URL, does it override the old selection’s parameter in the URL?

It’s possible to do with JS/jQuery too. If you add the industry, language, neighbourhood and content of each item to the items you’re displaying/filtering as a class you can use an on change event for your filters. Something like:

$('select').change(function(){
 var filters = $.map($('select').toArray(), function(e){
 return $(e).val();
 }).join('.');
 $('.[items to be filtered]').hide();
 $('.[items to be filtered]' + filters).show();
});

In vanilla JS:

var selectElement = document.querySelectorAll('select');
var items = document.querySelectorAll('.[items to be filtered]');
selectElement.forEach(el => el.addEventListener('change', (e) => {
 var filters = Array.from(selectElement).map(function(e){
 return e.value;
 });
 filters = filters.join('.');
 for (i = 0; i < items.length; i++) {
 items[i].style.display = 'none';
 }
 let itemsShow = document.querySelectorAll('.[items to be filtered].'+filters);
 for (i = 0; i < itemsShow.length; i++) {
 itemsShow[i].style.display = 'flex';
 }
}));

@piersg

Thanks for your reply! The page I’m testing this on is www.tfocb.com/testing. You’ll see in the URL depending on what filter I’m using it will say www.tfocb.com/testing?FILTER=# but it will change if I go to another filter instead of www.tfocb.com/testing?FILTER1=#&FILTER2=#

@arodriguez219 I’m not sure why the URL parameter values are being overridden when you select a new value from the dropdown. However, I’ve come up with a JS solution for you. The only thing you need to change is to remove onChange=“this.form.submit()” from the dropdowns. I’ve added comments to make it clear what’s happening:

var selectElement = document.querySelectorAll('select');
selectElement.forEach(el => el.addEventListener('change', (e) => {
 // get type e.g. language
 let type = e.target.name;
 // get value 
 let val = e.target.value;
 // get current URL
 var url = new URL(location.href)
 // get URL parameters
 var search_params = url.searchParams;
 // if the type selected already exists in the URL as a parameter, override the current value with the new selected value, else add it to the URL as a new parameter
 if (window.location.search.indexOf(type) > -1) {
 search_params.set(type, val);
 } else {
 search_params.append(type, val);
 }
 // convert parameters to string
 url.search = search_params.toString();
 // conver full URL to string
 var new_url = url.toString();
 // load the url 
 window.location = new_url;
}));