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
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.