jcadima
11/1/2019 - 4:55 PM

Laravel implementation of typeahead search by title or sku

https://stackoverflow.com/questions/14150216/adding-label-value-and-picture-in-bootstraps-typeahead
https://jsfiddle.net/geghamk/59eranrc/3/


DB fields: id | title | sku | product_image

Web Route:
// AUTOCOMPLETE SEARCH PRODUCTS
Route::get('/autocomplete/search', 'Front\\ProductsController@search')->name('autocomplete.search');


HTML:
<div class="form-group">
    <label class="">Search by Product Title *</label>
    <div class="form-group">
        <input type="text"  name="title" class="form-control input-lg product_search" placeholder="Enter Product Title">
    </div>
</div>

<strong>Or </strong>

<div class="form-group">
    <label class="">Search by Product SKU *</label>
    <div class="form-group">
        <input type="text" name="sku"  class="form-control input-lg product_search" placeholder="Enter Product SKU">
    </div>
</div>

<?php
// Controller method:
public function search()
{
    return json_encode(Product::all() );
}

<script>
// JS bottom of Page
function productSearch() {
    $.get("{{ route('autocomplete.search') }}", function(data) {
        // (1) Products Array
        var productNames = [];

        // (2) Get row of products first, with '#' delimiter
        $.each(data, function(index, product) {
            productNames.push(product.title + "#" + product.product_image + "#" + product.sku);
        });
        // console.log('ProductNames: ' + productNames) ;

        $( '.product_search' ).typeahead({
            minLength: 2,
            highlight: true,
            source: productNames,
            autoSelect: false,
            // displayText() is not needed

            highlighter: function (item) {  // source is productNames, this is passed as 'item'
                let parts = item.split('#') ; // (3) split product rows
                // ProductNames:
                // Test Product 001#80.png#TEST-001,
                // Test Product 002#80.png#TEST-002,
                // Test Prod 3#80.png#TEST-003,
                // Baron Series SD-AZ001#5dbb5bd23119d_single_basin2.jpg#BAR-001
                console.log('part0: ' + parts[0]) ;
                console.log('part1: ' + parts[1]) ;
                console.log('part2: ' + parts[2]) ;

                console.log('item in highlighter: ', item) ;

                return '<img src="/images/' + parts[1]  + '">' + parts[0] ; // (4) highlight product Image + Title
            },

            // (5) Filtered Text that is returned to the input field excluding the image shown in highlighter(step 4)
            updater: function(selectedTitle) {
                var title = selectedTitle.split('#')[0];
                return title;
            }

        });
    },'json');
}

</script>