Skip to main content
Skip table of contents

Implementing quick search results

This recipe explains how to implement quick search results.

Requirements

For this recipe to work, you need jQuery. Also, you should also have set up the search form as described in this previous recipe.

Quick search results are the ones that appear while typing into the search box.

The image shows quick search results for the word 'Recipe' in Confluence.

Extend the Search Result Template

In your template file search.vm overwrite or merge the existing code with the template below:

CODE
#if ($stringUtils.contains($url.query, 'quicksearch=true'))
    #foreach($result in $searchResults.items)
        <li n="$velocityCount" class="search-result">
            <a href="$result.link">$result.displayTitle</a>
        </li>
    #end
#else
    #set($search = "/search")
    #if ($stringUtils.equals(${viewport.link}, "/") == false)
    #set($search = "${viewport.link}/search")
    #end 
    <form id="search" action="$search" method="GET">
        <input id="search-input" type="text" placeholder="Search" autocomplete="off" name="q" value="$!searchRequest.queryString" />
        <br><br>
        <input type="hidden" name="s" value="*" />
        <input type="submit" value="Submit">
    </form>
    <div id="search-results"></div>
    <h1>Search</h1>
    <p class="lead">Search for "<em>$searchRequest.queryString</em>" returned $searchResults.total results.</p>
    <ol>
        #foreach($result in $searchResults.results)
        <li>
            <h4><a href="$result.link">$result.displayTitle</a></h4>
            <p>$result.description</p>
        </li>
        #end
    </ol>
#end

This template contains both the search form, search results and quick search results. The results will be loaded into the container with the id search-results. Whenever you search with the GET parameter quicksearch=true, you'll be able to load the results asynchronously. For this, you have to load some javascript. See Referencing JS/CSS Files on how to include scripts.

You can position and style the quick results any way you want. If you need inspiration, check out how we styled ours in our help center search function.

Getting the search results through AJAX

Add this code to your JavaScript code. 

main.js

JS
$(document).ready(() => {
    $('#search-input').on('keyup', function () {
        if($('#search-input').val().length >= 3){
            $('#search-results')
                .load(
                    $('#search').attr('action'), "quicksearch=true&q=" + $("#search-input")
                .val());
        }
    });
});

As you can see, when the user types more than 3 letters, a request will be sent and the search results will be loaded in the results container. 

A working implementation of this recipe can be found in the Scroll Help Theme (Viewport's default theme). This is the method we use to load search results in the mobile sidebar.

Including page-relevant properties

If you want to display other search result-relevant data such as the spaceKey, you can retrieve the object with $result.getObject().

This will give you, depending on the object type (page, blog_post, user, status and attachment) a placeholder.

So we have to make sure that we are retrieving data from a ContentPlaceholder in order to get the spaceKey.

CODE
#foreach($result in $searchResults.results)
<li>
    #set( $space = '' )
    #if( $result.type == 'page' )
        #set( $space = $result.getObject().spaceKey )
    #end
    <h4>
        <a href="$result.link">
            $result.displayTitle
            #if( $space )
                <span>$space</span>
            #end
        </a>
    </h4>
    <p>$result.description</p>
</li>
#end

Please see the Template Contexts for a list of all available placeholders.

Next steps

A search form can be modified to search just for users with the User Search Recipe.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.