How to load a value into a DIV after selecting an option in the dropdownlist of an input text that uses Typeahead and Ajax?

Asked

Viewed 356 times

0

Hello! I am developing a project where I am using the plugin Bootstrap Twitter-Typeahead where I load values inside an input text. The page I am developing has 2 fields:

1. An input text field whose id is "#products" and that loads values from a column in Mysql;

2. And a div whose id is "#image" and that in this case I would like to see a value related to the option selected in the input text.

I tried to find some questions similar to my doubt but could not find a correct way to do it:

  1. Load value in input text after selecting value in select Codeigniter
  2. when selecting a value from a select, a div appears
  3. Load input text after select

First, it follows the structure of my table (products) in Mysql:

id | nomeProduto    | categoriaFK | imagem
---------------------------------------------
01 | Tenis Nike     | 1           | 001
02 | Camisa Adidas  | 2           | 002
03 | Sapato Kildare | 1           | 003

Note: The column "categoriaFK" is a foreing Key within the table "products"

Below follows the html code that displays the input field "#products" and the div "#image":

<!DOCTYPE html>
<html>
 <head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js"></script>  
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
 
</head>
 
<body>
<br/>
  <div class="container">
   <h2 align="center">Typeahead with Ajax PHP</h2>
   <br/>
   <div class="row">

   <div class="col-md-4">
   <label>Produto</label>
   <input type="text" name="produtos" id="produtos" class="form-control input-lg" autocomplete="off" placeholder="Type Country Name" />
   </div>

   <div class="col-md-4">
   <label>Imagem</label>
   <div id="imagem" name="imagem"></div>
   
   </div>
  </div>
  </div>

 </body>
</html>

Below, the Ajax script code that sends a request to php code (fetch php.):

<script>
$(document).ready(function(){
 
 $('#produtos').typeahead({
  source: function(query, result)
  {
   $.ajax({
    url:"fetch.php",
    method:"POST",
    data:{query:query},
    dataType:"json",
    success:function(data)
    {
     result($.map(data, function(item){
      return item;
     }));
    }
   })
  },
  afterSelect: function (data) {

      $('#imagem').html(data);
         
    },    
 });
 
});
</script>

Below, the php code that sends the result of the request to Ajax:

<?php
//fetch.php
include 'dbConfig.php';
$request = mysqli_real_escape_string($db, $_POST["query"]);
$query = "
 SELECT * FROM produtos WHERE nomeProduto LIKE '%".$request."%'
";

$result = mysqli_query($db, $query);

$data = array();

if(mysqli_num_rows($result) > 0)
{
 while($row = mysqli_fetch_assoc($result))
 {
  $data[] = $row["nomeProduto"];
  $data[] = $row["imagem"];
 }
 echo json_encode($data);
}

?>

As you can see in the above code, I inserted into the typeahead script a code that runs after the value is selected within the input text #products as below:

afterSelect: function (data) {

      $('#imagem').html(data);
         
    },    

In this case every time I select a value inside the input text it shows that same value inside the div #image but what I would like to do is to show the value of the column "image" which is related to the value "productName" inside the picture div and not the value of the column "productName".

How can I proceed? Thank you.

1 answer

1


Instead of using $.map, use $.each to iterate the returned JSON, creating an array with the product names and populating an object with a key related to the image name, for example:

{
   "Tenis Nike": "001"
}

To do this create the two objects inside the function .ready:

$(document).ready(function(){
   var nomes = []; // cria a array
   var lista = {}; // cria o objeto
   ...

In the success you use the $.each to popular the two objects created above:

success:function(data){
   $.each(data, function(idx, item){
      // verifica se já consta na array e insere
      if(!~nomes.indexOf(item.nomeProduto)) nomes.push(item.nomeProduto);
      lista[item.nomeProduto] = item.imagem;
   });
   return result(nomes);
}

In the afterSelect you pull from the object lista the value of the key containing the product name, which corresponds to the image value:

afterSelect: function (data) {
   $('#imagem').html(lista[data]);
},
  • Hello Sam. Thank you for your feedback. I adapted your solution and in the Google Chrome console I got the following reply: bootstrap3-typeahead.min.js:1 Uncaught TypeError: Cannot read property 'toLowerCase' of undefined at Typeahead.matcher (bootstrap3-typeahead.min.js:1) at bootstrap3-typeahead.min.js:1 at Function.grep (jquery.min.js:2) at Typeahead.process (bootstrap3-typeahead.min.js:1) at e (jquery.min.js:2) at Object.success (index.php:50) at i (jquery.min.js:2) at Object.fireWith [as resolveWith] (jquery.min.js:2) at A (jquery.min.js:4) at XMLHttpRequest.<anonymous> (jquery.min.js:4)

  • Do you think it might be some conflict with the Typeahead plugin’s Cdn? Anyway thank you for your attention :)

  • 1

    Do as follows: comment on the line dataType:"json", and puts at the beginning of the Function of the Success a console.log(data);... should give an error but should also show a JSON... glue here the JSON that returns

  • 1

    type a name in the input to return

  • Okay, thank you. The console reported so: Uncaught TypeError: Cannot use 'in' operator to search for 'length' in ["Tenis Nike","01"]&#xA; at w (jquery.min.js:2)&#xA; at Function.each (jquery.min.js:2)&#xA; at Object.success (index.php:46)&#xA; at i (jquery.min.js:2)&#xA; at Object.fireWith [as resolveWith] (jquery.min.js:2)&#xA; at A (jquery.min.js:4)&#xA; at XMLHttpRequest.<anonymous> (jquery.min.js:4)

  • 1

    previously not shown the JSON?

  • Oh yes, sorry. In case before this error appears this line of code: ["Tênis Nike","01"]and then the above error appears below JSON. Would that be it? Thank you.

  • 1
  • 1

    Thanks for your attention Sam. I adapted your solution by fixing php script to send the results in JSON. that way it worked: {$data[] = $row; } header("Content-type: application/json; charset=utf-8"); &#xA; echo json_encode($data);&#xA; exit();

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.