← Snippets - Script

Editable Blog Categories

This script allows for blog-style articles to be reordered by most recent (as seen here), but once that’s complete, also takes comma-separated items from a CMS-only div and adds it to a dropdown. This allows clients to create their own list of categories to filter the blog.

By adding ?search=category+name to the end of the URL (for example, yoursite-uat.banno.com/personal/blog?search=credit+101), you can load the page with that category auto-filtered. Note that to do this the spaces in the category will need to be replaced with plus signs, and the category should be in all lower case. To link to these auto-filtered views, the link will need to be manually added in the code view of the CMS.

How To

Script (script.js)

// Blog page - reorder news articles by most recent, and once done reordering take the visible articles and add their categories to a select dd
function sortDescending(a, b) {
  var date1  = $(a).find(".blog-item-inner-text-date").text();
    date1 = date1.split('/');
    date1 = new Date(date1[2], date1[0], date1[1] -1);
    var date2  = $(b).find(".blog-item-inner-text-date").text();
    date2= date2.split('/');
    date2= new Date(date2[2], date2[0], date2[1] -1);
    return date1 < date2 ? 1 : -1;
}
$(document).ready(function() {
    $('.reorderable-articles .reorderable').sort(sortDescending).appendTo('.reorderable-articles');

    if(document.location.search.length) {
        setTimeout(function() {
          var locationSearch = document.location.search;
          var locationSearchArray = locationSearch.split('=');
          var initialCategory = locationSearchArray.pop();
          $('#categoryFilter option').each(function() {
              var singleCategory = $(this).text();
              var categoryIndex = $(this).index();
              if(initialCategory == singleCategory.toLowerCase().split(' ').join('+')) {
                $('#categoryFilter option:eq('+ categoryIndex +')').prop('selected', true);
                filterBlog(initialCategory.split('+').join(' '));
                return false;
              }
          })
        }, 800);
    }

    function categorySelect() { // Adding necessary categories to dropdown
        var categoryArray = [];
        $('.reorderable-articles .blog-item-inner-text-tags').each(function() {
          var categoryString = $.trim($(this).text());
          var singleCardArray = categoryString.split(', ');
          for (var i = 0; i < singleCardArray.length; ++i) {
              categoryArray.push(singleCardArray[i]);
          }
        });
        var result = [];
        $.each(categoryArray, function (i, e) {
          var matchingItems = $.grep(result, function(item) {
              return item === e;
          });
          if( matchingItems.length === 0) {
              result.push(e);
          }
        });

      for (var i = 0; i < result.length; ++i) {
        $('#categoryFilter').append('<option value="' + result[i] + '">' + result[i] + '</option>');
      }
  }

  categorySelect();

  function filterBlog(filter) { // Functionality to filter entries based on option selected. Function called in an .on('change') function see below
    var categoryValue = filter.toLowerCase();

    $('.reorderable-articles .blog-item-inner-text-tags').each(function() {
      var categoryString = $.trim($(this).text().toLowerCase());
      var singleCardArray = categoryString.split(', ');
      for (var i = 0; i < singleCardArray.length; ++i) {
          if(categoryValue == singleCardArray[i]) {
            $(this).closest('.reorderable').removeClass('d-none');
            return true;
          } else {
            $(this).closest('.reorderable').addClass('d-none');
          }
      }
    });
    if(categoryValue === 'all categories') {
      $('.reorderable-articles .reorderable').each(function() {
          $(this).removeClass('d-none');
      });
    }
  }

  $('#categoryFilter').on('change', function() {
    filterBlog($(this).val());
  });

  if($('#categoryFilter').val() === 'All Categories') {
    $('.reorderable-articles .reorderable').each(function() {
      $(this).removeClass('d-none');
    });
  }
});

HTML (ex: blog.mustache)

Here is an an example HTML setup that you can paste into your mustache file and build/customize to your needs. In the example, all the class names will match what’s in the script. {% raw %}

<div class="form-group">
  	<label for="categoryFilter" class="sr-only">Filter By Category</label>
  	<select id="categoryFilter" class="form-control">
    	<option value="All Categories">All Categories</option>
    	{{! The remaining options auto populate based on a script }}
  	</select>
</div>
<div class="row reorderable-articles">
    <div class="col-sm-6 d-none remove-blank reorderable mb-3">
      	<div class="blog-item remove-blank">
        	<div class="blog-item-inner">
          		<div class="blog-item-inner-image">
	            	<div data-content-block="blog1image" data-content="content" data-editable="editable" class="content remove-blank">
		              {{#page.blog1image}}
		                  {{& content}}
		                {{/page.blog1image}}
		                <!-- @if NODE_ENV!='production' -->
		                    <img src="https://dummyimage.com/476x300?text=2019-6-1" alt="">
		                <!-- @endif -->
		            </div>
          		</div>  
          		<div class="blog-item-inner-text">
		            <div data-content-block="blog1blurb" data-content="content" data-editable="editable" class="blog-item-inner-text-blurb">
		              {{#page.blog1blurb}}
		                  {{& content}}
		                {{/page.blog1blurb}}
		                  <!-- @if NODE_ENV!='production' -->
		                    <p class="big"><strong>Max of 90 Cards Total</strong></p>
		                    <p>Optional supporting text goes here.</p>
		                    <p><a href="/style-guide">Call to Action</a></p>
		                  <!-- @endif -->
		            </div>
	            	<div data-content-block="blog1date" data-content="content" data-editable="editable" class="blog-item-inner-text-date cms-only">
		              {{#page.blog1date}}
		                  {{& content}}
		                {{/page.blog1date}}
		                  <!-- @if NODE_ENV!='production' -->
		                    06/01/2019
		                  <!-- @endif -->
		            </div>
	            	<div data-content-block="blog1tagss" data-content="content" data-editable="editable" class="blog-item-inner-text-tags cms-only remove-blank">
		              {{#page.blog1tags}}
		                  {{& content}}
		                {{/page.blog1tags}}
		                <!-- @if NODE_ENV!='production' -->
		                    Banking Basics
		                <!-- @endif -->
		            </div>
          		</div>
        	</div>
      	</div>
    </div>
    {{! repeat as needed}}
</div> 

{% endraw %}

Example Sites

Tags: cards, BS4, blog, filter, script, js, jquery, javascript, html