Search Box with Auto Suggest Links Items Tutorial using PHP and jQuery

This is a simple tutorial that tackles about creating a Search Box with AutoSuggest Links Items. This tutorial uses HTM, PHP, MySQL Database, JavaScript, jQuery, and Ajax. The tutorial code will help you to understand and to have an idea or knowledge of how to create the said web application feature for your future project. This kind of feature is commonly used when adding a search feature that matches the keywords on multiple database tables and columns.

About the Application

Our goal in this tutorial is to create a simple web application that has a Search Box that allows users to enter a certain keyword to find data on the database. The Search box has a suggestion list every time the user enters a new character in the text fields. The Suggestion List will display all suggested links of the data that contain or matches the given keyword. Suggestion Items will only display 10 items maximum. Next, when the user will press the "Enter key", the application will list all the list links where its data content contains the given keyword. The search suggestion item and result will have 2 possible links of page which are the Author's Details Page Link and Post Details Link.

Getting Started

Download the following:

Compile the downloaded libraries into a directory that serve as the location of your source code. Then, open your XAMPP's Control Panel and start Apache and MySQL.

Creating the Database

Download the provided source code zip file below this article to have a copy to database I used for this web application.

Open your XAMPP's PHPMyAdmin and create a new database naming dummy_data. Next, navigate the page into the Import Tab and import the provided db file known as dummy_data.sql inside the database directory.

Creating The Database Connection

The following code is the PHP Script that configures the web application's database connection. Copy and Paste the code into a text-editor and save it as connection.php.

  1. <?php
  2.         $host="localhost";
  3.         $username="root";
  4.         $password="";
  5.         $dbname="dummy_data";
  6.  
  7.         $conn = new mysqli($host, $username, $password, $dbname);
  8.         if(!$conn)
  9.             die("Database Connection Failes. Error:". $conn->error);

Creating the Interface

The following codes is the script that contains the HTML Scripts for the template of the web application. It also contains the PHP Scripts that queries the data from the database. Save Code according the file name given above each scripts.

index.php

This contains the script of the application main template.

  1. <?php session_start(); ?>
  2. <?php require_once('connection.php') ?>
  3. <?php
  4. $page = isset($_GET['page']) ? $_GET['page'] : "home";
  5. ?>
  6. <!DOCTYPE html>
  7. <html lang="en">
  8.  
  9. <head>
  10.     <meta charset="UTF-8">
  11.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  12.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  13.     <title>Search Box with AutoSuggest Links</title>
  14.     <link rel="stylesheet" href="./css/bootstrap.min.css">
  15.     <script src="./js/jquery-3.6.0.min.js"></script>
  16.     <script src="./js/bootstrap.min.js"></script>
  17.     <script src="./js/script.js"></script>
  18.     <style>
  19.          :root {
  20.             --bs-success-rgb: 71, 222, 152 !important;
  21.         }
  22.        
  23.         html,
  24.         body {
  25.             height: 100%;
  26.             width: 100%;
  27.             font-family: Apple Chancery, cursive;
  28.         }
  29.         .btn-info.text-light:hover,.btn-info.text-light:focus{
  30.             background: #000;
  31.         }
  32.         #search-suggestion {
  33.             position: absolute;
  34.             top: 2.4em;
  35.             left: 1em;
  36.             width: 90%;
  37.             z-index: 9;
  38.         }
  39.     </style>
  40. </head>
  41.  
  42. <body class="bg-light">
  43.     <nav class="navbar navbar-expand-lg navbar-dark bg-primary bg-gradient" id="topNavBar">
  44.         <div class="container">
  45.             <a class="navbar-brand" href="https://sourcecodester.com">
  46.             Sourcecodester
  47.             </a>
  48.         </div>
  49.     </nav>
  50.     <div class="container py-3" id="page-container">
  51.         <h3>Search Box with AutoSuggest Links</h3>
  52.         <hr>
  53.         <div class="content">
  54.             <?php include("{$page}.php"); ?>
  55.         </div>
  56.     </div>
  57. </body>
  58. <?php $conn->close(); ?>
  59. </html>
home.php

