Bootstrap Typeahead with AJAX source (not working)

7.3k views Asked by At

I'm trying to implement a search bar dropdown using bootstrap v3.0.0 with typeahead.js. My search bar will take a student's firstname and lastname. I'm using a MYSQL database which consists of a table called practice with afirstname, alastname, aid as columns. The search bar should not only contain the firstname and lastname in the dropdown, but also the id associated with it in a second row. I've read all the examples on the typeahead.js page and I'm unable to do it with ajax call.

Below is the code of my index.php

JS

<script type="text/javascript">

      $(document).ready(function() {
        $('.cr.typeahead').typeahead({
          source:  header: '<h3>Select</h3>',
          name: 'accounts',

          source: function (query, process) {
                return $.getJSON(
                    'localhost/resultly/source.php',
                    { query: query },
                    function (data) {
                        return process(data);
                    });
        });
      });
    </script>

HTML:

     <body>
     <div class="container">

     <br/><br/>

    <input type="text" name="query" class="form-control cr typeahead" id="firstname" />

    <br/><br/>



    </div>
    </body>

Code for source.php : This should return the firstname and lastname from my database in the form of a json string or object?

<?php 
    $query = $_POST['query'];

    try {


        $conn = new PDO('mysql:host=localhost;dbname=practice','root','');
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


        $stmt = $conn->prepare("SELECT * FROM actualtable WHERE afirstname LIKE '%($query)%'");
        $stmt->execute();





    } 

    catch (PDOException $e) {
        echo 'ERROR:' . $e->getMessage();
    }



    foreach ($stmt as $row) {
            $afirstname[] = $row['afirstname'];
            $alastname[] = $row['alastname'];


    }

    echo json_encode($afirstname);
    echo json_encode($alastname);


 ?>

result: http://oi41.tinypic.com/50moi1.jpg

Nothing shows up. I've tried adding a prefetch:

 prefetch: {
                url: 'localhost/resultly/source.php',
                filter: function(data) {
                r1 = [];
                for (var i = 0;  i < data.length;  i++) {
                r1.push({
                value: data[i].afirstname,
                tokens: [data[i].afirstname, data[i]alastname],
                afirstname: data[i].afirstname,
                alastname: data[i].alastname,
                template: '<p>{{afirstname}} - {{alastname}}</p>',
                });
            }
            return r1;
        }
    }

Please do provide a solution or an example which I could refer.

Update:

The source.php should return a list of json encoded data. I debugged by looking at the output that the source.pho created. What I did wrong was whenever I was supposed to put a url I did localhost/source.php instead of just source.php.

Solution provided by Bass Jobsen works and now I have run into another problem.

I'm using if(isset($_POST['query'])) { $q_uery = $_POST['query']; $query = ucfirst(strtolower($q_uery))};

to take the user's data and use it for searching logic $stmt = $conn->prepare("SELECT * FROM actualtable WHERE afirstname LIKE '%($query)%'");

The updated source.php is http://pastebin.com/T9Q4m10g

I get an error on this line saying Notice: Undefined variable: stmt I guess the $query is not being initialized. How do I get this to work. Thanks.

Update 3

I used prefetch: instead of 'remote:' that did all the matching.

2

There are 2 answers

7
Bass Jobsen On BEST ANSWER

Your return is not correct:

echo json_encode($afirstname);
echo json_encode($alastname);

See for example Twitter TypeAhead.js not updating input

Try echo json_encode((object)$stmt);, see: typeahead.js search from beginng

Update

I tried echo json_encode((object)$stmt);still doesn't work.

Do you use any kind of debugging? What does? source.php return? Try to follow the steps from typeahead.js search from beginng without the filter.

html:

<div class="demo">
  <input class="typeahead" value="" type="text" spellcheck="off" autocomplete="off" placeholder="countries">
</div>

javascript:

$('.typeahead').typeahead({                                
        remote: 'http://testdrive/source.php?q=%QUERY',
        limit: 10                                                                   
        });

php (source.php):

<?php
$people = array();
$people[] = array("lastname"=>"Inaw",
    "firstname"=>"Dsajhjkdsa");
$people[] = array("lastname"=>"Dsahjk",
    "firstname"=>"YYYsgbm");
$people[] = array("lastname"=>"Dasjhdsjka",
    "firstname"=>"JHJKGJ");

$datums = array();  
foreach($people as $human)
{
    $datums[]=(object)array('value'=>$human['firstname'],'tokens'=>array($human['firstname'],$human['lastname']));
}     

echo json_encode((object)$datums);

This should work

update2

Thanks, it worked. How do I display 2 or more 'value'?

add some values to your datums in source.php:

foreach($people as $human)
{
    $datums[]=(object)array
    (
        'value'=>$human['firstname'],
        'tokens'=>array($human['firstname'],$human['lastname']),
        'firstname'=>$human['firstname'],
        'lastname'=>$human['lastname']
    );
}

firstname and lastname now are field you csn use in your templates

Add a template and template engine to your javascript declaration:

$('.typeahead').typeahead({                                
        remote: 'http://testdrive/source.php?q=%QUERY',
        limit: 10,
          template: [ 
          '<p>{{firstname}} - {{lastname}}</p>'    
          ].join(''),
          engine: Hogan 

        });

The above make use of https://github.com/twitter/hogan.js. You will have to include the template engine by javascript, for example:

<script src="http://twitter.github.io/typeahead.js/js/hogan-2.0.0.js"></script>

0
Ankit Mori On

It is working for me. please follow below step.

Please add below Js and give proper reference.

bootstrap3-typeahead

--- Ajax Call ----

$("#cityId").keyup(function () {
    var al = $(this).val();
    $('#cityId').typeahead({
        source: function (valuequery, process) {
            var states = [];
            return $.ajax({
                url: http://localhost:4000/GetcityList,
                type: 'POST',
                data: { valueType: "", valueFilter: valuequery },
                dataType: 'JSON',
                success: function (result) {
                    var resultList = result.map(function (item) {
                        states.push({
                            "name": item.Value,
                            "value": item.Key
                        });
                    });

                    return process(states);
                }
            });
        },
    });
});

---- Cs Code ---

public JsonResult SearchKeyValuesByValue(string valueType, string valueFilter)
        {
            List<KeyValueType> returnValue = SearchKeyValuesByValue(valueType, valueFilter);
            return Json(returnValue);
        }

Auto suggest of Bootstrap typehead will get accept only "name" and "value" so create reponse accordinly