Typeahead Bloodhound Filter

Filter a Bloodhound dataset dynamically

by likeuntomurphy

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.2/typeahead.bundle.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<div class="outer">
    <input type="text" class="form-control typeahead" placeholder="Typeahead . . ." />
    <p id="selected"></p>
</div>

CSS

div.outer {
    padding: 5%;
}

#selected {
    margin-top: 5%;
}

.tt-hint {
  color: #999
}

.tt-dropdown-menu {
  font-weight: lighter;  
  width: 100%;
  margin-top: -6px;
  padding: 8px 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
          box-shadow: 0 5px 10px rgba(0,0,0,.2);
  max-height: 150px;
  overflow-y: auto;
}

.tt-suggestion {
  padding: 3px 20px;
  font-size: 18px;
  line-height: 24px;
}

.tt-suggestion.tt-cursor, .tt-suggestion.tt-cursor small {
  color: #fff;
  background-color: #0097cf;

}

.tt-suggestion p {
  margin: 0;
}

.twitter-typeahead {
    top: 8px;
    width: 100%;
}

.empty-message {
    padding-left: 12px;
}

JavaScript

var selected = [];

var select = function(e, datum, dataset) {
    selected.push(datum.val);
    $("#selected").text(JSON.stringify(selected));
    $("input.typeahead").val("");
}

var filter = function(suggestions) {
    return $.grep(suggestions, function(suggestion) {
        return $.inArray(suggestion.val, selected) === -1;
    });
}

var data = new Bloodhound({
    name: 'animals',
    local: [{ val: 'dog' }, { val: 'pig' }, { val: 'moose' }],
    datumTokenizer: function(d) {
      return Bloodhound.tokenizers.whitespace(d.val);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace
});

data.initialize();

$('input.typeahead').typeahead(null,
    {
        name: 'animals',
        displayKey: 'val',
     /* don't use
        source: data.ttAdapter(), */
        source: function(query, cb) {
            data.get(query, function(suggestions) {
                cb(filter(suggestions));
            });
        },
        templates: {
            empty: '<div class="empty-message">No matches.</div>'
        }
    }
).bind('typeahead:selected', select);