Build Instant Search with Ajax, PHP & MySQL

Instant Search or Live Search is a web applications functionality. It is used to search data and display search result instantly on same page.

So if you’re a PHP developer and looking for instant search solution then you’re here at the right place. In our previous tutorial, you learned how to build Content Management System with PHP & MySQL. In this tutorial, you will learn how to develop instant search system with Ajax, PHP and MySQL.

Also, read:

In this tutorial, we will create live example of instant search to allow users with keywords and display results instantly with pagination.


So let’s proceed to develop instant search system with Ajax, PHP and MySQL. We will have following file structure for this project.

  • instant-search-ajax-php-mysql
    • config
      • Database.php
    • class
      • Search.php
    • js
      • search.js
    • index.php
    • load_data.php

Step1: Create MySQL Database Table

First we will create MySQL database table product_details to store product details.

CREATE TABLE `product_details` (
  `id` int(20) NOT NULL,
  `name` varchar(120) NOT NULL,
  `brand` varchar(100) NOT NULL,
  `price` decimal(8,2) NOT NULL,
  `ram` char(5) NOT NULL,
  `storage` varchar(50) NOT NULL,
  `camera` varchar(20) NOT NULL,
  `image` varchar(100) NOT NULL,
  `quantity` mediumint(5) NOT NULL,
  `status` enum('0','1') NOT NULL COMMENT '0-active,1-inactive'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ALTER TABLE `product_details`
  ADD PRIMARY KEY (`id`);

Step2: Create Search Form

In index.php file, we will create search form with an input. We will also create a container to display search results.

<div class="card">
	<div class="card-header">Search Result</div>
	<div class="card-body" id="searchSection">
	  <div class="form-group">
		<input type="text" name="search" id="search" class="form-control" placeholder="Type your search keyword here" />
	  </div>
	  <div class="table-responsive" id="searchResult"></div>
	</div>
</div>

Step3: Make Ajax Request to Display Search Results

In search.js file, we will make ajax request to load_data.php to get search result and display on keyup.

$('#search').keyup(function(){
  var searchQuery = $('#search').val();
  searchData(1, searchQuery);
});

function searchData(page, searchQuery = '') {
  $.ajax({
	url:"load_data.php",
	method:"POST",
	data:{search:'search', page:page, searchQuery:searchQuery},
	success:function(data) {
	  $('#searchResult').html(data);
	}
  });
}

We will also handle search record display on pagination.


$('#searchSection').on('click', '.page-link', function(){
  var page = $(this).data('page_number');
  var searchQuery = $('#search').val();
  searchData(page, searchQuery);
});

Step4: Implement Search

In load_data.php, we will call method product() from class Search.php to get search result.

$search = new Search($db);

if(!empty($_POST['search']) && $_POST['search'] == 'search') {
	$search->product();
}

We will implement method product() in class Search.php to search result data.

public function product() {	
	$limit = '5';
	$page = 1;
	if($_POST['page'] > 1) {
	  $start = (($_POST['page'] - 1) * $limit);
	  $page = $_POST['page'];
	} else {
	  $start = 0;
	}

	$sqlQuery = "SELECT * FROM ".$this->productTable;
	if($_POST['searchQuery'] != ''){
	  $sqlQuery .= ' WHERE name LIKE "%'.str_replace(' ', '%', $_POST['searchQuery']).'%" ';
	}
	$sqlQuery .= ' ORDER BY id ASC';

	$filter_query = $sqlQuery . ' LIMIT '.$start.', '.$limit.'';	

	$statement = $this->conn->prepare($sqlQuery);			
	$statement->execute();

	$result = $statement->get_result();
	$totalSearchResults =  $result->num_rows;	

	$statement = $this->conn->prepare($filter_query);			
	$statement->execute();

	$result = $statement->get_result();
	$total_filter_data = $result->num_rows;
	
	$resultHTML = '
		<label>Total Search Result - '.$totalSearchResults.'</label>
		<table class="table table-striped table-bordered">
		  <tr>
			<th>ID</th>
			<th>Product Name</th>
		  </tr>';

	if($totalSearchResults > 0) {	  
	  while ($product = $result->fetch_assoc()) { 	
		$resultHTML .= '
		<tr>
		  <td>'.$product["id"].'</td>
		  <td>'.$product["name"].'</td>
		</tr>';
	  }
	} else {
	  $resultHTML .= '
	  <tr>
		<td colspan="2" align="center">No Record Found</td>
	  </tr>';
	}

	$resultHTML .= '
	</table>
	<br />
	<div align="center">
	  <ul class="pagination">';

	$totalLinks = ceil($totalSearchResults/$limit);
	$previousLink = '';
	$nextLink = '';
	$pageLink = '';	

	if($totalLinks > 4){
	  if($page < 5){
		for($count = 1; $count <= 5; $count++){
		  $pageData[] = $count;
		}
		$pageData[] = '...';
		$pageData[] = $totalLinks;
	  } else {
		$endLimit = $totalLinks - 5;
		if($page > $endLimit){
		  $pageData[] = 1;
		  $pageData[] = '...';
		  for($count = $endLimit; $count <= $totalLinks; $count++)
		  {
			$pageData[] = $count;
		  }
		} else {
		  $pageData[] = 1;
		  $pageData[] = '...';
		  for($count = $page - 1; $count <= $page + 1; $count++)
		  {
			$pageData[] = $count;
		  }
		  $pageData[] = '...';
		  $pageData[] = $totalLinks;
		}
	  }
	} else {
	  for($count = 1; $count <= $totalLinks; $count++) {
		$pageData[] = $count;
	  }
	}

	for($count = 0; $count < count($pageData); $count++){
	  if($page == $pageData[$count]){
		$pageLink .= '
		<li class="page-item active">
		  <a class="page-link" href="#">'.$pageData[$count].' <span class="sr-only">(current)</span></a>
		</li>';

		$previousData = $pageData[$count] - 1;
		if($previousData > 0){
		  $previousLink = '<li class="page-item"><a class="page-link" href="javascript:void(0)" data-page_number="'.$previousData.'">Previous</a></li>';
		} else {
		  $previousLink = '
		  <li class="page-item disabled">
			<a class="page-link" href="#">Previous</a>
		  </li>';
		}
		$nextData = $pageData[$count] + 1;
		if($nextData > $totalLinks){
		  $nextLink = '
		  <li class="page-item disabled">
			<a class="page-link" href="#">Next</a>
		  </li>';
		} else {
		  $nextLink = '<li class="page-item"><a class="page-link" href="javascript:void(0)" data-page_number="'.$nextData.'">Next</a></li>';
		}
	  } else {
		if($pageData[$count] == '...'){
		  $pageLink .= '
		  <li class="page-item disabled">
			  <a class="page-link" href="#">...</a>
		  </li>';
		} else {
		  $pageLink .= '
		  <li class="page-item"><a class="page-link" href="javascript:void(0)" data-page_number="'.$pageData[$count].'">'.$pageData[$count].'</a></li>';
		}
	  }
	}
	
	$resultHTML .= $previousLink . $pageLink . $nextLink;
	$resultHTML .= '</ul></div>';
	echo $resultHTML;
}	

You may also like:

You can view the live demo from the Demo link and can download the script from the Download link below.
Demo Download


3 thoughts on “Build Instant Search with Ajax, PHP & MySQL

  1. I have an error when I search something.

    Fatal error: Uncaught Error: Call to a member function execute() on bool in F:\xampp\htdocs\t3\class\Search.php:30 Stack trace: #0 F:\xampp\htdocs\t3\load_data.php(11): Search->product() #1 {main} thrown in F:\xampp\htdocs\t3\class\Search.php on line 30

    Why is this happening?

  2. Thanks for the post. I get following error. when it doesn’t find any records. its not showing msg “record not found” as in your demo. but error :

    Warning: Undefined variable $pageData in C:\xampp\htdocs\phpzag-sep-2021-instant-search-ajax-php-mysql\class\Search.php on line 108

    Fatal error: Uncaught TypeError: count(): Argument #1 ($var) must be of type Countable|array, null given in C:\xampp\htdocs\phpzag-sep-2021-instant-search-ajax-php-mysql\class\Search.php:108 Stack trace: #0 C:\xampp\htdocs\phpzag-sep-2021-instant-search-ajax-php-mysql\load_data.php(11): Search->product() #1 {main} thrown in C:\xampp\htdocs\phpzag-sep-2021-instant-search-ajax-php-mysql\class\Search.php on line 108

    any suggestions

Comments are closed.