Search Autocomplete HTML

Search Autocomplete HTML

Features

  • Displays suggestions to end-users as they type
  • Shows top suggestion as a hint (i.e. background text)

Installation

The rekai_autocomplete.js library must be included after the Rek.ai base script.

<script src="https://static.rekai.se/addon/v3/rekai_autocomplete.min.js"></script>

Usage

Step 1

Include rekai_autocomplete.min.js.

Step 2

Initialize the auto-completion by calling the rekai_autocomplete function:

<input type="text" id="search-input" placeholder="Search unicorns..." />
 
<script src="https://static.rekai.se/addon/v3/rekai_autocomplete.min.js"></script>
<script>
 
// Add the id from the search field in the variable below, replace id with #.
// If your search field does not have an id but a class instead,
// then replace #search-input with .searchinput
 
  __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#searchform-input')
      .on('rekai_autocomplete:selected', function (event, suggestion, dataset) {
          window.location = suggestion.url;
      });
  });
 
  </script>
 

See also: How to redirect the user when a suggestion is selected. (opens in a new tab)

Using Rek.ai parameters

All parameters that can be added to a div can be added to the autocomplete by using a "params" option.

Only use autocomplete on news:

<script>
    __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#search-input', {
        params: {
          subtree: '/news'
        }
      });
    });
</script>

Get all metadata known for each page in the search result

This is useful if you want to show, for example, images or other metadata in the autocomplete.

<script>
    __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#search-input', {
        params: {
          addcontent: true
        }
      });
    });
</script>

Include Questions & Answers

If your project is using Questions & Answers, you can add them to the autocomplete with entitytype: 'all' parameter.

<script>
    __rekai.ready(function() {
        var rekAutocomplete = rekai_autocomplete('#searchform input', {
            debug: true,
            params: {
                entitytype: 'all'
            }
          }).on('rekai_autocomplete:selected', function (event, suggestion, dataset) {
            window.location = suggestion.url;
        });
    });
</script>

See also: Add a header before the questions in autocomplete (opens in a new tab).

Global Options

When initializing an autocomplete, there are a number of global options you can configure.

  • baseUrl - string that overrides the default baseUrl https://predict.rek.ai/predict. Don't forget to include https or http.
  • projectid - string or number that overrides the currently loaded projectid.
  • cms - string that overrides the cms set by the static file.
  • autoselect - If true, the first rendered suggestion in the dropdown will automatically have the cursor class, and pressing <ENTER> will select it.
  • styled - If false, the autocomplete will only include minimal CSS styling for positioning.
  • tabAutocomplete - If true, pressing tab will select the first rendered suggestion in the dropdown. Defaults to true.
  • hint - If true, the autocomplete will show a hint. Defaults to false.
  • debug - If true, the autocomplete will not close on blur. Defaults to false.
  • clearOnSelected - If true, the autocomplete will empty the search box when a suggestion is selected. This is useful if you want to use this as a way to input tags using the selected event.
  • openOnFocus - If true, the dropdown menu will open when the input is focused. Defaults to false.
  • dropdownMenuContainer - If set with a DOM selector, it overrides the container of the dropdown menu.
  • keyboardShortcuts - Array of shortcuts that will focus the input. For example, if you want to bind s and /, you can specify: keyboardShortcuts: ['s', '/'].
  • ariaLabel - An optional string that will populate the aria-label attribute.
  • minLength - The minimum character length needed before suggestions start getting rendered. Defaults to 1.
  • autoWidth - Controls the width of the autocomplete wrapper. When false, the wrapper will not have a width style attribute, so you're able to set your own width property in CSS. Defaults to true.
  • highlight - If true, the query will be highlighted in the search hits. Defaults to false.
  • params - An optional object that can be used as data parameters for the Rek.ai prediction <div>. See All parameters (opens in a new tab) for the full list.

Examples of global options use

Highlight query word

<script>
    __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#search-input', {
        highlight: true
      });
    });
</script>

Custom projectid

<script>
  __rekai.ready(function() {
    var rekAutocomplete = rekai_autocomplete('#search-input', {
      params: {
        projectid: 111111
      }
    });
  });
</script>

Debug mode

<script>
  __rekai.ready(function() {
    var rekAutocomplete = rekai_autocomplete('#search-input', {
      debug: true
    });
  });
</script>

