Autocomplete textbox with Vue.js PHP and MySQL

Autocomplete textbox with Vue.js PHP and MySQL

 

By adding autocomplete to a textbox makes it easier to search for an item. It displays a suggestion list based on the input in the textbox.

I am using the Axios package for loading suggestions.

In this tutorial, I show how you can add autocomplete textbox using a custom component in Vue.js. I am using PHP to fetch data from the MySQL database and return a response for suggestions.


 

1. Table structure

Create users table and added some records.

CREATE TABLE `users` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `username` varchar(80) NOT NULL,
  `fullname` varchar(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. Configuration

Create a config.php for the database connection.

Completed Code

<?php

$host = "localhost"; /* Host name */
$user = "root"; /* User */
$password = ""; /* Password */
$dbname = "tutorial"; /* Database name */

$con = mysqli_connect($host, $user, $password,$dbname);
// Check connection
if (!$con) {
  die("Connection failed: " . mysqli_connect_error());
}

3. HTML

You can download the Axios package from here or you can use CDN.

<script src='https://unpkg.com/axios/dist/axios.min.js'></script>

Create <div id='myapp' > container.

Create two vueauto-complete components. Defined model to read the selected item value from the suggestion list and @input event for performing action after item selection.

Display the value of the model in <p>.

Completed Code

<!DOCTYPE html>
<html>
<head>
   <title>Autocomplete textbox with Vue.js PHP and MySQL</title>

   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
   <!-- CSS -->
   <link rel="stylesheet" type="text/css" href="style.css">

   <!-- Script -->
   <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
   <script src='https://unpkg.com/axios/dist/axios.min.js'></script>

</head>
<body>
   <div id='myapp' >

      <!-- Auto complete element 1 -->
      <vueauto-complete v-model="userid1" @input="handleInput1()"></vueauto-complete>

      <!-- Selected item -->
      <p><b>Selected UserID - {{ userid1 }}</b> </p>

      <br>
      <!-- Auto complete element 2 -->
      <vueauto-complete v-model="userid2" @input="handleInput2()"></vueauto-complete>

      <!-- Selected item -->
      <p><b>Selected UserID - {{ userid2 }}</b> </p>

   </div>

</body>

</html>

4. CSS

Create style.css file.

Completed Code

.autocompleteel,.autocompleteel .suggestionlist{
   width: 300px;
}

.autocompleteel input[type=text]{
   width: 100%;
   padding: 5px;
}

.suggestionlist{
   position: absolute;
}

.suggestionlist ul{
   width: 100%;
   background: whitesmoke;
   list-style: none;
   margin: 0;
   padding: 5px;
}

.suggestionlist ul li{
   background: white;
   padding: 4px;
   margin-bottom: 1px;
}

.suggestionlist li:not(:last-child){
   border-bottom: 1px solid #cecece;
}

.suggestionlist ul li:hover{
   cursor: pointer;
   background: whitesmoke;
}

5. PHP

Create ajaxfile.php file for handling AJAX requests and return response.

Assign $_GET['search'] to $search variable.

If $search is not empty then fetch 5 records from the users table where $search exists on the fullname field.

Loop on the fetched records and initialize $data_arr Array with id and name keys.

Pass $row['id'] to id key and $row['name'] to name key.

Return $data_arr Array in JSON format.

Completed Code

<?php
include "config.php";

if(isset($_GET['search'])){
   $search = mysqli_real_escape_string($con,trim($_GET['search']));

   $data = array();
   if(!empty($search)){

      // Fetch 5 records
      $result = mysqli_query($con,"select * from users where fullname like '%".$search."%' limit 5");

      while ($row = mysqli_fetch_array($result)) {
         $data[] = array(
            "id" => $row['id'],
            "name"=>$row['fullname']
         );
      }
   }

   echo json_encode($data);
   exit;
}

6. Script

Create Component –

Create a vueauto-complete component for adding autocomplete textbox.

data() – Define searchText and suggestiondata. Use searchText for v-model and suggestiondata to store suggestion list.

template – With the template option set the component template.

Create a textbox element. Set v-model='searchText' and define @keyup='loadSuggestions' event to load the suggestion data.
Display <div class='suggestionlist' > if suggestiondata is not empty.

Using <ul > to display the item list by looping on the suggestiondata. Define @click='itemSelected(index)' on the <li>.

methods – Define two methods –

  • loadSuggestions() – This method called when keyup event trigger on the textbox.

Empty the suggestiondata and send AJAX request to 'ajaxfile.php' if searchText is not empty. Pass search: this.searchText as data.
On successful callback assign response.data to el.suggestiondata.

  • itemSelected() – This method called when an item is selected from the suggestion list.

Read id and name. Assign name to this.searchText and empty the this.suggestiondata.

Emit an event to the parent component once the value of the input changes.

this.$emit("input", id);

I passed id as the second parameter. You can change it according to your requirement.


Initialize Vue –

Initialize Vue on #myapp.

Create two data variables userid1 and userid2. Both variables use as a model variable in the component.

Define two methods – handleInput1 and handleInput2.

A method called when an item selected from the suggestion list. Here, I am just printing the selected value in the console. You can use this method to perform some action.

Completed Code

Vue.component('vueauto-complete', {
   data: function () {
      return {
         searchText:'',
         suggestiondata:[]
      }
   },
   template: `<div class='autocompleteel' > 
     <div >
        <input type='text' @keyup='loadSuggestions' placeholder='Enter some text' 
v-model='searchText' 
> <br> 
        <div class='suggestionlist' v-if="suggestiondata.length" >
          <ul > 
            <li v-for= '(item,index) in suggestiondata' @click='itemSelected(index)' > 
{{ item.name }} 
            </li> 
          </ul>
        </div> 
     </div>
     </div>`, 
   methods: {
      loadSuggestions: function(e){
         var el = this;
         this.suggestiondata = [];

         if(this.searchText != ''){

            axios.get('ajaxfile.php', {
               params: {
                  search: this.searchText
               }
            })
            .then(function (response) {
                el.suggestiondata = response.data;
            });

         } 

      },
      itemSelected: function(index){
         var id = this.suggestiondata[index].id; 
         var name = this.suggestiondata[index].name;

         this.searchText = name;
         this.suggestiondata = [];

         this.$emit("input", id);

      }

   },
})

var app = new Vue({
   el: '#myapp',
   data: {
      userid1: 0,
      userid2: 0
   },
   methods: {
      handleInput1: function(){
         console.log("value : " + this.userid1);
      },
      handleInput2: function(){
         console.log("value : " + this.userid2);
      }
   }
})

7. Demo

View Demo


8. Conclusion

You can use this component multiple times on the same page. With your defined model read the selected item value.

In the example, I assigned the user id to the model after item selection. You can modify it according to your requirement and with the input event you can perform an action.



Comments