Build an Ajax Search Module for Joomla

Build an Ajax Search Module for Joomla

Ajax makes it possible to create websites that are easier and faster to use. You can use Ajax to refresh a specific section of a page without reloading all the content. 

One really common use for Ajax is a search feature. With Ajax, visitors can try multiple different searches without refreshing the page.

In this tutorial, I'm going to show you how to use Ajax to create a Joomla search module.

This tutorial is based on the great example code from betweenbrain's Github repositories.

Yes, there are already Ajax search modules for Joomla, but this tutorial is to help you understand how they work.

After finishing this tutorial, this will be your module structure:

joomla ajax

Step #1. The manifest file

Create a file named mod_ajax_search.xml with the code below. The purpose of this manifest file is to define the module name, type of extension, files to include, author information, supported Joomla versions, etc.

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.4" method="upgrade">
    <name>Ajax Search</name>
    <creationDate>February 16, 2016</creationDate>
    <author>Your awesome name goes here</author>
    <authorUrl>https://www.yoursite.any</authorUrl>
    <copyright>Copyright (C) 2016 Your name goes here. All rights reserved.</copyright>
    <license>GNU General Public License version 2, or later.</license>
    <version>1.0.0</version>
    <description>Ajax Search</description>
    <files>
        <filename module="mod_ajax_search">mod_ajax_search.php</filename>
        <filename>helper.php</filename>
        <folder>tmpl</folder>
    </files>
</extension>

Step #2. The helper file

We will add the PHP code to process the search requests in a file named helper.php that includes the method getAjax():

<?php
defined('_JEXEC') or die;

class modAjaxSearchHelper
{
    public static function getAjax()
    {
        include_once JPATH_ROOT . '/components/com_content/helpers/route.php';

        $input = JFactory::getApplication()->input;
        $data  = $input->get('data', '', 'string');

        // Connect to database
        $db = JFactory::getDbo();
        $query = $db->getQuery(true);

        // Build the query
        $query
            ->select($db->quoteName(array('title','id','catid')))
            ->from($db->quoteName('#__content'))
            ->where($db->quoteName('title') . ' LIKE '. $db->quote('%' . $data . '%')
                . ' AND ' . $db->quoteName('state') . ' = 1')
            ->order('ordering ASC');
 
        $db->setQuery($query);
        $results = $db->loadObjectList();
 
        // Get output
        $output = null;

        foreach($results as $result){
            $output .= '<h4><a href="' . ContentHelperRoute::getArticleRoute($result->id,  $result->catid) . '">' . $result->title . '</a></h4>';
        }

        if($output == null or empty($data))
        {
            $output = 'Sorry! No results for your search.';
        }
 
        return $output;
    }
}

This file performs a database query that looks for any article titles that partially match the words typed in the search form. It will then list the links to the matching articles.

We call the route.php file to render the article's links inside the search results:

include_once JPATH_ROOT . '/components/com_content/helpers/route.php';

Get the typed words in the search form and sanitize them with the "string" filter:

$input = JFactory::getApplication()->input;
$data  = $input->get('data', '', 'string');

Look in the database for articles that partially match the searched title:

->where($db->quoteName('title') . ' LIKE '. $db->quote('%' . $data . '%')

Output the search results:

foreach($results as $result){
     $output .= '<h4><a href="' . ContentHelperRoute::getArticleRoute($result->id,  $result->catid) . '">' . $result->title . '</a></h4>';
 }

If no results come up, display a message:

$output = 'Sorry! No results for your search.';

Step #3. The module PHP file

Create a file named mod_ajax_search.php with the code below:

<?php
defined('_JEXEC') or die;

include_once __DIR__ . '/helper.php';

// Instantiate global document object
$doc = JFactory::getDocument();

$js = <<<JS
(function ($) {
    $(document).on('click', 'input[type=submit]', function () {
        var value   = $('input[name=data]').val(),
            request = {
                    'option' : 'com_ajax',
                    'module' : 'ajax_search',
                    'data'   : value,
                    'format' : 'raw'
                };
        $.ajax({
            type   : 'POST',
            data   : request,
            success: function (response) {
                $('.search-results').html(response);
            }
        });
        return false;
    });
})(jQuery)
JS;

$doc->addScriptDeclaration($js);

require JModuleHelper::getLayoutPath('mod_ajax_search');

It's important to outline the purpose of some of this code, so we'll do so below:

Load the helper.php file from the previous step.

include_once __DIR__ . '/helper.php';

A bit of jQuery code to execute an asynchronous HTTP request once the search button is clicked:

$(document).on('click', 'input[type=submit]', function () { ... });

Grab the value from the search field, and assign it to the "value" variable:

var value   = $('input[name=data]').val()

These params will build the HTTP request:

request = {
    'option' : 'com_ajax',
    'module' : 'ajax_search',
    'data'   : value,
    'format' : 'raw'
};

...and would generate an "invisible" URL:

joomla ajax

This part is essential to print the search results we got from getAjax() method above:

$('.search-results').html(response);

Output the Javascript code in the head tag of the Joomla site:

$doc->addScriptDeclaration($js);

Call the layout file from next step:

require JModuleHelper::getLayoutPath('mod_ajax_search');

Step #4. The layout file

Create a file named default.php and put inside a tmpl/ folder. This file will contain the HTML to render the search form:

<?php defined('_JEXEC') or die; ?>

<form>
    <input type="text" name="data" />
    <input type="submit" value="Search articles" />
</form>
<div class="search-results"></div>

The search results will be displayed inside this empty div:

<div class="search-results"></div>

Step #5. Create the installer

Compress the files into a zip:

joomla ajax

You have a module ready to install!

joomla ajax

Step #6. Install the module

Install the zip file as you would install any regular extension.

  • Go to Extensions
  • Manage
  • Upload package file
joomla ajax

You will now see a successful message when the install is complete.

Step #7. Test the module

  • Go to Extensions > Modules > New
  • Select a Module Type: Ajax Search (or the name you gave to your module)
joomla ajax
  • Choose a valid module position and assign it to at least one page.
  • Save and close

Step #8. End result

Visit your public site and test the module form by typing the names of articles you know exist and are published:

joomla ajax

On the other hand, if you look for content that doesn't exist, a message will come up:

Alternative solution: install Shack Search

Shack Search is a free extension that improves your Joomla search box. With this search module, your visitors can get instant search results. 

Instead of clicking the "Search" button and waiting for the page to reload, Shack Search provides instant results as you type:

Shack Search provides instant results as you type

You can start using Shack Search module virtually instantly.

  • Install it.
  • Assign it to the required Joomla pages.
  • That's all.

The module works just nicely out of the box, with its default settings.

What's Next?

Save $1,000's when you sign up to Joomlashack's Everything Club.

You will get access to all our 32 extensions, and legendary support!

  Click here to join the Everything Club