Saturday, January 24, 2015

Typeahead js Autocomplete Suggestion Bloodhount Remote Data Tutorial and Demo

Typeahead.js improved version includes Bloodhound suggestion engine which handles filtering and sorting things for you. 

Typeahead Js is similar to google, facebook, twitter, gmail auto suggestion. It completes the full string when you type.

You need

  • JQuery
  • Typeahead JS Plugin
  • BloodHound Suggestion Engine (Part of Typeahead Project)


To initiate Typeahead on any input use $("ELEMENTSELECTOR").typeahead();

Typeahead has following notable options. read all here 

 hint  - If  true  shows the Hint as you Type.

typeahead Hint shown
typeahead autocompletes the word when you type - Hint

 highlight  -  If  true  highlights the options (Bold Text).


Typeahead Highlight Option explained
Highlight Object of Typeahead
If you want to have more control over the result set displayed as suggestions, use templates object.
template object with Typeahead JS
Templates Object with Suggestion function

Check out the working code
 
<!-- Bootstrap core CSS OPTIONAL -->
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- JavaScript
================================================== -->

<!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script>
<script src="js/typeahead.bundle.js"></script>
<script src="js/bloodhound.js"></script>

Javascript Array of Country List

var country_list = ["Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua &amp; Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia &amp; Herzegovina","Botswana","Brazil","British Virgin Islands","Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Cape Verde","Cayman Islands","Chad","Chile","China","Colombia","Congo","Cook Islands","Costa Rica","Cote D Ivoire","Croatia","Cruise Ship","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Polynesia","French West Indies","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guam","Guatemala","Guernsey","Guinea","Guinea Bissau","Guyana","Haiti","Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kuwait","Kyrgyz Republic","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Mauritania","Mauritius","Mexico","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Namibia","Nepal","Netherlands","Netherlands Antilles","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","Norway","Oman","Pakistan","Palestine","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Pierre &amp; Miquelon","Samoa","San Marino","Satellite","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","South Africa","South Korea","Spain","Sri Lanka","St Kitts &amp; Nevis","St Lucia","St Vincent","St. Lucia","Sudan","Suriname","Swaziland","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor LEste","Togo","Tonga","Trinidad &amp; Tobago","Tunisia","Turkey","Turkmenistan","Turks &amp; Caicos","Uganda","Ukraine","United Arab Emirates","United Kingdom","Uruguay","Uzbekistan","Venezuela","Vietnam","Virgin Islands (US)","Yemen","Zambia","Zimbabwe"];

Javascript for Typeahead with Local Javascript Array

           $(document).ready(function() {

// Set the Options for "Bloodhound" Engine
var my_Suggestion_class = new Bloodhound({
limit: 10,
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(value),
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: $.map(country_list, function(item) {
//console.log(item);
return {value: item};
})
});

//Initialize the Suggestion Engine
my_Suggestion_class.initialize();

var typeahead_elem = $(.typeahead);
typeahead_elem.typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: value,
displayKey: value,
source: my_Suggestion_class.ttAdapter(),
templates: {
empty: [
<div class="noitems">,
No Items Found,
</div>
].join(
)
}
});
});

Typeahead need array of JSON object to show the suggestion. 

{ "identifier" : "itemvalue}{ "identifier" : "itemvalue} ]

We have prepared above structured array from JQuery map function
                    local: $.map(country_list, function(item) {
return {value: item};
})

    datumTokenizer: Bloodhound.tokenizers.obj.whitespace(value),
queryTokenizer: Bloodhound.tokenizers.whitespace,
The above two Tokenizer lines may confuse every one. datumTokenizer needs the array of JSON as shown here

{ "identifier" : "itemvalue}{ "identifier" : "itemvalue} ]

If your array or JSON data structure is same as above then 

datumTokenizer: Bloodhound.tokenizers.obj.whitespace(identifier)

Typeahead shows plain string without any styling if you dont customize the response. You can modifiy the following style as you like.

Stlying the Suggestions

<style>
.typeahead,
.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;
}

.typeahead {
background-color: #fff;
}

.typeahead:focus {
border: 2px solid #0097cf;
}

.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-cursor {
color: #fff;
background-color: #0097cf;

}

.tt-suggestion p {
margin: 0;
}
tt-highlight{
color:red;
}
</style>

Output of Typeahead in browser

To modify the result displayed in suggestion you need to add templates object with typeahead.

It has four options
empty - If no result found return this custom text / style.
suggestion - Adding HTML Elements and customizing the result suggestion shown when you type.
header - To add header data for the suggestion list shown
footer - Similar to header, add footer text to result set shown in screen.

Typeahead JS with Bloodhound Remote and Prefetch


            $(document).ready(function() {
//Set up "Bloodhound" Options
var my_Suggestion_class = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(vval),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: "countries.json",
filter: function(countryArray) {
return $.map(countryArray, function(country) {
return {vval: country.name};
});
//return catAR;
}
},
remote: {
url: "s.php?s=%QUERY",
filter: function(x) {
return $.map(x, function(item) {
return {vval: item.name};
});
},
wildcard: "%QUERY"
}
//http://code.educationgovt.com/typeaheadjs/countries.json
});

// Initialize Typeahead with Parameters
my_Suggestion_class.initialize();
var typeahead_elem = $(.typeahead);
typeahead_elem.typeahead({
hint: false,
highlight: true,
minLength: 1
},
{
// `ttAdapter` wraps the suggestion engine in an adapter that
// is compatible with the typeahead jQuery plugin
name: vval,
displayKey: vval,
source: my_Suggestion_class.ttAdapter()
});

//Get the Typeahead Value on Following Events
$(input).on([
typeahead:initialized,
typeahead:initialized:err,
typeahead:selected,
typeahead:autocompleted,
typeahead:cursorchanged,
typeahead:opened,
typeahead:closed
].join( ), function(x) {
//console.log(this.value);
});
});

How to get typeahead Selected input value 

Following events applicable on typeahead input element. I have given the events with complete example below
                $(input).on([
typeahead:initialized,
typeahead:initialized:err,
typeahead:selected,
typeahead:autocompleted,
typeahead:cursorchanged,
typeahead:opened,
typeahead:closed
].join( ), function(x) {
console.log(this.value);
});

Prefetch Data will be stored in localstorage

When the page is loaded the response from prefetch will be stored in localstorage.

Fetching Remote JSON Data in suggestion

Check the Demo

<script type=text/javascript>
var image_url = "http://image.tmdb.org/t/p/original/";
$(window).load(function(){
// Instantiate the Bloodhound suggestion engine
var movies = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: http://api.themoviedb.org/3/search/movie?query=%QUERY&api_key=470fd2ec8853e25d2f8d86f685d2270e,
filter: function (movies) {
return $.map(movies.results, function (movie) {
return {
value: movie.original_title,
release_date: movie.release_date,
poster_path:image_url+movie.poster_path
};
});
}
}
});

// Initialize the Bloodhound suggestion engine
movies.initialize();
// Instantiate the Typeahead UI
$(.typeahead).typeahead(null, {
displayKey: value,
source: movies.ttAdapter(),
templates: {
suggestion: Handlebars.compile("<p style=padding:6px><img width=50 src={{poster_path}}> <b>{{value}}</b> - Release date {{release_date}} </p>"),
footer: Handlebars.compile("<b>Searched for {{query}}</b>")
}
});
});

</script>

The difference is remote data response is JSON array. We use filter function to prepare the data we need to display in suggestion.

Thats it.


No comments:

Post a Comment

Note: Only a member of this blog may post a comment.