This script contains the search box, suggestion list container, and the search result list.

  1. <div class="col-md-12">
  2.     <div class="row justify-content-center">
  3.         <div class="col-md-6 position-relative">
  4.             <div class="input-group mb-3">
  5.                 <input type="text" id="search" class="form-control" aria-label="Search Here" placeholder="Search here..." value="<?php echo isset($_GET['search']) ? $_GET['search'] : "" ?>">
  6.                 <span class="input-group-text" id="empty_search"><a href="javascript:void(0)" class="text-decoration-none text-dark fw-bolder">X</a></span>
  7.             </div>
  8.             <div id="search-suggestion" class="d-none">
  9.                 <div class="list-group rounded-0" id="suggestion-list">
  10.                 </div>
  11.             </div>
  12.         </div>
  13.     </div>
  14.     <?php if(isset($_GET['search']) && urldecode($_GET['search']) != ''): ?>
  15.     <div class="row">
  16.         <div class="col-md-12">
  17.             <div class="fs-5 fw-bold text-info">Search Result for "<?php echo $_GET['search'] ?>" Keyword.</div>
  18.             <hr>
  19.             <div class="list-group rounded-0">
  20.             <?php
  21.                 $keyword = urldecode($_GET['search']);
  22.                 $sql_post = "SELECT p.*,a.first_name, a.last_name,CONCAT(a.first_name,' ',a.last_name) as `name`,a.email FROM `posts` p inner join `authors` a on p.author_id = a.id where CONCAT(a.first_name,' ',a.last_name) LIKE '%{$keyword}%' or CONCAT(a.last_name,' ',a.first_name) LIKE '%{$keyword}%' or a.email LIKE '%{$keyword}%' or p.title LIKE '%{$keyword}%' or p.description LIKE '%{$keyword}%' or p.content LIKE '%{$keyword}%' ";
  23.                 $qry_post = $conn->query($sql_post);
  24.  
  25.                 if($qry_post->num_rows > 0):
  26.                 while($row = $qry_post->fetch_assoc()):
  27.             ?>
  28.             <?php
  29.                 if(str_contains($row['name'],$keyword) == true || str_contains($row['last_name'] . ' '. $row['last_name'],$keyword) || str_contains($row['email'],$keyword)):
  30.             ?>
  31.                 <a href="./?page=author_details&id=<?php echo $row['author_id'] ?>" class="list-group-item list-group-item-action search-item mb-2 border-top shadow">
  32.                     <div class="fs-5 text-info"><?php echo $row['name'] ?></div>
  33.                     <hr>
  34.                     <small class="muted text-truncate"><i><?php echo $row['email'] ?></i></small>
  35.                 </a>
  36.             <?php endif; ?>
  37.             <?php
  38.                 if(str_contains($row['title'],$keyword) || str_contains($row['description'],$keyword) || str_contains($row['content'],$keyword)):
  39.             ?>
  40.                 <a href="./?page=post&id=<?php echo $row['id'] ?>" class="list-group-item list-group-item-action search-item mb-2 border-top shadow">
  41.                     <div class="fs-5 text-info"><?php echo $row['title'] ?></div>
  42.                     <hr>
  43.                     <div class="text-truncate"><small class="muted"><i><?php echo $row['description'] ?></i></small></div>
  44.                 </a>
  45.             <?php endif; ?>
  46.             <?php endwhile; ?>
  47.             <?php else: ?>
  48.                     <div class="list-group item text-center">No result.</div>
  49.             <?php endif; ?>
  50.             </div>
  51.         </div>
  52.     </div>
  53.     <?php endif; ?>
  54. </div>
author_details.php

The below code contains the script that outputs the Author Details Page Content.

  1. <?php require_once('connection.php'); ?>
  2. <?php
  3. $qry = $conn->query("SELECT *,CONCAT(first_name,' ',last_name) as `name` FROM `authors` where id = '{$_GET['id']}'");
  4. foreach($qry->fetch_assoc() as $k => $v){
  5.     $$k = $v;
  6. }
  7. ?>
  8. <div class="card shadow">
  9.     <div class="card-header">
  10.         <h5 class="card-title">Author Details</h5>
  11.     </div>
  12.     <div class="card-body">
  13.         <dl>
  14.             <dt class='text-info'>Author Name</dt>
  15.             <dd class="ps-4"><?php echo $name ?></dd>
  16.             <dt class='text-info'>Email</dt>
  17.             <dd class="ps-4"><?php echo $email ?></dd>
  18.             <dt class='text-info'>Birthday</dt>
  19.             <dd class="ps-4"><?php echo date('F d, Y',strtotime($birthdate)) ?></dd>
  20.         </dl>
  21.     </div>
  22. </div>
post.php

The below code contains the script that outputs the Post Details Page Content.

  1. <?php require_once('connection.php'); ?>
  2. <?php
  3. $qry = $conn->query("SELECT p.*,CONCAT(a.first_name,' ',a.last_name) as `author`FROM `posts` p inner join `authors` a on p.author_id = a.id where p.id = '{$_GET['id']}'");
  4. foreach($qry->fetch_assoc() as $k => $v){
  5.     $$k = $v;
  6. }
  7. ?>
  8. <div class="card shadow">
  9.     <div class="card-header">
  10.         <h5 class="card-title"><?php echo $title ?></h5>
  11.     </div>
  12.     <div class="card-body">
  13.         <h4><b>Description</b></h4>
  14.         <p><?php echo $description ?></p>
  15.        
  16.         <h4><b>Content</b></h4>
  17.         <p><?php echo $content ?></p>
  18.     </div>
  19.     <div class="card-footer d-flex justify-content-between">
  20.         <div>
  21.             <small><span class="text-muted">Author: <?php echo $author ?></span></small>
  22.         </div>
  23.         <div>
  24.             <small><span class="text-muted">Publish Date: <?php echo date('F d, Y',strtotime($date)) ?></span></small>
  25.         </div>
  26.     </div>
  27. </div>

Main Function

