JSFiddle - React, Tailwind, and code Playground

by Michael Keller

HTML

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
Topics
<ul data-group="topics">
    <li><label>U.S. Politics <input type="checkbox" value="us-politics"/></label></li>
    <li><label>Race <input type="checkbox" value="race"/></label></li>
    <li><label>Religion <input type="checkbox" value="religion"/></label></li>
</ul>

Author
<ul data-group="authors">
    <li><label>Person A <input type="checkbox" value="person-a"/></label></li>
    <li><label>Person B <input type="checkbox" value="person-b"/></label></li>
    <li><label>Person C <input type="checkbox" value="person-c"/></label></li>
</ul>

<script>
    var PourOver = (function(){

    PourOver = {
      // Utility functions. Skip down to "Collections" for the real meat of PourOver.
      //
      // # The basic sorted set operations
      //
      union_sorted: function(a,b){
        // Make more efficient by just copying at Infinity
        var lowa = 0, lowb = 0, higha = a.length, highb = b.length, result=[], la, lb;
        while (higha > lowa || highb > lowb){
          la = a[lowa];
          lb = b[lowb];
          if(_.isUndefined(la)) la = Infinity;
          if(_.isUndefined(lb)) lb = Infinity;
          if(lowa == higha){
            return result.concat(b.slice(lowb,highb));
          }
          if(lowb == highb){
            return result.concat(a.slice(lowa,higha));
          }
          if(la == lb){
            result.push(la);
            lowa++;lowb++;
          } else if (la < lb){
            result.push(la);
            lowa++;
          } else {
            result.push(lb);
            lowb++;
          }
        }
        return result;
      },
      intersect_sorted: function(a,b){
        var lowa = 0, lowb = 0, higha = a.length, highb = b.length, result=[], la, lb;
        while (higha > lowa && highb > lowb){
          la = a[lowa];
          lb = b[lowb];


          if(la == lb){
            result.push(la);
            lowa++;lowb++;
          } else if (la <...

JavaScript

var article_data = [
    {id: 1,  authors: ["person-a","person-b"], topics: ["us-politics", "religion"]},
    {id: 2,  authors: ["person-b","person-c"], topics: ["religion"]},
    {id: 3,  authors: ["person-c"], topics: ["race", "religion"]},
    ]

var collection = new PourOver.Collection(article_data);
    
var topicsFilter = PourOver.makeInclusionFilter("topics", ["race", "religion", "us-politics"]);
var authorsFilter = PourOver.makeInclusionFilter("authors", ["person-a", "person-b", "person-c"]);

collection.addFilters([topicsFilter, authorsFilter]);

var view = new PourOver.View('default_view', collection);

$('input[type="checkbox"]').on('change', function(){
    var $this = $(this),
        filter_group = $this.parents('ul').attr('data-group'),
        value = $this.val(),
        checked = $this.prop('checked') == true;
    
    console.log(filter_group, value, checked);
    
    // If it's checked set the query to the value of this tag
    if (checked){
	    collection.filters[filter_group].intersectQuery(value);
	} else {
	// If it's not checked then clear the query from the PourOver match set.
		collection.filters[filter_group].removeSingleQuery(value);
	}
	console.log(view.getCurrentItems());
});