CMS Development

jpineda91
Contributeur

HubDB filter

Résolue

Hello,
I'm working on a resource library using HubDB. I got most of the things working, except the filters by content_type. Filters display but I'm not sure if the URL ?topic=Case%20Study is created and shows only the resources type = Case Study.

 

<div class="resource-cards-module">
  {% if module.show_filters %}
  <div class="filters">
    <div class="filter-by-type">

      <select name="topic">
        <option value="">View Resources By Type</option>
        {% for content_type in resource_content_type|map(attribute='content_type') %}
        {% set resource_content_type = hubdb_table_rows(module.hubdbtable_field) %}
        <option>{{ content_type.name }}</option>
        {% endfor %}
      </select>
      <script>
        jQuery('select[name=topic').on('change',function(){
          let topic = jQuery(this).val();
          if(topic !='') {
            document.location.href='{{module.resources_page_link.url.href}}?topic={{tag}}'+topic;
          }   
        });
      </script>
    </div>
    <div class="search-articles">
      {% icon name="search" style="SOLID" %}
      <input type="text" name="search" placeholder="Search Resources" value="" />
    </div>
  </div>
  {% endif %}
  {% if module.headline %}<h2 class="text-center light">{{ module.headline }}</h2>{% endif %}
  <div class="grid">
    {% for row in hubdb_table_rows(module.hubdbtable_field,'&orderBy=-date','&limit='~module.limit) %}
    <div class="grid-item">
      <a href="{{ row.link }}" class="item-link"></a>
      <div class="item-image-wrapper">
        <div class="item-image" style="background-image: url('{{ row.featured_image.url }}');"></div>
      </div>
      <div class="item-content">
        <h3>{{ row.name }}</h3>
        {{ row.description|truncatehtml(150) }}
        <hr />
        {% if row.content_type %}
        <div class="resource-topics">
          {% for tag in row.content_type.name|split(',') %}
            <a class="resource-topic-link" href="{{module.resources_page_link.url.href}}?topic={{tag}}">{{ tag }}</a>{% if not loop.last %},{% endif %}
          {% endfor %}
        </div>
        {% endif %}
      </div>
    </div>
    {% endfor %}
  </div>
</div>

 

Any help is appreciated! 

Thanks in advance,
Jonathan

0 Votes
2 Solutions acceptées
BarryGrennan
Solution
Contributeur de premier rang

HubDB filter

Résolue

Hi Jonathan, 

 

Not sure if this is the solution, but it's the first thing I noticed - it looks to me like these two lines may be in the wrong order:

{% for content_type in resource_content_type|map(attribute='content_type') %}
        {% set resource_content_type = hubdb_table_rows(module.hubdbtable_field) %}

You're doing the for content_type in resource_content_type but it hasn't been set yet.


Edit:

 

