Wednesday, September 10, 2014

Twitter typehead.js basic example with token field.

A simple example for twitter typehead.js.

The server should return an array of type:

[ { name: "asas", value: "1234" }, { name: "asas", value: "121212" } ]


Include following CSS and js:

<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link href="tokenfield-typeahead.css" rel="stylesheet">
<link href="bootstrap-tokenfield.css" rel="stylesheet">
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
     <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
     <script src="http://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.4/typeahead.bundle.min.js" ></script>

     <script src="bootstrap-tokenfield.js" ></script>

Style ur typeahead:

      <style>
.tt-query,
.tt-hint {
    width: 396px;
    height: 30px;
    padding: 8px 12px;
    font-size: 24px;
    line-height: 30px;
    border: 2px solid #ccc;
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
    outline: none;
}

.tt-query {
    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
    color: #999
}

.tt-dropdown-menu {
    width: 422px;
    margin-top: 12px;
    padding: 8px 0;
    background-color: #fff;
    border: 1px solid #ccc;
    border: 1px solid rgba(0, 0, 0, 0.2);
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
    -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);
}

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

.tt-suggestion.tt-is-under-cursor {
    color: #fff;
    background-color: #0097cf;

}

JS for intializing typehead,  tokenizer and bloodhound:

 <script>
      $(function() {
      
  var engine = new Bloodhound({
  datumTokenizer: function(d) {
  return Bloodhound.tokenizers.whitespace(d.value); 
  },
  queryTokenizer: function(d) {
  return Bloodhound.tokenizers.whitespace(d.name); 
  },
  prefetch: '/contact/fetch?host=lifesize.com&user=bsaraf&password=testing!!123&term=S',
  remote: '/contact/fetch?host=lifesize.com&user=bsaraf&password=testing!!123&term=%QUERY'
});
 
engine.initialize();
 
   $('#exampleInputEmail1').tokenfield({
  typeahead: [null, {  source: engine.ttAdapter() }]
});
   $('#exampleInputEmail1').tokenfield();
   $(document).ajaxSend(function(event, jqXHR, settings) {
       console.log("Loading");
   $('.tt-hint').css('background-repeat', 'no-repeat');
   $('.tt-hint').css('background-position', '98%');
   $('.tt-hint').css('background-image', 'url("http://primefaces-rocks.appspot.com/design/ajaxloading.gif")');
   });

   $(document).ajaxComplete(function(event, jqXHR, settings) {
      console.log("Loaded.");
   $('.tt-hint').css('background', '');
   });
});
 </script>

And a simple html:

<input type="text" class="form-control" id="exampleInputEmail1" placeholder="Enter email">


And what you get is:




The Bloodhound docuementation is available at: https://github.com/twitter/typeahead.js/blob/master/doc/bloodhound.md#remote


I had to do dynamic change the url to fetch results in bloodhound based on some paramters.
This I achieved by:


var engine = new Bloodhound({
           datumTokenizer: function(d) {
                   return Bloodhound.tokenizers.whitespace(d.value)
           },
           queryTokenizer: function(d) {
                   return Bloodhound.tokenizers.whitespace(d.name)
           },
           prefetch: '/contact/fetch?host=lifesize.com&user=bsaraf&password=testing!!123&term=S',
           remote:{
                        'url' : '/contact/fetch?term=%QUERY',
                        'replace' : function(url,query) {
                                var q = '/contact/fetch?host='+$('#exampleInputHostName').val()+'&user='
                                                + encodeURIComponent($('#exampleInputUser').val())
                                                + '&password='
                                                + encodeURIComponent($('#exampleInputPassword1').val())
                                                + '&term='
                                                + query;
                                return q;
                        }
          }

        });


If you see the above code remote has a new replace method which fetched the values from input  fields and appends them to url. Note, here method takes query as argument to give the exact term typed in by user.