Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

AJAX Live Search

AJAX Live Search is a jQuery plugin / PHP search form that searches and displays the result as you type similar to Google Autocomplete feature.


Check it out in action.

Browser Support

IE Chrome Firefox Opera Safari
IE 8+ Chrome Firefox Opera Safari

Thanks to BrowserStack and JetBrains for supporting this project.

Getting started with Ajax Live Search

Getting the current example in index.php to work including creating a dummy database and a table should not take longer than 7 minutes. But it will take more in case you need to integrate it in an existing project. To achieve that assuming you have this text field:

<input type="text" class='mySearch' id="ls_query" placeholder="Type to start searching ...">

  1. Copy the folders including core, css, font, img, js and templates to your project.

  2. Specify the required configurations specially database configurations in core/Config.template.php and rename the file to Config.php. This file contains all the back-end settings for the plugin that have been explained in PHP Configs table.

  3. Include js/ajaxlivesearch.min.js or js/ajaxlivesearch.js and css/ajaxlivesearch.min.css or css/ajaxlivesearch.css in your page.

  4. Change the URL for Access-Control-Allow-Origin header in core/AjaxProcessor.php to your project URL. Currently it is

  5. Make sure core/Handler.php and core/Config.php are included in your (PHP) page and you have these lines at the very top of the file (Check index.php):

    use AjaxLiveSearch\core\Config;
    use AjaxLiveSearch\core\Handler;
    if (session_id() == '') {
    $handler = new Handler();
  6. Lastly, hook the plugin to the text field and pass the required options (loaded_at & token):

jQuery("#ls_query").ajaxlivesearch({ loaded_at: , token: getToken() . "'"; ?>, max_input: , }); ```

You can also post additional parameters to the server if you need. To achieve this you should add data attributes to the search input:

<input type="text" class='mySearch' id="ls_query" placeholder="Type to start searching ..." data-additionalData="hello world!">

For example, in this case you can access the data attribute in PHP like this:

// key is transformed to lowercase
$additionalData = $_POST['additionaldata'];

jQuery Options

Name Type Required Description
loaded_at Integer Yes This is used to prevent bots from searching.
token String Yes This is used to prevent CSRF attack.
url String No Default: ajax/process_livesearch.php.
cache Boolean No This refers to Ajax request caching. Default: false
form_anti_bot String No Default: ajaxlivesearch_guard
slide_speed String No Default: fast
type_delay Integer No Default: 350
max_input Integer No Default: 20
min_chars_to_search Integer No Minimum characters length to start searching. Default: 0
page_ranges Array No Default: [0, 5, 10]
page_range_default Integer No Default: 5
form_anti_bot_class String No Default: ls_anti_bot
footer_class String No Default: ls_result_footer
next_page_class String No Default: ls_next_page
previous_page_class String No Default: ls_previous_page
page_limit String No Default: page_limit
result_wrapper_class String No Default: ls_result_div
result_class String No Default: ls_result_main
container_class String No Default: ls_container
pagination_class String No Default: pagination
form_class String No Default: search
loaded_at_class String No Default: ls_page_loaded_at
token_class String No Default: ls_token
current_page_hidden_class String No Default: ls_current_page
current_page_lbl_class String No Default: ls_current_page_lbl
last_page_lbl_class String No Default: ls_last_page_lbl
total_page_lbl_class String No Default: ls_last_page_lbl
page_range_class String No Default: ls_items_per_page
navigation_class String No Default: navigation
arrow_class String No Default: arrow

Custom Event



    loaded_at: <?php echo time(); ?>,
    token: <?php echo "'" . $handler->getToken() . "'"; ?>,
    max_input: <?php echo Config::getConfig('maxInputLength'); ?>,
    onResultClick: function(e, data) {
        // get the index 1 (second column) value
        var selectedOne = jQuery(data.selected).find('td').eq('1').text();

        // set the input value

        // hide the result
    onResultEnter: function(e, data) {
        // do whatever you want
        // jQuery("#ls_query").trigger('ajaxlivesearch:search', {query: 'test'});
    onAjaxComplete: function(e, data) {


Custom Trigger


PHP Configurations

Name Type Required Description
dataSources Array Yes Data source for each search text field. Keys are refering to the field HTML id. Currently MySQL and mongoDB (this is in beta) are supported.

MySQL data source configs:
Name Type Required Description
host String Yes MySQL database host. It usually is 'localhost'.
database String Yes MySQL database name.
username String Yes MySQL database username.
pass String Yes MySQL database username password.
table String Yes MySQL database table that the live search searches in.
searchColumns Array Yes Search columns that the live search searches in. It can be one or many. e.g. array('column_name_1', 'column_name_2')
orderBy String No Column that the result is ordered based in it.
orderDirection String No Order direction: 'ASC' or 'DESC' for 'orderBy'. Default value: ASC
filterResult Array No Columns that need to be in the result. If it is empty all the columns will be returned.
comparisonOperator String Yes Search query comparison operator. Possible values for comparison operators are: 'LIKE' and '='.
searchPattern String Yes This is used to specify how the query is searched. possible values are: `q`, `*q`, `q*`, `*q*`.
caseSensitive String Yes Search query case sensitivity
maxResult Integer No This is used to limit the maximum number of result.
displayHeader Array No This is used to display or hide the header in the result. If 'active' is set to true header is displayed. Also, it is possible to map columns to different titles.
type String Yes Type of the datasource. Currently possible values are: 'mysql' or 'mongo'.
antiBot String Yes This is used as a security technique to prevent form submissions from those bots that do not use JavaScript. In this technique, a hidden field is populated using jQuery with this value. It can have any value, but it MUST be the same as `form_anti_bot` option passed to the jQuery plugin. By default it is set to `ajaxlivesearch_guard`.
searchStartTimeOffset Integer Yes This is used for another security technique against bots. Some bots immediately submit a form once the page is finished loading. However, for human beings it takes more time to fill a field. By default this parameter is set to 3 seconds. Assigning more than 3 seconds is not recommended.
maxInputLength Integer Yes This specifies the maximum length of characters in search field.
template String Yes This specifies the template name located in templates folder


  • What is the risk in disabling anti_bot and token?

    form_anti_bot is a nice security feature to have but it should be fine to remove it. To achieve this you need to change validateRequest() in core/AjaxProcessor.php and remove $_POST['ls_anti_bot'] as well as changing verifySessionValue($sessionParameter, $sessionValue) in core/Handler.php. In contrast, removing the token allows anyone to create a form and use your server as the data source and therefore it is not recommended. Currently, each time the page / search form is loaded a new token is generated by calling getToken() in the form page (index.php in the current example). Then the token and anti_bot are checked using verifySessionValue($sessionParameter, $sessionValue) upon searching / sending a new request to the server. If this looks an overkill to you, in getToken() return the same token for the existing session.

  • How a column can be hidden in the result?

    This can be achieved in your template. An example can be found in templates/hiddenColumn.php


MIT License

Buy me half of a coffee if you like!