CMS Development

Woodsy
Contributor

Glossary Realtime Filter

SOLVE

I have got a glossary list showing and am trying to add a dropdown filter and keyword search. The list is being pulled from a HubDB. I am trying to make the dropdown (column from HubDb called 'category2' and keyword search both update the list in realtime rather than having to press a submit button. Would anyone be able to let me know how I would implement the filter? Thank you in advance for any help.

 

<!--
  templateType: page
  isAvailableForNewContent: true
  label: Glossary 2200A
-->
{% extends "./layouts/base.html" %}

{% block body %}

{% if dynamic_page_hubdb_row %}

<!-- Content Page -->
<h1>{{ dynamic_page_hubdb_row.hs_name }}</h1>
<p>{{dynamic_page_hubdb_row.description}}</p>
<!-------->

{% elif dynamic_page_hubdb_table_id %}


<!-- Hero -->
{% dnd_area "body_dnd_area" %}
    {% dnd_section
        background_image = {
            'backgroundPosition': 'MIDDLE_CENTER',
            'backgroundSize': 'cover',
            'imageUrl': 'https://www.dragndrop.com/bg-image.jpg'
          },
          max_width=1000,
          vertical_alignment='MIDDLE'
    %}
        {% dnd_module path='../modules/Hero' %}
            {% module_attribute "html"%}
                This is your main headline.
                Use this space to tell everyone about what you have to offer.
            {% end_module_attribute %}
        {% end_dnd_module %}
    {% end_dnd_section %}
{% end_dnd_area %}
<!-------->




<!-- A-Z Filter Buttons -->
<div class="a-z_filter">
				
  <div class="">
     
  </div>

  <div class="a-z_filter_outercontainer">
    <div class="a-z_label v1"><p><strong>Find terms by letter:</strong></p></div>
    <div class="a-z_filter_container">

    <div class="a-z_label v2"><p><strong>Find terms<br>by letter:</strong></p></div>

    {% set table = hubdb_table_rows(module.hubdb_id) %}
    {% set alphabet = ["3","A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] %}
    {% for letter in alphabet %}    
    <a class="a-z_button" href="#{{ letter }}">{{ letter }}</a>
    {% endfor %}

    </div>
  </div>
</div>
<!-------->



<!-- Dropdown and Search Box that will update the list in realtime with no need to press a submit button-->
<div>
  <form id="form_id" method="get" >
    {# Category2 filter #}
    <div>
      <h3>Keyword Filter:</h3>
      <select name="category2" form="form_id" onChange="this.form.submit()">
        <option value="show-all">Show All</option>
        dropdown list pulled from HuBdb category2 column
      </select>
    </div>
    {# Search filter #}
    <div>
      <input name="publication" type="text" id="search-by" class="autocomplete" value="" placeholder="Search by keyword">
    </div>
  </form>
</div>
<!-------->











<!-- A-Z Listing -->
{% set table = hubdb_table_rows(module.hubdb_id) %}
{% set alphabet = ["3","A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] %}

<div class="row-fluid a-z">
  
{% for letter in alphabet %}
    
<h3 id="{{ letter }}" class="letter">{{ letter }}</h3>
  
  <div class="set">
    
      <ul class="word">
        
      {% for row in hubdb_table_rows(dynamic_page_hubdb_table_id) %}
      {% if row.name is string_startingwith letter %}

        <li><a href="{{ request.path }}/{{ row.hs_path }}?hs_preview=AyQeGSab-190730271634">{{ row.name }}</a></li>

      {% endif %}   
      {% endfor %}
        
      </ul>
     
  </div>

{% endfor %}
</div>
<!-------->




{% endif %}


<!-- CTA Banner-->
{% global_partial path='./partials/footer-cta-banner.html' %}
<!-------->
{% endblock %}

 

 

Woodsy_0-1749068233730.png

 

0 Upvotes
1 Accepted solution
sylvain_tirreau
Solution
Top Contributor

Glossary Realtime Filter

SOLVE

You can first retrieve and display all rows when rendering the page by including "data-*" attributes on each row. This would look something like this:

<div>
  <h3>Filter by category:</h3>
  <select id="category-filter">
    <option value="show-all">Show all</option>
    {% set rows = hubdb_table_rows(module.hubdb_id) %}
    {% set categories = rows | map(attribute='category2') | unique %}
    {% for category in categories %}
      <option value="{{ category }}">{{ category }}</option>
    {% endfor %}
  </select>
</div>

<div>
  <h3>Search by keyword:</h3>
  <input type="text" id="keyword-search" placeholder="Enter keyword...">
</div>

<div class="row-fluid a-z">
  {% for letter in alphabet %}
    <h3 id="{{ letter }}" class="letter">{{ letter }}</h3>
    <ul class="word">
      {% for row in rows %}
        {% if row.name is string_startingwith letter %}
          <li 
            data-category="{{ row.category2 }}" 
            data-name="{{ row.name | lower }}">
            <a href="{{ request.path }}/{{ row.hs_path }}">{{ row.name }}</a>
          </li>
        {% endif %}
      {% endfor %}
    </ul>
  {% endfor %}
</div>

 

And you can do something like this in javascript&colon;

document.addEventListener('DOMContentLoaded', function() {
    const selectCategory = document.getElementById('category-filter');
    const inputKeyword   = document.getElementById('keyword-search');
    const items     = Array.from(document.querySelectorAll('.word li'));

    function filterList() {
      const chosenCategory = selectCategory.value;
      const keyword = inputKeyword.value.trim().toLowerCase();

      items.forEach(li => {
        const category  = li.dataset.category;
        const name = li.dataset.name;
        const matchCategory = (chosenCategory === 'show-all' || category === chosenCategory);
        const matchKeyword  = (keyword === '' || name.includes(keyword));
        li.style.display = (matchCategory && matchKeyword) ? '' : 'none';
      });
    }

    selectCategory.addEventListener('change', filterList);
    inputKeyword.addEventListener('input', filterList);
  });

This is untested. Adapt this to your code.

View solution in original post

0 Upvotes
4 Replies 4
sylvain_tirreau
Solution
Top Contributor

Glossary Realtime Filter

SOLVE

You can first retrieve and display all rows when rendering the page by including "data-*" attributes on each row. This would look something like this:

<div>
  <h3>Filter by category:</h3>
  <select id="category-filter">
    <option value="show-all">Show all</option>
    {% set rows = hubdb_table_rows(module.hubdb_id) %}
    {% set categories = rows | map(attribute='category2') | unique %}
    {% for category in categories %}
      <option value="{{ category }}">{{ category }}</option>
    {% endfor %}
  </select>
</div>

<div>
  <h3>Search by keyword:</h3>
  <input type="text" id="keyword-search" placeholder="Enter keyword...">
</div>

<div class="row-fluid a-z">
  {% for letter in alphabet %}
    <h3 id="{{ letter }}" class="letter">{{ letter }}</h3>
    <ul class="word">
      {% for row in rows %}
        {% if row.name is string_startingwith letter %}
          <li 
            data-category="{{ row.category2 }}" 
            data-name="{{ row.name | lower }}">
            <a href="{{ request.path }}/{{ row.hs_path }}">{{ row.name }}</a>
          </li>
        {% endif %}
      {% endfor %}
    </ul>
  {% endfor %}
</div>

 

And you can do something like this in javascript&colon;

document.addEventListener('DOMContentLoaded', function() {
    const selectCategory = document.getElementById('category-filter');
    const inputKeyword   = document.getElementById('keyword-search');
    const items     = Array.from(document.querySelectorAll('.word li'));

    function filterList() {
      const chosenCategory = selectCategory.value;
      const keyword = inputKeyword.value.trim().toLowerCase();

      items.forEach(li => {
        const category  = li.dataset.category;
        const name = li.dataset.name;
        const matchCategory = (chosenCategory === 'show-all' || category === chosenCategory);
        const matchKeyword  = (keyword === '' || name.includes(keyword));
        li.style.display = (matchCategory && matchKeyword) ? '' : 'none';
      });
    }

    selectCategory.addEventListener('change', filterList);
    inputKeyword.addEventListener('input', filterList);
  });

This is untested. Adapt this to your code.

0 Upvotes
BérangèreL
Community Manager
Community Manager

Glossary Realtime Filter

SOLVE

Hi @Woodsy, I hope that you are well!
 

Thanks for asking the HubSpot Community!

I spotted these threads, not sure if that's entirely similar to what you are looking for but it might be interesting for you to take a look:

- The solution from @alyssamwilie on this post "Passing HubDB Multi-selection select options into Module Field Choice option"
- The solution from @alyssamwilie on this post "Choice field / select a row from HubDB list within a custom module"

Also, I'd love to put you in touch with our Top Experts: Hi @jonchim, @matt_scott and @Stephanie-OG do you have suggestions to help @Woodsy, please?

Have a fantastic day and thanks so much in advance for your help!
Bérangère


HubSpot’s AI-powered customer agent resolves up to 50% of customer queries instantly, with some customers reaching up to 90% resolution rates.
Learn More.


Saviez vous que la Communauté est disponible en français?
Rejoignez les discussions francophones en changeant votre langue dans les paramètres! !
0 Upvotes
Woodsy
Contributor

Glossary Realtime Filter

SOLVE

Hi @Bérangère

 

Those links you shared are not quite right for what I'm after. I would be extremely gratefully to any other community members who maybe able to share their knowledge around this request.

Thank you again Bérangère for reaching out to me with those suggestions.

James

0 Upvotes
BérangèreL
Community Manager
Community Manager

Glossary Realtime Filter

SOLVE

Hi @Woodsy, thanks for getting back to me!

I'd love to put you in touch with our Top Experts: Hi @sylvain_tirreau, @Anton and @zach_threadint do you have suggestions to help @Woodsy, please?

Have a lovely weekend and thanks so much in advance for your help!
Bérangère


HubSpot’s AI-powered customer agent resolves up to 50% of customer queries instantly, with some customers reaching up to 90% resolution rates.
Learn More.


Saviez vous que la Communauté est disponible en français?
Rejoignez les discussions francophones en changeant votre langue dans les paramètres! !