Skip to content

Instantly share code, notes, and snippets.

@dogrocker
Last active April 19, 2016 03:57
Show Gist options
  • Save dogrocker/20c255a7919d7033f73d to your computer and use it in GitHub Desktop.
Save dogrocker/20c255a7919d7033f73d to your computer and use it in GitHub Desktop.
Autocomplete with Laravel 5.1 & Materializecss & Typeahead.js
  • View index.blade.php
<div class="row">
    {!! Form::open(['route' => 'some.route', 'autocomplete' => 'off', 'class' => 'col s12']) !!}
      <div class="row">
        <div class="input-field col s6">
          {!! Form::text('username', isset($user->username) ? $user->username : '', ['id' => 'username', 'placeholder' => '']) !!}
          {!! Form::label('username', 'Username') !!}
        </div>
      </div>
    {!! Form::close() !!}
</div>
  • route.php
Route::get('/', 'SearchController@index'); // Or some serach form.
Route::get('search/queryUsers', ['as' => 'search.query_users', 'uses' => 'SearchController@queryUsers']);
  • Controller SearchController.php
public function queryUsers(Request $request)
{
    $query = $request->input('q_user');
    $res = User::where('username', 'LIKE', "%$query%")->take(10)->get();
    if ($res->isEmpty()) {
        // You can return what you want a.k.a. 404 it use by typeahead templates empty.
        $usersArray = [];
    } else {
        // This will only send the id, username to avoid that users can view all the rows from selected user table
        // But you can use protected $hidden = []; in model too.
        foreach ($res as $index => $user) {
            $usersArray[$index] = [
                'id'          => $user->id,
                'username'    => $user->username
            ];
        }
    }
    return response()->json($usersArray);
}
  • app.js
var users = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.whitespace('username'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote:{
    url: '{!! route('search.query_users') !!}'+'?q_user=%QUERY',
    wildcard: '%QUERY'
  }
});
var users_typeahead = $("#username").typeahead({
  hint: true,
  highlight: true,
  minLength: 2,
  classNames: {
    menu: 'typeahead-content',
    highlight: 'typeahead-highlight',
    cursor: 'typeahead-cursor'
  }
  }, {
  source: users.ttAdapter(),
  name: 'Users_list',
  displayKey: 'username',
  templates: {
  empty: [
    '<div class="typeahead-notfound">Not Found!</div>'
  ],
    suggestion: function (data) {
      return '<div class="typeahead-suggestion">'+ data.username +'</div>'
    }
  }
});
// Litle hack for Materializecss bug with label.
users_typeahead.unwrap();
        
/* Extra this is Event handle when selected.
$('#username').bind('typeahead:selected', function(obj, datum, name) {
  $('#firstname').val(datum.firstname);
  // Update label for Materializecss.
  Materialize.updateTextFields();
});
*/
  • app.css (It work for me) If it not work you need to make your own css style.
.twitter-typeahead {
    display: inline !important;
}

.typeahead-content {
    box-shadow: 0 1px 2px rgba(0,0,0,.26);
    background-color: #fff;
    cursor: pointer;
    margin-top: -15px;
    min-width: 100px;
    width: 100%;
    max-height: 200px;
    overflow-y: auto;
    position: absolute;
    white-space: nowrap;
    z-index: 1001;
    will-change: width,height;
}

.typeahead-highlight {
    font-weight: 900;
}

.typeahead-suggestion {
    padding: 5px 0px 10px 10px;
}

.typeahead-suggestion:hover {
    background-color: #42A5F5;
    color: #FFF;
}

.typeahead-notfound {
    cursor:not-allowed;
    padding: 5px 0px 10px 10px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment