Skip to main content

Autocomplete

This powerful search functionality enhances your Craft CMS website by providing a user-friendly autocomplete feature. Users can easily find desired entries as they type, with results fetched and displayed in real-time.

Key Features:

  • Efficient client-side processing: The search operates on the client-side, minimizing server requests and avoiding excessive database queries.
  • JSON-based entry caching: Upon focus, desired entries are fetched and stored in the session cache (sessionStorage) for quick retrieval.
  • Integration with Element API: Utilizes Craft CMS' Element API plugin to create a customizable endpoint for CMS entries. GraphQL integration is also possible.
  • Field and section flexibility: Make any field and section available for search, providing precise control over the searchable content.
  • Multi-language support: Seamlessly search within the current language, ensuring an inclusive search experience for multi-lingual websites.

Demo

To test the demo, use one of the component names. For example, try entering "me" or "drop" (for menu, dropdown, etc.)

Installation

Import the function into a JavaScript file

import { Autocomplete } from "@overdog/fn"

Create and initialize an instance

new Autocomplete("#autocomplete-searchform", {
   textLength: 2,
   // Craft CMS element api endpoint and the related langCode (must match the lang code in your html)
   endpoints: [
      { langCode: "fr-CA", slug: "/autocomplete.json" },
      { langCode: "en-CA", slug: "/en/autocomplete.json" }
   ],
   fieldsToSearch: ["title", "url", "titleToAscii"],
   fieldToHighlight: "title",
   highlightClasses: "font-bold text-[#084b83]"
}).init()

Create an endpoint using Element API or GraphQL

use craft\elements\Entry;
use craft\helpers\StringHelper;

return [
  'endpoints' => [

      'autocomplete.json' => function() {

          return [
              'elementType' => Entry::class,
              'criteria' => [
                'section' => 'structurePages',
              ],
              'paginate' => false,
              'pretty' => true,
              'transformer' => function(craft\elements\Entry $entry) {

                return [
                    'title' => $entry->title,
                    // clone the title column without any accent on export - toAscii
                    'titleToAscii' => craft\helpers\StringHelper::toAscii ($entry->title),
                    // url field
                    'url' => $entry->url,
                ];
              },
          ];
      },
  ]
];

Twig template Code


<form id="autocomplete-searchform" class="flex max-w-[600px]" role="search" action="{{ url('search-results'|t) }}" tabindex="0">
   {# 
      TEMPLATE FOR SUGGESTIONS PICKED UP BY JAVASCRIPT
      JavaScript will used this template for the suggestion. Template tags are ignored by browsers. 
      Use the $key$ placeholder to tell JavaScript wich value to inject from your data.
   #}
   <template data-fn-autocomplete-template>
      <a 
         href="$url$"
         class="block px-4 py-2 focus:bg-[#d7e4f4] hover:bg-gray-[#e0e2e7]">
         $title$
         {# you can add image, description, etc. any element from your data #}
      </a>
   </template>  

   {# LAYOUT #}
    <div data-fn-autocomplete-wrapper class="h-[44px] relative w-full">
      <input 
         data-fn-autocomplete-input
         class="h-full px-1 w-full border border-gray-200" 
         type="text" 
         name="s" 
         autocomplete="off" 
         placeholder="Search.." 
         required
      >
      <div 
         data-fn-autocomplete-results
         class="bg-white rounded-b-md shadow-[0_1px_2px_0_rgba(0,_0,_0,_0.11)] max-h-[300px] overflow-auto absolute top-[44px] left-0 w-full z-50" 
         tabindex="0"
      >
        <div data-fn-autocomplete-results-inner></div>
      </div>
    </div>
    <button 
      data-fn-autocomplete-submit
      class="
         rounded-full shrink-0 text-0.9em h-[44px] ml-4 w-[44px] bg-slate-700 text-white
         disabled:bg-[#c1c1c4] disabled:text-[#5a656a] disabled:opacity-50 disabled:pointer-events-none
      "
      type="submit" 
      disabled>
      Go
   </button>
</form>

Options