Sapnesh Naik
Software Developer, Technical Writer
sapnesh@kerneldev.com
Blog Post

Laravel Autocomplete Search with typeahead.Js

February 7, 2018

Search autocompletion is a must-have feature for most web applications of today and I have used Twitter’s typeahead.js autocomplete library in many of the Laravel based projects I have worked on. typeahead.js provides a simple yet robust solution for search autocompletion and it comes coupled with an excellent suggestion engine called Bloodhound.

The typeahead.js Library Consists of Two Parts:

  1. Bloodhound – The suggestion engine, is responsible for computing suggestions and offers advanced functionalities such as prefetching, intelligent caching, fast lookups, and backfilling with remote data.
  2. Typeahead – The User Interface, using which you can display the search results and it also provides several options for customization.

Now let us see how we can use typeahead.js in our Laravel application by implementing an autocomplete user search in this tutorial.

Set up Routes and Controllers:

  • Define a route in web.php to display our search form

    Route::view('/search', 'search');
  • Define a search route which will be responsible for returning search results.

    Route::get('/user/find', 'SearchController@searchUsers');
  • Create a SearchController and add the following searchUsers() method to it.

    public function searchUsers(Request $request)
    {
      return User::where('name', 'LIKE', '%'.$request->q.'%')->get();
    }

Set up The View:

  • Create a search.blade.php in the resources/views directory and add the below code to it.

    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="www.kerneldev.com">
        <meta name="author" content="sapnesh_naik">
    
    	<title>Laravel Search Autocomplete tutorial</title>
    
        <!-- Bootstrap core CSS -->
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
    
        <!-- Custom styles for this template -->
        <link href="{{asset('starter-template.css')}}" rel="stylesheet">
     	<style>
        	.twitter-typeahead,
        	.tt-hint,
        	.tt-input,
        	.tt-menu{
            	width: auto ! important;
            	font-weight: normal;
    
        	}
     	</style>
      </head>
      <body>
    
        <div class="container">
    
          <div class="starter-template" style="align-text:center">
    		<h1>Laravel Search Autocomplete</h1>
    		<br>
    		<input type="text" id="search" placeholder="Type to search users" autocomplete="off" >
    	  </div>
    
        </div>
    
    
        <!-- Bootstrap core JavaScript
        ================================================== -->
        <!-- Placed at the end of the document so the pages load faster -->
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
    	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
    
    
        <!-- Import typeahead.js -->
    	<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
    
        <!-- Initialize typeahead.js on the input -->
    	<script>
        	$(document).ready(function() {
        		var bloodhound = new Bloodhound({
    				datumTokenizer: Bloodhound.tokenizers.whitespace,
    				queryTokenizer: Bloodhound.tokenizers.whitespace,
    				remote: {
    					url: '/user/find?q=%QUERY%',
    					wildcard: '%QUERY%'
    				},
    			});
    
    			$('#search').typeahead({
    				hint: true,
    				highlight: true,
    				minLength: 1
    			}, {
    				name: 'users',
    				source: bloodhound,
    				display: function(data) {
    					return data.name  //Input value to be set when you select a suggestion.
    				},
    				templates: {
    					empty: [
    						'<div class="list-group search-results-dropdown"><div class="list-group-item">Nothing found.</div></div>'
    					],
    					header: [
    						'<div class="list-group search-results-dropdown">'
    					],
    					suggestion: function(data) {
    					return '<div style="font-weight:normal; margin-top:-10px ! important;" class="list-group-item">' + data.name + '</div></div>'
    					}
    				}
    			});
            });
    	</script>
    
      </body>
    </html>
  • Here we process the suggestions using bloodhound and you can see that we have specified remote.url as /user/find?q=%QUERY%, which is the route we defined in our web.php.

    • We then initialize typeahead on out search input and set the source as bloodhound.
    • Some key things to note here:
    • The display function is responsible for the input value that is going to be set when you select a suggestion.
    • Templates key lets you customize the look of your suggestions, here you can set a template for when there are no results found (empty) and you can also customize the actual suggestion template.
    • I have added this style script to fix a bug where the width of the suggestions was not equal to the input itself. Feel free to use this and customize it to your needs.

      <style>
        .twitter-typeahead,
        .tt-hint,
        .tt-input,
        .tt-menu{
             width: auto ! important;
             font-weight: normal;
         }
      </style>
    • Feel free to play around with other options such as hint and highlight and there are lots more options for typeahead and you can read them all on its GitHub page.

That’s it, your search autocompletion should work now! Here is how my simple example looks like.

Laravel autocomplete search with typeahead.js

The source code for the example project used in this tutorial can be found in my GitHub repository.