Dropdown for filtering subjects in timetable

Hi there, have been taking some inspiration from https://community.hubspot.com/t5/CMS-Development/Add-a-filter-dropdown-to-a-listing-page-containing-HubDB-similar/m-p/339886 to create a simple filter to filter the results in https://8830131.hs-sites.com/timetable-with-filter by things such as mode. I’ve been able to get the dropdown to populate and url to change but not been able to get the results to actually change based on this.
See code for module:

<h2>2023 Timetable</h2>

<div>
 <form id="form_id" method="get">
 <div>
 <h4>Filter by Delivery Mode:</h4>
 <select id="delivery_mode" class="delivery_mode" name="delivery_mode">
 <option selected value="show-all">Show all</option>
 {% set types = hubdb_table_column(5886054, "delivery_mode").options %}
 {% for choice in types %}
 <option {% if choice.name == request.query_dict.delivery_mode %} selected {% endif %} value="{{ choice.name }}">{{ choice.name }}</option>
 {% endfor %}
 </select>
 </div>
 </form>
</div>

<!-- sets the different query parameters using submitted input for hubdb query -->
{% set queryparam = "" %}
{% if request.query_dict.delivery_mode in ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30"] %}
 {% set queryparam = queryparam ~ "&delivery_mode="~request.query_dict.delivery_mode|urlencode %}
{% endif %}
{% if request.query_dict.delivery_mode == "show-all" %}
 {% set queryparam = queryparam %}
{% endif %}

{% for row in hubdb_table_rows(5886054, "&orderBy=intake_period" ~ queryparam) %} 
 <div class="card">
 <h6 class="heading">
 {{ row.subject_name }}
 </h6>
 <p>
 <strong>Intake Period:</strong> {{ row.intake_period.name }}<br>
 <strong>Campus:</strong> {% for campus_availability in row.campus_availability %}
 {{ campus_availability.name }}{% endfor %}<br> 
 <strong>Associated Courses:</strong> {% for associated_course in row.associated_course %}
 {{ associated_course.name }}{% if not loop.last %}, {% endif %}{% endfor %}<br> 
 {% if row.intensive_dates %}
 <strong>Intensive or staggered class dates:</strong> {{row.intensive_dates}}<br>
 {% endif %} 
 {% if row.class_time %}
 <strong>Class time (by host):</strong> {{row.class_time}}<br>
 {% endif %}
 {% if row.class_frequency %}
 <strong>Frequency:</strong> {% for class_frequency in row.class_frequency %} {{class_frequency.name}}{% endfor %}<br>
 {% endif %}
 {% if row.delivery_mode %}
 <strong>Mode:</strong> {{row.delivery_mode.name}}<br>
 {% endif %}
 {% if row.prerequisites %}
 <strong>Prerequisites:</strong> {{row.prerequisites}}<br>
 {% endif %}
 {% if row.additional_notes %}
 <strong>Notes:</strong> {{row.additional_notes}}
 {% endif %}
 </p>
 </div> 
{% endfor %} 

<script>
const deliveryModeFilterElement = document.getElementById('delivery_mode');
let deliveryModeFilter = ''; // Initialize the filter value

deliveryModeFilterElement.addEventListener('change', function(event) {
 deliveryModeFilter = event.target.value; // Update the filter value
 // Perform any additional logic or actions based on the new filter value

 // Trigger form submission to apply the filter
 document.getElementById('form_id').submit();
});
</script>

Is someone able to help with why this might be broken? I’ve probably overlooked something pretty trivial I assume.

Cheers.

Hi @Luke-Simp,

There are some ways to improve you code.

So for instance, the queryparam.

When I want to modify the queryparam I want to have controle over what it’s doing.

So I start with an empty variable like this.

{% set queryparam = '' %}

When adding extra options I append info (in this example an orderBy function) like this.

{% set queryparam = queryparam ~ '&orderBy=name' %}

When searching inside a a multiselect field, you can search if a value is inside the list of choices like this.

{% set delivery_mode = hubdb_table_column('5886054', "delivery_mode").options %}

{% if request.query_dict.delivery_mode in delivery_mode|map('id') %}
 {% set queryparam = queryparam ~ "&delivery_mode="~request.query_dict.delivery_mode|urlencode %}
{% endif %}

The problem if you let if check by a manual array like [1,2,3,4] if you Add new values and remove old ones,it won’t match.

Last thing you need to do is setup the HubDB to query.

{% set rows = hubdb_table_rows('5886054', queryparam) %}

{% for row in rows %}
 {{ row.name }}
{% endfor %}

One last thing I recommand is setting up a variable for you HubDB. This way you can also make it dynamically withing a HubSpot field (hubdb table) and replace all hardcoded Table IDs

{% set db = module.table_id || '5886054' %} (# dynamic setup with a fallback #}

{# Replace the Hardcoded ID #}
{% set rows = hubdb_table_rows(db, queryparam) %}

{# Also replace the Hardcoded ID for the delivery_mode #}
{% set delivery_mode = hubdb_table_column(db, "delivery_mode").options %}

Hi Indra,

Thanks for your feedback and help. I’m very much a novice coder so I was having trouble following your suggestions sorry. Easier to understand if I can see in the complete code where you suggest these changes but have attempted updating with the following. If you’re able to advise how to fix that would be appreciated!

<h2>2023 Timetable</h2>

<div>
 <form id="form_id" method="get">
 <div>
 <h4>Filter by Delivery Mode:</h4>
 <select id="delivery_mode" class="delivery_mode" name="delivery_mode">
 <option selected value="show-all">Show all</option>
 {% set db = module.table_id || '5886054' %}
 {% set delivery_mode = hubdb_table_column(db, "delivery_mode").options %}
 {% for choice in delivery_mode %}
 <option {% if choice.name == request.query_dict.delivery_mode %} selected {% endif %} value="{{ choice.name }}">{{ choice.name }}</option>
 {% endfor %}
 </select>
 </div>
 </form>
</div>

<!-- sets the different query parameters using submitted input for hubdb query -->
{% set queryparam = '' %}
{% if request.query_dict.delivery_mode in delivery_mode|map('id') %}
 {% set queryparam = queryparam ~ "&delivery_mode="~request.query_dict.delivery_mode|urlencode %}
{% endif %}
{% if request.query_dict.delivery_mode == "show-all" %}
 {% set queryparam = queryparam ~ '&orderBy=subject_name' %}
{% endif %}

{% set rows = hubdb_table_rows(db, queryparam) %}
{% for row in hubdb_table_rows(db, "&orderBy=intake_period" ~ queryparam) %} 
 <div class="card">
 <h6 class="heading">
 {{ row.subject_name }}
 </h6>
 <p>
 <strong>Intake Period:</strong> {{ row.intake_period.name }}<br>
 <strong>Campus:</strong> {% for campus_availability in row.campus_availability %}
 {{ campus_availability.name }}{% endfor %}<br> 
 <strong>Associated Courses:</strong> {% for associated_course in row.associated_course %}
 {{ associated_course.name }}{% if not loop.last %}, {% endif %}{% endfor %}<br> 
 {% if row.intensive_dates %}
 <strong>Intensive or staggered class dates:</strong> {{row.intensive_dates}}<br>
 {% endif %} 
 {% if row.class_time %}
 <strong>Class time (by host):</strong> {{row.class_time}}<br>
 {% endif %}
 {% if row.class_frequency %}
 <strong>Frequency:</strong> {% for class_frequency in row.class_frequency %} {{class_frequency.name}}{% endfor %}<br>
 {% endif %}
 {% if row.delivery_mode %}
 <strong>Mode:</strong> {{row.delivery_mode.name}}<br>
 {% endif %}
 {% if row.prerequisites %}
 <strong>Prerequisites:</strong> {{row.prerequisites}}<br>
 {% endif %}
 {% if row.additional_notes %}
 <strong>Notes:</strong> {{row.additional_notes}}
 {% endif %}
 </p>
 </div> 
{% endfor %} 
<script>
const delivery_modeElement = document.getElementById('delivery_mode');
let delivery_modeFilter = ''; // Initialize the filter value

delivery_modeElement.addEventListener('change', function(event) {
 delivery_mode = event.target.value; // Update the filter value
 // Perform any additional logic or actions based on the new filter value

 // Trigger form submission to apply the filter
 document.getElementById('form_id').submit();
});
</script>

Thanks in advance.

Hi @Luke-Simp

From the provided code, it seems that you are correctly updating the URL parameter when the delivery mode filter is changed. However, the issue lies in the way you are using the `queryparam` variable to filter the results. Here are a few suggestions to fix the problem:

1. Update the form action:
- Add `action=“{{ hubdb_table_url(5886054) }}”` to the `<form>` tag. This ensures that the form submits to the current page URL with the updated query parameters.

2. Update the loop that fetches the table rows:
- Instead of `{% for row in hubdb_table_rows(5886054, “&orderBy=intake_period” ~ queryparam) %}`, use `{% for row in hubdb_table_rows(5886054, queryparam ~ “&orderBy=intake_period”) %}`. This change allows the query parameters to be applied correctly to the table rows.

With these changes, the modified code should look like this:

```html
<h2>2023 Timetable</h2>

<div>
<form id=“form_id” method=“get” action=“{{ hubdb_table_url(5886054) }}”>
<div>
<h4>Filter by Delivery Mode:</h4>
<select id=“delivery_mode” class=“delivery_mode” name=“delivery_mode”>
<option selected value=“show-all”>Show all</option>
{% set types = hubdb_table_column(5886054, “delivery_mode”).options %}
{% for choice in types %}
<option {% if choice.name == request.query_dict.delivery_mode %} selected {% endif %} value=“{{ choice.name }}”>{{ choice.name }}</option>
{% endfor %}
</select>
</div>
</form>
</div>

<!-- sets the different query parameters using submitted input for hubdb query -->
{% set queryparam = “” %}
{% if request.query_dict.delivery_mode in [“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”,“10”,“11”,“12”,“13”,“14”,“15”,“16”,“17”,“18”,“19”,“20”,“21”,“22”,“23”,“24”,“25”,“26”,“27”,“28”,“29”,“30”] %}
{% set queryparam = queryparam ~ “&delivery_mode=”~request.query_dict.delivery_mode|urlencode %}
{% endif %}
{% if request.query_dict.delivery_mode == “show-all” %}
{% set queryparam = queryparam %}
{% endif %}

{% for row in hubdb_table_rows(5886054, queryparam ~ “&orderBy=intake_period”) %}
<div class=“card”>
<h6 class=“heading”>
{{ row.subject_name }}
</h6>
<!-- Rest of the card content -->
</div>
{% endfor %}

<script>
const deliveryModeFilterElement = document.getElementById(‘delivery_mode’);
let deliveryModeFilter = ‘’; // Initialize the filter value

deliveryModeFilterElement.addEventListener(‘change’, function(event) {
deliveryModeFilter = event.target.value; // Update the filter value
// Perform any additional logic or actions based on the new filter value

// Trigger form submission to apply the filter
document.getElementById(‘form_id’).submit();
});
</script>
```

Make sure to include this modified code and test if the filter functionality works as expected.

Hope this will helps you out. Please mark it as Solution to help other community member.

Thanks!

Hi Gaurav,

Thanks for your guidance and support! Looks good.

I’m getting an error with <form id=“form_id” method=“get” action=“{{ hubdb_table_url(5886054) }}”>

Sepecifically hubdb_table_url(5886054) is saying there’s a syntax error. When searching hubdb_table_url I can’t see any other examples of this on google so is there maybe a different way we can express this section of the code?

Cheers.