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">Titles</div>
<input type="text" />
<br/>
<br/>
<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) {
          ...

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"]);

// We'll populate this with cids from our text inputting via Bloodhound
var textSearchFilter = PourOver.makeManualFilter("title")

collection.addFilters([topicsFilter, authorsFilter, textSearchFilter]);

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

// Grab everything and store it
// We'll feed this to Bloodhound
// Grab a list of all cids to pass when we want to 
var base_view = view.getCurrentItems(),
    all_cids  = _.pluck(base_view, 'cid');

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

// Set up bloodhound
// https://github.com/twitter/typeahead.js/blob/master/doc/bloodhound.md

var engine = new Bloodhound({
    name: 'articles',
    local: base_view,
 ...