The following code are the scripts that queries the matches keyword to the data in the database. Save the script as search_api.php.

  1. <?php
  2. require_once('connection.php');
  3.  
  4. $keyword = $_POST['search'];
  5. $data=array();
  6.  
  7. $sql_post = "SELECT p.*,a.first_name, a.last_name,CONCAT(a.first_name,' ',a.last_name) as `name`,a.email FROM `posts` p inner join `authors` a on p.author_id = a.id where CONCAT(a.first_name,' ',a.last_name) LIKE '%{$keyword}%' or CONCAT(a.last_name,' ',a.first_name) LIKE '%{$keyword}%' or a.email LIKE '%{$keyword}%' or p.title LIKE '%{$keyword}%' or p.description LIKE '%{$keyword}%' or p.content LIKE '%{$keyword}%' ";
  8.  
  9. $qry_post = $conn->query($sql_post);
  10.  
  11. while($row = $qry_post->fetch_assoc()){
  12.     if(str_contains($row['name'],$keyword) == true || str_contains($row['last_name'] . ' '. $row['last_name'],$keyword)){
  13.         $data[] = array('link'=>"./?page=author_details&id=".$row['author_id'],
  14.                         'text'=>$row['name']);
  15.     }
  16.     if(str_contains($row['email'],$keyword) == true){
  17.         $data[] = array('link'=>"./?page=author_details&id=".$row['author_id'],
  18.                         'text'=>$row['email']);
  19.     }
  20.     if(str_contains($row['title'],$keyword) == true){
  21.         $data[] = array('link'=>"./?page=post&id=".$row['id'],
  22.                         'text'=>$row['title']);
  23.     }
  24.     if(str_contains($row['description'],$keyword) == true){
  25.         $data[] = array('link'=>"./?page=post&id=".$row['id'],
  26.                         'text'=>$row['description']);
  27.     }
  28.     if(str_contains($row['content'],$keyword) == true){
  29.         $data[] = array('link'=>"./?page=post&id=".$row['id'],
  30.                         'text'=>$row['content']);
  31.     }
  32. }
  33. shuffle($data);
  34. echo json_encode($data);

Lastly, the following script is a JavaScript code which holds the functions and scripts that displays the suggestion items, and some event function of the search box. Save the following script as script.js.

  1. function search_suggest($keyword = "") {
  2.     var max_suggest = 10;
  3.     var suggest_list = $('#suggestion-list')
  4.     suggest_list.html('')
  5.     $.ajax({
  6.         url: 'search_api.php',
  7.         method: 'POST',
  8.         data: { search: $keyword },
  9.         dataType: 'json',
  10.         error: err => {
  11.             console.log(err)
  12.             alert('An error occured while fetching suggested items')
  13.         },
  14.         success: function(resp) {
  15.             if (resp.length > 0) {
  16.                 resp = resp.slice(0, max_suggest)
  17.                 Object.keys(resp).map(k => {
  18.                     var item = resp[k]
  19.                     var a = $("<a class='list-group-item  list-group-item-action text-truncate suggest-item'>")
  20.                     a.attr('href', item.link)
  21.                     a.text(item.text)
  22.  
  23.                     suggest_list.append(a)
  24.                 })
  25.             }
  26.         },
  27.         complete: function() {
  28.             if ($('#suggestion-list a').length > 0) {
  29.                 $('#search-suggestion').removeClass('d-none')
  30.             } else {
  31.                 $('#search-suggestion').addClass('d-none')
  32.             }
  33.         }
  34.     })
  35. }
  36. $(function() {
  37.     $('#search').on('input', function() {
  38.         if ($(this).val() != '')
  39.             search_suggest($(this).val())
  40.     })
  41.     $('#search').on('keydown', function(e) {
  42.         if (e.which == 13)
  43.             location.href = "./?search=" + encodeURI($(this).val());
  44.     })
  45.     $('#search').on('focusin', function() {
  46.             if ($('#suggestion-list a').length > 0) {
  47.                 $('#search-suggestion').removeClass('d-none')
  48.             } else {
  49.                 $('#search').trigger('input')
  50.             }
  51.         })
  52.         // $('#search').focusout(function() {
  53.         //     $('#search-suggestion').addClass('d-none')
  54.         // })
  55.     $('#empty_search').click(function() {
  56.         $('#search').val('')
  57.         $('#suggestion-list').html('')
  58.     })
  59.     $(document).click(function(e) {
  60.         if ($('#search-suggestion').hasClass('d-none') == false && $('#search').is(':focus') == false) {
  61.             var el = $(e.target)
  62.             if (el.hasClass('suggest-item') == false) {
  63.                 $('#search-suggestion').addClass('d-none')
  64.             }
  65.         }
  66.     })
  67. })

DEMO VIDEO

That's it. You can now test the simple Search Web Application on your end to see if works as we planned. If you have encountered any errors, kindly review your source code. You can also run the source code provided I created for this tutorial. The download button is located below this article.

That is the end of this tutorial. I hope you will find this tutorial useful for your future projects. Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding :)

Add new comment