Make Dropdown with Search box with vue-select – Vue.js

HTML <select > element doesn’t provide search feature.

In VueJS you can use vue-select component to add a customizable and responsive select element. It allows us to load options with and without AJAX.

In this tutorial, I will explain both ways to load options in vue-select.

Make dropdown with search box with Vue-select - Vue.js


Contents

  1. Table structure
  2. Configuration
  3. HTML
  4. AJAX
  5. Script
  6. Demo
  7. Conclusion

1. Table structure

Create countries table.

CREATE TABLE `countries` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` 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

I am using CDN to include CSS and JS script for vue-select. It is available on GitHub. You can install it in your project.

Include vue-select.css in the <head > section.

<link rel="stylesheet" href="https://unpkg.com/vue-select@3.0.0/dist/vue-select.css">

I am using Axios package to send AJAX request. I have stored in the project directory. You can download it from here.

Include vue, vue-select, and axios js script at the end of <body>. Also, included script.js file. In this file write Vue script to load vue-select component and fetch options.

<script src="https://unpkg.com/vue@latest"></script> 
<script src="https://unpkg.com/vue-select@latest"></script> 
<script src="axios-master/dist/axios.min.js"></script> 
<script src="script.js" ></script>

vue-select options and methods – 

v-select has following options which I used in the example –

  • :options – Load options list. Require Array type value.
  • label – If :options has an array of objects then you need to specify the key name which use for the label otherwise the list label not show e.g. – { id: 1, name: Yogesh }. Here, use name key for the label.

NOTE – It is not require for single dimensional Array e.g. – [ yogesh, visual, sonarika ].

  • :reduce – if :options has an array of objects. In this case when you read selected option value then it contains the whole object. You need to read required key from the object.

With :reduce you can return the single key value. e.g. { id: 1, name: Yogesh }.

v-select methods which I used in the example –

  • @search – This event trigger when updating the search text. Use this for load options using AJAX.
  • @input – This event trigger on value state change. You can use this method to perform action based on option selection.

HTML

Create two <v-select >

  • In the 1st v-select load options without AJAX and
  • In the 2nd v-select load options with AJAX.

Pass users_options in :options on the 1st v-select and add v-model="user". Similarly, pass country_options in :options on the 2nd v-select, add v-model="country", use :reduce="country => country.id" to get the selected option id key as value.

With @search load options using AJAX and with @input perform action on option selection.

Completed Code

<!DOCTYPE html>
<html>
<head>
  <title>Make Dropdown with Search box with vue-select - Vue.js</title>

  <link rel="stylesheet" href="https://unpkg.com/vue-select@3.0.0/dist/vue-select.css">
  <style type="text/css">

  #app {
      max-width: 500px;
      margin-top: 10px;
  }
  </style>
</head>
<body>

   <div id="app">

     <table width='100%' >
       <thead>
         <tr>
            <th width='10%'></th>
            <th width='60%'></th>
            <th width='30%'>Selected Value</th>
         </tr>
       </thead>
       <tbody>
         <tr>
            <td>Users</td>
            <td>
               <v-select 
                  v-model="user" 
                  :options="users_options">
               </v-select>
            </td>
            <td align='center' v-text="user"></td>
         </tr>
         <tr>
            <td>Countries</td>
            <td>
              <v-select label="name" 
                 v-model="country" 
                 :reduce="country => country.id" 
                 :options="country_options" 
                 @search="fetchOptions" 
                 @input="selectedOption" >
              </v-select>
            </td>
            <td align='center' v-text="country"></td>
         </tr>
       </tbody>

     </table>

   </div>

   <!-- Script -->
   <script src="https://unpkg.com/vue@latest"></script>
   <script src="https://unpkg.com/vue-select@latest"></script>
   <script src="axios-master/dist/axios.min.js"></script>

   <script src="script.js" ></script>
</body>
</html>

4. AJAX

Create ajaxfile.php file.

Check if $_GET['search'] is set or not. If set then assign $_GET['search'] to $search variable.

Fetch records from the countries table and use $search to search on the name field.

Loop on the fetched records. Initialize $return_arr Array with id and name keys. Pass $id in 'id' key and $name in 'name' key.

NOTE – You can change the key names according to your requirement.

Return $return_arr Array in JSON format.

Completed Code

<?php

// configuration
include 'config.php';

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

// Fetch records
$query = 'SELECT * FROM countries where name like "%'.$search.'%" ';
$result = mysqli_query($con,$query);

$response_arr = array();

while($datarow = mysqli_fetch_assoc($result)){

   $id = $datarow['id'];
   $name = $datarow['name'];

   $response_arr[] = array(
     "id"=> $id,
     "name" => $name
   );

}

echo json_encode($response_arr);
exit;

5. Script

Create script.js file.

Register the v-select component.

Created 4 data variables –

  • user – Model variable of 1st v-select. Use to retrieve selected option value.
  • country – Model variable of 2nd v-select. Use to retrieve selected option value.
  • users_options – Stored user names in the Array. This use for options load for 1st v-select.
  • country_options – An empty array. This use for options load for 2nd v-select.

Created 2 methods –

fetchOptions – This option trigger on @search event trigger. It has 2 parameters –

  • search – The current input text.
  • loading – Boolean parameter to toggle the loading state.

Send AJAX GET request using Axios. Pass search as a parameter { search: search }. On successful callback assign response.data in country_options.

selectedOption – It has 1 parameter that stores selected option value. I am just displaying value using console.log(). You can use this to perform an action based on value.

Completed Code

Vue.component('v-select', VueSelect.VueSelect)

new Vue({
   el: '#app',
   data: {
     user: "",
     country: 0,
     users_options: [
       "Yogesh singh",
       "Sunil singh",
       "Sonarika bhadoria",
       "Akilesh sahu",
       "Mayank patidar"
     ],
     country_options: []
   },
   methods: {
      fetchOptions: function(search,loading){

        var el = this;

        // AJAX request
        axios.get('ajaxfile.php', {
           params: {
              search: search, 
           }
        })
        .then(function (response) {

           // Update options
           el.country_options = response.data; 

        });

      },
      selectedOption: function(value){
         console.log("value : " + value);
      }
   }
})

6. Demo

View Demo


7. Conclusion

Use :options to load the options list in the select box. With @input event you can execute your action according to the option selected.

You can learn more about this component from here.

If you found this tutorial helpful then don't forget to share.

Leave a Comment