Only swedish pages

<script>
  __rekai.ready(function() {
    var rekAutocomplete = rekai_autocomplete('#search-input', {
      params: {
        allowedlangs: 'se'
      }
    });
  });
</script>

Events

The autocomplete component triggers the following custom events.

  • rekai_autocomplete:opened - Triggered when the dropdown menu of the autocomplete is opened.
  • rekai_autocomplete:shown - Triggered when the dropdown menu of the autocomplete is shown (opened and non-empty).
  • rekai_autocomplete:empty - Triggered when all datasets are empty.
  • rekai_autocomplete:closed - Triggered when the dropdown menu of the autocomplete is closed.
  • rekai_autocomplete:updated - Triggered when a dataset is rendered.
  • rekai_autocomplete:cursorchanged - Triggered when the dropdown menu cursor is moved to a different suggestion. The event handler will be invoked with 3 arguments: the jQuery event object, the suggestion object, and the name of the dataset the suggestion belongs to.
  • rekai_autocomplete:selected - Triggered when a suggestion from the dropdown menu is selected. The event handler will be invoked with the following arguments: the jQuery event object, the suggestion object, the name of the dataset the suggestion belongs to, and a context object. The context contains a .selectionMethod key that can be either click, enterKey, tabKey, or blur, depending on how the suggestion was selected.
  • rekai_autocomplete:cursorremoved - Triggered when the cursor leaves the selections or its current index is lower than 0.
  • rekai_autocomplete:autocompleted - Triggered when the query is autocompleted. Autocompleted means the query was changed to the hint. The event handler will be invoked with 3 arguments: the jQuery event object, the suggestion object, and the name of the dataset the suggestion belongs to.
  • rekai_autocomplete:redrawn - Triggered when appendTo is used and the wrapper is resized/repositioned.

All custom events are triggered on the element initialized as the autocomplete.

Examples of events use

Go to the hit URL directly on select

<script>
    __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#search-input')
        .on('rekai_autocomplete:selected', function(event, suggestion, dataset) {
          window.location = suggestion.url;
        });
      });
</script>

Go to the hit url directly on select and open external links in a new browser tab

<script>
    __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#search-input')
        .on('rekai_autocomplete:selected', function(event, suggestion, dataset) {
          if (suggestion.url.indexOf('http') > -1) {
            window.open(suggestion.url,'_blank');
          } else {
            window.location = suggestion.url;
          }
        });
      });
</script>

Add highlight and go to target

When adding features to the init, make sure they're added in the correct place.

<script>
   __rekai.ready(function() {
    var rekAutocomplete = rekai_autocomplete('#search-input',
      {
        highlight: true
      }
    ).on('rekai_autocomplete:selected', function(event, suggestion, dataset) {
      window.location = suggestion.url;
    });
  });
</script>

Go to the search page with a query

<script>
    __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#search-input')
        .on('rekai_autocomplete:selected', function(event, suggestion, dataset) {
          window.location = '/searchresults?query=' + encodeURIComponent(suggestion.title);
      });
    });
</script>

Add one last selection to autocomplete

Since not all pages are included in our index and there's a selection, it's a good idea to add a link that clarifies there are more search hits.

Visa alla
<script>
    __rekai.ready(function() {
      // START HTML AUTOCOMPLETE
      var rekAutocomplete = rekai_autocomplete('input[name="search"]', {
        debug: true,
        params: {
        }
      },
      [{
        templates: {
          footer: function (options) {
            if (!options.isEmpty) { // Remove this if you always want the footer to be displayed
              // Check so the path to the searchpage is correct
              return '<div class="rekai-suggestion-footer"><a href="/search?q=' + options.query + '" class="rekai-view-searches">Show all hits</a></div>'
            }
          }
        }
      }]
      ).on('rekai_autocomplete:selected', function (event, suggestion, dataset) {
        window.location = suggestion.url;
      });
    });
</script>

API

var search = rekai_autocomplete(containerSelector, globalOptions, datasets);

Example:

var search = rekai_autocomplete('#search', { debug: true });
 
search.autocomplete.open();
search.autocomplete.close();
search.autocomplete.getVal();
search.autocomplete.setVal('Hey Jude');
search.autocomplete.destroy();

Custom calls & custom templates

A small example of adding an icon to external links pointing to the support website.

