JSFiddle - React, Tailwind, and code Playground

by Michael Keller

HTML

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<div class="section-title">Topics</div>
<ul data-group="topics">
    <li>
        <label>Politics
            <input type="checkbox" value="politics" />
        </label>
    </li>
    <li>
        <label>Race
            <input type="checkbox" value="race" />
        </label>
    </li>
    <li>
        <label>Religion
            <input type="checkbox" value="religion" />
        </label>
    </li>
</ul>
<div class="section-title">Author</div>
<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>

<div class="section-title">Results</div>
<div id="results"></div>

<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...

CSS

body {
    font-family: Helvetica;
    font-size: 11px;
}

.section-title{
    font-weight: bold;
    margin: 10px 0;
}
#results{
    font-size: 12px;
}
.result{
    margin-bottom: 5px;
}

JavaScript

var article_data = [{
    id: 1,
    title: "Fearing midterm turnout, Jedis embrace dark side.",
    authors: ["person-a", "person-b"],
    topics: ["politics", "religion"]
}, {
    id: 2,
    title: "We used the force to clean our apartment, you won't believe what happened next.",
    authors: ["person-b", "person-c"],
    topics: ["religion"]
}, {
    id: 3,
    title: "Can ewoks use the force? Jedi council debates.",
    authors: ["person-c"],
    topics: ["race", "religion"]
}]
var collection = new PourOver.Collection(article_data);
    
var topicsFilter = PourOver.makeInclusionFilter("topics", ["race", "religion", "politics"]);
var authorsFilter = PourOver.makeInclusionFilter("authors", ["person-a", "person-b", "person-c"]);

collection.addFilters([topicsFilter, authorsFilter]);

var TitleSort = PourOver.Sort.extend({
    attr: 'uqbar',
    fn: function(a,b){
        if (b.title < a.title){
          return -1;
        } else if (b.title > a.title){
          return 1;
        } else {
          return 0;
        }
    }
});

var title_sort = new TitleSort('title_sort');

collection.addSorts([title_sort]);

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

printResults();

$('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());
    printResults();
});

function printResults(){
    var results = view.getCurrentItems(),
        $resultsContainer = $('#results');
    // Clear previous...