Filtering HubDB elements with HTML Checkboxes

Highlighted
Regular Contributor

Hi,

 

I'm working on creating a video directory, using HubDB to store the details for each video.

I'm looking for a way where a user can filter the results iterated from HubDB by interacting with HTML checkboxes like this:

Capture.PNG

The issue I'm having at the moment is that I don't see a straightforward way to connect the user interacting with checkboxes and the HubDB filter queries.

I tried using javascript for if conditionals and use HubL code inside, but it seems that the HubL code regardless if it passes the logic test or not.  I have since removed that and I am a little stuck. 

Would greatly appreciate some help. Thanks!

I've included the HTML+HubL code below:

 

{% set nofilter = hubdb_table_rows(1036506)%}
<div class="hubdb-outer-wrapper">Level-of-interest
  <div class="hubdb-content-wrapper">
  <div class="hubdb-left-column">
    Level of Study
    <div class="checkboxes">
     <input id="emba-box" type="checkbox" name="Level-of-interest-emba" value="Executive+MBA">EMBA
     <input id="mba-box" type="checkbox" name="Level-of-interest-mba" value="MBA" onclick="mbaFilter()">MBA<br>
     <input id="masters-box" type="checkbox" name="Level-of-interest-masters" value="Masters" checked>Masters<br>
    </div>
    Region of Study
    <div class="checkboxes">
     <input id="china-box" type="checkbox" name="region-study-china" value="China">China
     <input id="india-box" type="checkbox" name="region0study-india" value="India">India<br>
     <input id="africa-box" type="checkbox" name="region-study-africa" value="Africa">Africa<br>
      </div>
   </div>
   <div class="hubdb-right-column">
  {% for row in nofilter %}
      <div class="hubdb-box">
       <div class="hubdb-image">
          <img src="{{ row.thumbnail.url }}">
        </div>
        <div class="hubdb-title">
          {{ row.name }}
        </div>
        <div class="hubdb-description">
          {{ row.description }}
        </div>
     </div>
     {% endfor %}
   </div>
  </div>
</div>
Reply
0 Upvotes
4 Replies 4
Advisor

Hey @Aaaaandrei 

 

I did something similar recently! I will have to get back to the code and follow up with the solutions I had come up with.

If in the unlikely scenary you don't hear from me in the nexty few days please message me!

Regular Contributor

Thank you Kevin, looking forward to hearing from you!

Cheers,

Andrei

Reply
0 Upvotes
Advisor

Hey @Aaaaandrei 

 

Thanks for the reminder message.

Below I've dropped in a basic template code that I built for a POC and learning experience for myself. You'' have to excuse the mess haha.

 

This is purely a JS solution, I might have a HUBL excusive solution that I will continue to look for.

 