Dedicated image for link to external
var rekAutocomplete = rekai_autocomplete(searchSelector,
  {
    debug: true
  },
  [{
    templates: {
      suggestion: function (suggestion) {
        // Is called for each suggestion row
        // If link to exteral supportsite add icon
        var supportIcon = '';
        if(suggestion.url.indexOf('kundforum') > -1) {
          supportIcon = '<img style="width: 13px; height: 13px; margin-right: 7px;" src="https://cdn-icons-png.flaticon.com/512/69/69890.png"/>';
        }
 
        return '<div class="rekai-suggestion-item">' + supportIcon + suggestion.title + '</div>';
      }
    }
  }]).on('rekai_autocomplete:selected', function(event, suggestion, dataset) {
    if (suggestion.url.indexOf('http') > -1) {
      window.open(suggestion.url,'_blank');
    } else {
      window.location = suggestion.url;
    }
});

Full example:

var search = rekai_autocomplete('#search', {}, [{
  source: function(query, callback) {
    var url = "https://predict.rek.ai/predict?addcontent=true&mb=1&vt=1&v30=1&dlv=30&ubl=sv&pl=sv&p=10011002&srek=cc1bdb34&rt=flat&keywords=true&term=" + encodeURIComponent(query);
    rekai_autocomplete.getJSON(url, function(response) {
      callback(response.slice(0,10));
    });
  },
  templates: {
    header: function (options) {
      // options: { query: string, isEmpty: boolean }
      // is called once, before suggestions are rendered
      return options.isEmpty ? '<div class="rekai-suggestion-header">Header: empty</div>' : '<div class="rekai-suggestion-header">Header</div>';
    },
    body: function (suggestions) {
      // suggestions: Array<suggestion>
      // is called when suggestions are rendered.
 
      var totalSuggestions = suggestions.length;
      var halfwayMark = Math.ceil(totalSuggestions / 2);
 
      var bodyTemplate = [ // Array<{id: string, classes: string, suggestions: Array<suggestion>, titleHtml: string}>
        {
          id: 'my-div-id-1', // optional (defaults to 'suggestions-group-#')
          classes: 'suggestions-group-1', // optional (defaults to 'suggestions-group suggestions-group-#')
          suggestions: suggestions.slice(0, halfwayMark),
          titleHtml: '<h2>Suggestions title 1</h2>', // optional
        },
        {
          id: 'my-div-id-2',
          classes: 'suggestions-group-2',
          suggestions: suggestions.slice(halfwayMark, totalSuggestions),
          titleHtml: '<h2>Suggestions title 2</h2>',
        }
      ]
 
      return bodyTemplate
    },
    suggestion: function (suggestion) {
      // is called for each suggestion row
      return '<div class="rekai-suggestion-item">' + suggestion.title + '</div>';
    },
    footer: function (options) {
      // options: { query: string, isEmpty: boolean }
      // is called once, after suggestions are rendered
      return '<div class="rekai-suggestion-footer">Footer</div>';
    },
    empty: function (options) {
      // options: { query: string, isEmpty: boolean }
      // is called once, when no suggestions are available
      return '<div class="rekai-suggestion-empty">Empty</div>';
    }
  }
}]);

HTML structure

To customize the dropdown generated by the autocomplete feature with your own CSS, you can target its specific classes:

<span class="rekai-dropdown-menu rekai-with-1" role="listbox" id="rekai-autocomplete-listbox-0" style="position: absolute; top: 100%; z-index: 100; left: 0px; right: auto; display: block;">
  <div class="rekai-dataset-1">
    <span class="rekai-suggestions" style="display: block;">
      <div class="rekai-suggestion" role="option" id="option-74260288">
        <p style="white-space: normal;">Page 1</p>
      </div>
      <div class="rekai-suggestion" role="option" id="option-50811728">
        <p style="white-space: normal;">Page 2</p>
      </div>
    </span>
  </div>
</span>

Check access for autocomplete

If you already have an access-check function (see Validate user access (opens in a new tab)), you can reuse it here.

<script>
    __rekai.ready(function() {
      var rekAutocomplete = rekai_autocomplete('#search-input', {
        verifyurl: '/2.219e24b4172a2493ff21/12.24639b92184b91ba68116d.json'
      });
    });
</script>

Credit

This library was originally forked from Twitter's typeahead.js (opens in a new tab) library.