How to Make an Autocomplete With Select2 And Laravel?

Autocomplete is a very cool feature to have on a webpage. It allows us to select one of the many values from already saved values. With Laravel it becomes easy to code Autocomplete using Ajax and select2. Laravel facilitates us to populate database for values and search them fast.

Enough talking lets start writing some code.

1. Installing Laravel

To install the new version of Laravel run following command into your terminal or command prompt.

composer create-project --prefer-dist laravel/laravel shop

2. Database Configuration

In order to configure the database we need to add these credentials in my .env file.

  • Database name
  • Database password
  • Database username
  • Database host

In order to do so, we will add the following lines in the .env file.

DB_HOST=localhost 
DB_DATABASE=shop_db 
DB_USERNAME=root 
DB_PASSWORD=secret

3. Creating model and migration

First I will create a model and migration by running this command.

php artisan make:model Product -m

-m will create a migration file in your migration folder.

After running that command I will add this code in the migration file mentioned below:

/database/migrations/2021_01_01_122345_create_products_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->integer('price');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Now we will run the migration using the following command.

php artisan migrate

If you want to read about Laravel Migrations in depth, visit this link.

https://laravel.com/docs/8.x/migrations

If you have any questions regarding documentation or you cannot understand anything in code feel free to leave a comment.
Back to the code, let’s add below code in our Product model.

/app/Product.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
     protected $fillable = [
        'name', 'price',
    ];
}

4. Creating products

We can also create few products in our database to search from them. These products will be very close to real products. Laravel offers us something called seeders for that purpose. Let’s create a seeder.

php artisan make:seeder ProductsSeeder

then we have to run following command, so that Laravel gets information about new Seeder.

composer dump-autoload

now we have to add following code in our ProductsSeeder.
database/seeds/ProductsSeeder.php

<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
class ProductsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
	    foreach (range(1,10) as $index) {
		    DB::table( 'products' )->insert( [
			    'name'  => Str::random( 10 ),
			    'price' => rand( 100, 500 )
		    ] );
	    }
    }
}

Then we need to run following command to add records in our product table.

php artisan db:seed --class=ProductsSeeder

5. Creating Routes

This is how we can create routes to interact with Laravel Controller. 
routes/web.php

Route::get('select2', '[email protected]');
Route::get('/select2-autocomplete-ajax', '[email protected]');

6. Creating Controller

This is how we can run the command to create a ProductController.

php artisan make:controller ProductsController

Adding the code in PostController. 

/app/Http/Controllers/ProductController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;

class Select2AutocompleteController extends Controller
{
    /**
    * Show the application layout.
    *
    * @return \Illuminate\Http\Response
    */
    public function index()
    {
    	return view('select2.index');
    }
    /**
    * Show the application dataAjax.
    *
    * @return \Illuminate\Http\Response
    */
    public function dataAjax(Request $request)
    {
    	$data = [];

        if($request->has('q')){
            $search = $request->q;
            $data =Product::select("id","name")
            		->where('name','LIKE',"%$search%")
            		->get();
        }
        return response()->json($data);
   
}

7. Creating View

See how I will create a blade file and place Autoselect code in that. 
/resources/views/select2/index.blade.php

<!DOCTYPE html>
<html>
<head>
<title>Laravel - Dynamic autocomplete search using select2 JS Ajax - Laramatic.com</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
</head>
<body class="bg-dark">
<div class="container mt-4">
    <div class="row">
        <div class="col-md-8 offset-md-2">
            <div class="card">
                <div class="card-header">
                    <h4>Laravel - Dynamic autocomplete search using select2 JS Ajax</h4>
                </div>
                <div class="card-body">
                    <div class="row">
                        <div class="col-md-12">
                            <select class="itemName form-control" name="itemName"></select>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script type="text/javascript">
    $('.itemName').select2({
        placeholder: 'Select an item',
        ajax: {
            url: '/select2-autocomplete-ajax',
            dataType: 'json',
            delay: 250,
            processResults: function (data) {
                return {
                    results: $.map(data, function (item) {
                        return {
                            text: item.name,
                            id: item.id
                        }
                    })
                };
            },
            cache: true
        }
    });
</script>
</html>

Now, we will run this command to launch Laravel site.

php artisan serve

If you visit this URL you can see output like this.
http://localhost:8000/select2

8. Trouble Shooting

  • Why my select2 is not rendering?
  • We can watch console for errors.
  • We can check jQuery is included.

We can check that the database is connected and the values are in product table in database. If you like this post, make sure to share it with others.