I have clarified any comments I had left in the code to help understand what is going on / the thought process.

 

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>{{ content.html_title }}</title>
    <meta name="description" content="{{ content.meta_description }}">
    {{ standard_header_includes }}
    
    <style>
      img {
        max-width: 200px;
      }

      .grid {
        display: grid;
        grid-gap: 0;
        grid-template-columns: repeat(auto-fill,minmax(220px,1fr));
      }

      ul {
        padding: 0px;
      }
    </style>
    
  </head>
  <body>
    <form name="filters-form"></form>

    {% if dynamic_page_route_level == 0 %}
    <h1>Gallery - 0</h1><!-- For tracking purpose - remove for production -->
    <div class="grid">

      {% set rows = hubdb_table_rows(1056514) %}
      {% for row in rows %}
      <a class="gallery-1 gallery-card" href="{{ request.path }}/{{ row.hs_path }}" data-filter="{{row.tags}}">
        <img src="{{row.image.url}}" alt="" />
        <h2>{{ row.hs_name }}</h2>
        <p>{{row.tags}}</p>
      </a>
      {% endfor %}
    </div>
    {% endif %}

    {% if dynamic_page_route_level == 1 %}
    <h1>Gallery - 1</h1><!-- For tracking purpose - remove for production -->
    <h2>{{dynamic_page_hubdb_row.hs_name}}</h2>
    {% set rows = hubdb_table_rows(dynamic_page_hubdb_row.hs_child_table_id) %}
    <ul class="grid">
      {% for row in rows %}
      <a class="gallery-1 gallery-card" href="{{ request.path }}/{{ row.hs_path }}" data-filter="{{row.tags}}">
        <img src="{{row.image.url}}" alt="" />
        <h2>{{ row.hs_name }}</h2>
        <p>{{row.tags}}</p>
      </a>
      {% endfor %}
    </ul>
    {% endif %}

    <script>
      $(document).ready(function() {
        var filterValues = [];

        // Get all filters and place into an array
        function getAllFilters() {
          var returnArray = [];
          $('.gallery-card').each( function() {
            var c = $(this).data('filter').split(' ');
            console.log(c);
            returnArray = returnArray.concat(c).unique(); ;
          });
          return returnArray;
        }
        // Prevent duplicates in the filters
        Array.prototype.unique = function() {
          var a = this.concat();
          for(var i=0; i<a.length; ++i) {
            for(var j=i+1; j<a.length; ++j) {
              if(a[i] === a[j])
                a.splice(j--, 1);
            }
          }
          return a;
        };

        // Populate the filters in to the form
        function popFilters(filArray) {
          for (i=0; i<filArray.length; i++) {
            var checkbox = '<label><input type="checkbox" value="' + filArray[i] + '">' + filArray[i] + '</label>';
            $('[name="filters-form"]').append(checkbox);
          }
        }

        // Initialize the filters
        popFilters(getAllFilters());

        // Watch the filters form for changes
        $('form[name="filters-form"]').change(function () {
          // collect array of all "checked" checkboxes
          //var appliedFilters = getFiltersForm();
          // pass array into  filter function
          // function hides and shwos based on arry
          updateUi( getFiltersForm() );
        });

        // Collect the checked filters
        function getFiltersForm() {
          var filters = [];
          $('form[name="filters-form"] input[type="checkbox"]:checked').each( function() {
            var value =$(this).val();
            filters.push(value);
            console.log('filters = ' + filters);
          });
          return filters;
        }

        // Check if values are in an array
        function isInArray(needles, haystack){ 
          for(var i = 0 , len = needles.length; i < len; i++){
            if($.inArray(needles[i], haystack) == -1) return false;
          }
          return true;
        }

        // Update the gallery the UI
        function updateUi(b) {
          if (b.length <=0) {
            $('.gallery-card').show();
          } else {
            $('.gallery-card').each( function() {
              var a = $(this).data('filter').split(' ');
              console.log(isInArray(b,a));
              if ( isInArray(b,a) != true ) {
                $(this).hide();
              } else if ( isInArray(b,a) == true ) {
                $(this).show();
              }
            });
          }
        }

        // NEXT STEPS
        // Add querystring recognition and history API states

      });
    </script>

    {{ standard_footer_includes }}
  </body>
</html>

A few things to note:

- I'm pretty sure this POC uses an Additive Filtering model, it's been some time since I've been in it.

- This was also built for a multi level UI (terminology?), meaning it used nested database tables.

- This uses the html markup as the data source…slaps self on the wrist. This would ideally use JSON produced by HUBL and opperate more like a true micro SPA.

- My POC did not have filter categories as your UI shows, but I'm positive with a little logic this can be solved easily.

- The plan for this piece when in production was to do 2 additional things that aren't included here: 1) Use the history api so the user can use the back and forward  buttons. 2) Use a query string to allow deep linking.

 

 

 

EDIT:

After rereading the initiasl post I'm not positive this was a solution for you, but I hope it at least gets you going in the right direction.

Regular Contributor

Hi @Kevin-C ,

Thanks a lot for sharing this!

While I can't directly apply this, it's really useful to look at your logic and try to extrapolate from here.

Cheers,

Andrei