jQuery('select[name=topic').on('change',function(){

 

Should also be:

 

jQuery('select[name="topic"]').on('change',function(){

 

Missing closing ']' and the quotes on topic may matter


Barry Grennan

Freelance HubSpot CMS Developer

Website | Contact

Voir la solution dans l'envoi d'origine

0 Votes
BarryGrennan
Solution
Contributeur de premier rang

HubDB filter

Résolue

You're not setting anything to filter the entries in your loop that creates the posts

So this:

 {% for row in hubdb_table_rows(module.hubdbtable_field,'&orderBy=-date','&limit='~module.limit) %}

 

Needs to call in your string from the url:

// You need to do an if statment to account for the fact that it may not be set:

{% if request.query_dict.topic %}
    {% set tableQuery = hubdb_table_rows(module.hubdbtable_field, 'content_type='+request.query_dict.topic) %}
    {% else %}
    {% set tableQuery = hubdb_table_rows(module.hubdbtable_field) %}
    {% endif %}

// I haven't included your other parameters but you can add then in yourself

 

Then you'd replace your:

 

{% for row in hubdb_table_rows(module.hubdbtable_field,'&orderBy=-date','&limit='~module.limit) %}
    

 

with:

 

 {% for row in tableQuery %}

 

Voir la solution dans l'envoi d'origine

18 Réponses
BarryGrennan
Contributeur de premier rang

HubDB filter

Résolue

I think this should work:

<div class="filters">
    <div class="filter-by-type">

      <select name="topic">
        <option value="">View Resources By Type</option>
         {% set resource_content_type = hubdb_table_rows(module.hubdbtable_field) %}
        {% for content_type in resource_content_type|map(attribute='content_type') %}
        <option>{{ content_type }}</option>
        {% endfor %}
      </select>
      <script>
        jQuery('select[name="topic"]').on('change',function(){
          let topic = jQuery(this).val();
          if(topic !='') {
            document.location.href='{{module.resources_page_link.url.href}}?topic='+topic;
          }   
        });
      </script>
    </div>

 

It worked in a very quick test I ran on my portal. I removed the ".name" from the option. My column "content_type" was just a text input, what type of input is yours that it has a name attribute, I'll test that out too.

jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan I added the code and this is how it is displaying
resources-code-1.png

0 Votes
BarryGrennan
Contributeur de premier rang

HubDB filter

Résolue

What type of field is the content_type column in the HubDB?

0 Votes
jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan It is a select
resources-table-1.png

0 Votes
BarryGrennan
Contributeur de premier rang

HubDB filter

Résolue

Ok, then this works for me, putting the .name back in:

 

 

 

<div class="filters">
    <div class="filter-by-type">

      <select name="topic">
        <option value="">View Resources By Type</option>
         {% set resource_content_type = hubdb_table_rows(module.hubdbtable_field) %}
        {% for content_type in resource_content_type|map(attribute='content_type') %}
        <option>{{ content_type.name }}</option>
        {% endfor %}
      </select>
      <script>
        jQuery('select[name="topic"]').on('change',function(){
          let topic = jQuery(this).val();
          if(topic !='') {
            document.location.href='{{module.resources_page_link.url.href}}?topic='+topic;
          }   
        });
      </script>
    </div>

 

 

 

But yes you'd need to publish the page or your document.location.href will 404

jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan Thanks for all your help! that fixed the display issue, but now I have a new issue 😓
I added more resources with the same content_type and it just shows the same filter option multiple times. 
Screen Shot 2022-07-20 at 6.44.03 PM.png

0 Votes
BarryGrennan
Contributeur de premier rang

HubDB filter

Résolue

I'd suggest you create an array instead and add to it "unless" the entry is already there. That'll rule out duplicates.

Then loop that array for the options

 

So like: 

 

 {% set content_type_array = [] %}
        {% for content_type in resource_content_type|map(attribute='content_type') %}
      {% unless content_type.name in content_type_array %}
      {% unless content_type.name == null %}
             {% do content_type_array.append(content_type.name) %}
        {% endunless %}
           {% endunless %}
        {% endfor %}

 

 

Then in your options you'd loop through the array instead:

 

     {% for item in content_type_array %}
        <option>{{ item }}</option>
        {% endfor %}

 

jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan  I'm sorry, I don't know how to implement the array.
Does that code replace the <select>?
*EDIT*  The code you suggested got rid of the duplicates 🙌 but I published the page to test the actual filtering ?topic and it does not work 😫
Any help is appreciated!

 

<select name="topic">
<option value="">View Resources By Type</option>
{% set content_type_array = [] %}
{% for content_type in resource_content_type|map(attribute='content_type') %}
{% unless content_type.name in content_type_array %}
  {% unless content_type.name == null %}
    {% do content_type_array.append(content_type.name) %}
  {% endunless %}
{% endunless %}
{% endfor %}
{% for item in content_type_array %}
   <option>{{ item }}</option>
{% endfor %}
</select>

 



0 Votes
BarryGrennan
Contributeur de premier rang

HubDB filter

Résolue

Did you resolve the jQuery issue I pointed out? Is the page reloading on change with e.g. ?topic=Guide at the end of the url?

0 Votes
jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan It is, but all the resources are displaying instead of ?topic=Guide
I just noticed that the <option> doesn't have any value=""

Screen Shot 2022-07-20 at 10.06.03 PM.png

0 Votes
BarryGrennan
Solution
Contributeur de premier rang

HubDB filter

Résolue

You're not setting anything to filter the entries in your loop that creates the posts

So this:

 {% for row in hubdb_table_rows(module.hubdbtable_field,'&orderBy=-date','&limit='~module.limit) %}

 

Needs to call in your string from the url:

// You need to do an if statment to account for the fact that it may not be set:

{% if request.query_dict.topic %}
    {% set tableQuery = hubdb_table_rows(module.hubdbtable_field, 'content_type='+request.query_dict.topic) %}
    {% else %}
    {% set tableQuery = hubdb_table_rows(module.hubdbtable_field) %}
    {% endif %}

// I haven't included your other parameters but you can add then in yourself

 

Then you'd replace your:

 

{% for row in hubdb_table_rows(module.hubdbtable_field,'&orderBy=-date','&limit='~module.limit) %}
    

 

with:

 

 {% for row in tableQuery %}

 

jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan Thank you so much! The code above worked.
Is there a way to keep the active filter displayed after the page reloads ?topic=eBook 

Screen Shot 2022-07-20 at 11.09.29 PM.png

0 Votes
BarryGrennan
Contributeur de premier rang

HubDB filter

Résolue

Play around with the {% if request.query_dict.topic %}

If the request.query_dict.topic equals the {{ item }} in your option add "selected" to the option.

If I've helped solve your problem, it'd be great if you could mark one of my answers as the solution 🙂

jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan I added this code: 

{% if request.query_dict.topic == item %} selected{% endif %}

And it works! Thank you so much for all your help!

0 Votes
BarryGrennan
Solution
Contributeur de premier rang

HubDB filter

Résolue

Hi Jonathan, 

 

Not sure if this is the solution, but it's the first thing I noticed - it looks to me like these two lines may be in the wrong order:

{% for content_type in resource_content_type|map(attribute='content_type') %}
        {% set resource_content_type = hubdb_table_rows(module.hubdbtable_field) %}

You're doing the for content_type in resource_content_type but it hasn't been set yet.


Edit:

 

jQuery('select[name=topic').on('change',function(){

 

Should also be:

 

jQuery('select[name="topic"]').on('change',function(){

 

Missing closing ']' and the quotes on topic may matter


Barry Grennan

Freelance HubSpot CMS Developer

Website | Contact

0 Votes
jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan Thanks for your reply. Should it be:

{% set resource_content_type = hubdb_table_rows(module.hubdbtable_field) %}
{% for content_type in resource_content_type|map(attribute='content_type') %}

 

0 Votes
BarryGrennan
Contributeur de premier rang

HubDB filter

Résolue

I would have thought so, yeah.

Because you're doing a for loop base on resource_content_type but it hasn't been set yet.

Also just to note that I edited my reply (I think just before you replied) to mention that your jQuery may not work due to missing closing bracket, etc.

0 Votes
jpineda91
Contributeur

HubDB filter

Résolue

@BarryGrennan Thanks for your reply.

I updated the code, but I'm not sure if the filter works. Do you know if it would work on a preview page?

0 Votes