Suggestions Layer Reference (v7)

or send an email to support@doofinder.com

In this article

This document describes all the options you can use to configure the Doofinder Suggestions layer in your website.

Basics

The Doofinder script that you include in your website works just fine out of the box, but its behavior is customizable with a handful of options for almost every corner case you can imagine.

Doofinder script options comes for every possible taste, from basic knowledge about dimensions and positioning to javascript ninja, so don't worry if a few options seem somehow obscure to you. We just hope you find what is suitable for your needs, whatever javascript-ninja-level you're in.

If you're here, you probably already have a layer script for your website.

If you want to create your own script manually, you will find more details at the end of this document, in the Standalone Script section.

The Options Array

The layer script is in charge of requiring the Javascript code to run the layer from our CDN and configuring the layer or layers described in the options array.

In your script you can see something like this:

var dfSuggestionsLayers = [{
    hashid: '1955a94db43999fcc211f925fc85f12c',
    zone: 'eu1',
    queryInput: '#query'
}];

dfSuggestionsLayers is the name we gave to the Javascript array (a list) which contains all the layer descriptions for this type of layer.

Each layer description is a Javascript object (a key-value dictionary) with option names as keys and the corresponding values assigned to them.

This means that you could have more than one layer in your website:

var dfSuggestionsLayers = [
    {
        hashid: '1955a94db43999fcc211f925fc85f12c',
        zone: 'eu1',
        queryInput: '#query'
    },
    {
        hashid: '43999fcc85f12c1955a94dbc211f925f',
        zone: 'eu1',
        queryInput: '#query2'
    }
];

To customize your layer(s) you will have to add more keys to the proper layer description, taking care of commas, quotation marks for text, curly braces…:

var dfSuggestionsLayers = [
    {
        hashid: '1955a94db43999fcc211f925fc85f12c',
        zone: 'eu1',
        queryInput: '#query',   // We've added a comma
        display: {              // to add a new option.
            lang: 'en',         // This also needs a comma,
            minHeight: 100      // but no comma here…
        }                       // nor here…
    },
    {
        hashid: '43999fcc85f12c1955a94dbc211f925f',
        zone: 'eu1',
        queryInput: '#query2'   // no comma in the last option
    }
];

In order to make things simpler, we will represent single layer options in the rest of the document by omitting the dfSuggestionsLayers array so you'll see only the layer options:

{
    hashid: '1955a94db43999fcc211f925fc85f12c',
    zone: 'eu1',
    queryInput: '#query'
}

Mandatory options

hashid

Identifies your search engine in our servers. You will find all possible hashid values in the list of search engines in the Doofinder Admin.

{
  hashid: 'ce2c1ex5369d3r28419bzdee7bcfaa5c'
}

zone

Geographical location assigned to your search engine. All search engines in your account have the same location.

Current possible values are:

  • eu1
  • us1

This value is automatically added by the layer installer in the Doofinder Admin.

{
  zone: 'eu1'
}

queryInput

The CSS selector of the text box used to search on your website. The best value for this option is a CSS id, which should be unique and only used once in the HTML of your page.

The text box usually is an HTML <input> tag of type text or search.

<input type="text" id="query_input_id">
{
  queryInput: '#query_input_id' // a unique CSS id
}

NOTICE: If you use too generic selectors the layer will attach to all matching inputs.

Use generic selectors when there's no other way to match your text box or if you want to explicitly attach the layer to more than one text box.

{
  queryInput: 'input[type="search"]' // generic selector
}

General Options

autoHideVirtualKeyboard

This option is experimental and is disabled by default. You can configure a delay in ms to auto-hide Android's virtual keyboard when the user stops typing.

The recommended value in case you want to use this feature would be an integer greater or equal than 2000 (2s).

{
  autoHideVirtualKeyboard: 2000
}

WARNING: This option may cause important usability concerns. Use it at your own risk.

callbacks

Callbacks are functions that will be called at the end of certain actions or events. They are useful to change or add some extra behavior to the layer.

The callbacks option is an object (dictionary) which contains functions as values for specific keys.

resultsReceived

This callback will be called each time a search response is received.

{
  callbacks: {
    /**
     * @param  {Object} response Object that contains the search response.
     *                           Use your browser dev tools to inspect it.
     */
    resultsReceived: function(response) {
      console.log(response);
    }
  }
}
hit

This function will be called each time a search result is clicked.

{
  callbacks: {
    /**
     * @param  {Node}   item The DOM node that represents the item.
     */
    hit: function(item) {
      // item.dfClicked             `true` if the item was already clicked
      // item.getAttribute('href')  returns the URL if the item is a link
    }
  }
}
loaded

This function will be called when the layer is loaded. Use it to configure any additional behavior that requires that the layer exists in the page.

{
  callbacks: {
    /**
     * @param  {Object} instance that holds the layer and its options.
     */
    loaded: function(instance) {
      // instance.layerOptions  can be changed
      // instance.configure()   re-configures the layer
      // 
      // instance.layer         the layer instance itself
      // instance.layer.layer   the layer in the DOM
    }
  }
}

mainContainerId

You can define the prefix of the id attribute of the layer. When multiple layers of the same type are in the same page, a sequential number is added to the default prefix for the second, third and so on.

If you want a different prefix for your layer you can set it yourself:

{
  mainContainerId: 'my-first-layer'
}

searchParams

This option is an object (dictionary) of parameters and values to be sent in the query string of each search request.

{
  searchParams: {
    paramName: 'paramValue'
  }
}

All valid parameters can be found in the [Search API] reference but you will find the most common in the [Advanced Concepts] section of this document.

Display Options

Internationalization

lang

Language to use in the layer. The layer includes translations for some languages.

The default value for this option is en.

{
  display: {
    lang: 'en' // en, es, de, fr, it
  }
}

translations

The layer contains some pre-defined texts and translations for some languages. If your language is not included in the list of supported languages, you want to overwrite translations, or you want to add new ones, this is your option.

You need to provide an object (dictionary) to map the original text (the default english version) with its translated counterpart.

WARNING: Key sentences must be provided exactly as shown in the example. Otherwise they won't work.

Input Behavior

captureLength

Minimum number of characters a user must type in the search box for a search request to be triggered.

The default value for this option is 3.

{
  display: {
    captureLength: 3
  }
}

wait

Input checking is delayed so the user has a chance of typing more characters without immediately sending search requests. You can configure the delay in milliseconds using this option.

The default value for this option is 42.

{
  display: {
    wait: 42 // the meaning of life
  }
}

Close Behavior

closeOnClick

This option makes the layer close when the user clicks anywhere on the page other than the layer itself.

This options is enabled by default.

{
  display: {
    closeOnClick: true
  }
}

closeIfEmpty

This option makes the layer close when the user erases the content of the search box.

This options is enabled by default.

{
  display: {
    closeIfEmpty: true
  }
}

closeOnEscKey

This option makes the layer close if the user presses the ESC key.

This options is enabled by default.

{
  display: {
    closeOnEscKey: true
  }
}

Templating

templateFunctions

This option allows you to define your own template functions. Template functions transform the text passed to it so you can decide what to render in the HTML code.

Here is an example defining myBold which simply wraps the text with the <b> html tags.

{
  display: {
    templateFunctions: {
      // my helper is a function that returns a function
      myBold: function() {
        // the returned function receives the text and
        // a render function as an argument
        return function(text, render) {
          // you can transform the text before or after
          // rendering it
          return '<b>' + render(text) + '</b>';
        }
      }
    }
  }
}

Now you could use it in a custom template:

{{#results}}<h1>{{#myBold}}{{title}}{{/myBold}}</h1>{{/results}}

Take a look at the Mustache documentation to get familiar with the use of this functions and their possibilities.

templateVars

This option allows you to define your own variables to be passed to templates.

{
  display: {
    templateVars: {
      userName: "Charles Xavier"
    }
  }
}

template

A template defined here overrides the skeleton of the entire Layer. All other templates are inserted somewhere inside this one. You can use it as a starting point to build your own custom layer.

WARNING: Be Careful, changing objects ids may break your layer. Do not use a custom template if you don't know what you are doing.

NOTICE: You may feel more comfortable if you put the template code in a separate script and then import the template inside the layer options through its id.

Take a look at the Mustache documentation to get familiar with the use of templates.

Writing the layer template as Javascript code is prone to errors. The best approach is to wrap the layer template in a <script> tag with a custom type so the browser doesn't try to parse it as Javascript.

<script type="text/x-mustache-template" id="df-layer-template">
  <!-- Your HTML/Mustache code goes here -->
</script>

Now you can reference it as any other HTML element in your page. Just make sure the layer template is defined before the layer configuration.

{
  display: {
    template: document.getElementById('df-layer-template').innerHTML
  }
}

This is the default template:

<div class="df-suggestions" id="{{mainContainerId}}" hidden>
  <div id="df-results__{{mainContainerId}}"></div>
</div>

Placement

insertionPoint

By default the layer is appended to the <body> of your page. If you want to put the layer in a different place you can specify a CSS selector pointing to an element of your page.

Setting this option only just changes the place where the layer is appended. If you want to also change the way the layer is inserted relative to the insertion point take a look at insertionMethod.

{
  display: {
    insertionPoint: "#myresults"
  }
}

The previous example would append the layer to an element with the provided id attribute:

<div id="myresults">
  <h1>I'm a header</h1>
  <!-- layer will be appended here -->
</div>

NOTICE: Automatic positioning is disabled when you use the insertionPoint option. The values of the top and left options will be applied directly to the layer so it's convenient that you use a (relative/absolute) positioned container to hold the layer.

insertionMethod

This option is used in conjunction with insertionPoint and lets you specify the way the layer is inserted in the page.

Valid values for this option are:

  • append: This is the default value. The layer is appended as the last element of the specified insertion point.
  • prepend: Inserts the layer as the first element of the specified insertion point.
  • before: Inserts the layer as a sibling BEFORE the specified insertion point.
  • after: Inserts the layer as a sibling AFTER the specified insertion point.
  • html: The layer replaces the content of the specified insertion point.

NOTICE: When insertionPoint is the <body>, only append and prepend are valid methods.

Positioning

These are the default values for positioning:

{
  display: {
    position: 'absolute',
    top: undefined,
    left: undefined,
    align: 'auto',
    dtop: undefined,
    dleft: undefined,
    width: false,
    height: false,
    minWidth: 400,
    minHeight: 50
  }
}

By default the layer is positioned relative to the search box where the user types. These options affect how and where the layer is positioned.

NOTICE: You can use almost any valid CSS unit but it's safer to use px or %. No explicit unit means px.

position

This option determines the CSS position style used for the layer. You can use any valid value for this property but only fixed or absolute are actually supported.

The default value for this option is absolute, except when the search box is contained inside a tag that is positioned fixed container. In that case the position will be fixed by default.

top

Distance from the top of the layer to the top of the first positioned container. By default the layer is positioned relative to the viewport because it's appended to the <body> of the page.

The default value for this option is undefined (no explicit value).

WARNING: This option overrides any automatic positioning of the layer.

left

Distance from the left of the layer to the left of the first positioned container. By default the layer is positioned relative to the viewport because it's appended to the <body> of the page.

The default value for this option is undefined (no explicit value).

WARNING: This option overrides any automatic positioning of the layer.

align

This option controls the alignment of the layer relative to the search box.

Valid values are:

  • auto: This is the default value. The layer decides how to align itself relative to the position of the search box.
  • left: The layer's upper left corner is aligned with the lower left corner of the search box.
  • right: The layer's upper right corner is aligned with the lower right corner of the search box.
  • center: The layer is centered horizontally relative to the viewport.

WARNING: This option overrides any automatic positioning of the layer.

dtop

Used only with automatic positioning, moves the layer some pixels in the Y axis. Can be either a positive or a negative value.

dleft

Used only with automatic positioning, moves the layer some pixels in the X axis. Can be either a positive or a negative value.

width

Width of the layer.

NOTICE: When this option has a value of false, the layer adapts to its contents width.

height

Height of the layer.

NOTICE: When this option has no value, the layer adapts to the viewport height.

NOTICE: When this option has a value of false, the layer adapts to its contents height.

minWidth

The minimum width of the layer.

minHeight

The minimum height of the layer.

Results configuration

template

You can replace the default results template by your own template by using this option.

The templates are defined using the Mustache template system.

Here is the default template:

{{#results}}
  <div class="df-suggestion" tabindex="-1"
    data-role="result result-link" data-value="{{term}}">
      {{#highlight}}{{term}}{{/highlight}}
  </div>
{{/results}}

Advanced Concepts

Search Parameters

rpp

Results per page, how many results you want to be returned on each query.

{
  searchParams: {
    rpp: 20
  }
}

The Standalone Script

The easiest way to try Doofinder is by using one of our layers. You get a snippet of text and then you just include it in the HTML of your website.

This is how the standard Doofinder script looks like:

<script>
var doofinder_script ='//cdn.doofinder.com/media/js/doofinder-suggestions.7.latest.min.js';
(function(d,t){var f=d.createElement(t),s=d.getElementsByTagName(t)[0];f.async=1;
  f.src=('https:'==location.protocol?'https:':'http:')+doofinder_script;
  f.setAttribute('charset','utf-8');
  s.parentNode.insertBefore(f,s)}(document,'script')
);
var dfSuggestionsLayers = [{
  "queryInput": "#query",
  "hashid": '1955a94db43999fcc211f925fc85f12c',
  "zone": "eu1",
  "display": {
    "lang": 'en'
  }
}];
</script>

And this is what it does:

  1. First of all, the URL of the layer's source code is saved in a variable.
  2. Then a function is called to create a <script> tag wherever the rest of <script> tags are in your site.
  3. Then it declares the layers to be used in the page in the dfSuggestionsLayers variable.
  4. All this time the <script> tag we created has been downloading the code asynchronously. When the code is ready then the layers are instantiated and configured.

But, what if I use RequireJS in my page? That would break my site… Well, let's see that case.

RequireJS: the easy way

This is the easiest script you can use in a RequireJS environment if you only want to copy and paste a snippet with no hassle:

<script>
  var dfUrl = '//cdn.doofinder.com/media/js/doofinder-suggestions.7.latest.min.js';
  (function(c,o,k,e){var r,t,i=setInterval(function(){t+=c;r=typeof(require)==='function';
  if(t>=o||r)clearInterval(i);if(r)require([k],e)},c)})(100, 10000, dfUrl, function(doofinder){
    doofinder.suggestions.setLayers([{
      "queryInput": "#query",
      "hashid": '1955a94db43999fcc211f925fc85f12c',
      "zone": "eu1",
      "display": {
        "lang": 'en'
      }
    }]);
  });
</script>

And this is what it does:

  1. First of all, the URL of the layer's source code is saved in a variable.
  2. Then a function is called to check periodically that the require function exists in the page. The function stops if the function is not available after 10s.
  3. Then, the layer initialization is executed manually via setLayers.

RequireJS: the hard way

If you want to add Doofinder to your existing RequireJS workflow then you can just require its source code from a URL:

// DON'T COPY AND PASTE THIS CODE DIRECTLY INTO YOUR HTML!
// This code must be integrated into your existing RequireJS-based code.
require(['//cdn.doofinder.com/media/js/doofinder-suggestions.7.latest.min.js'], function(doofinder){
  doofinder.suggestions.setLayers([{
    "queryInput": "#query",
    "hashid": '1955a94db43999fcc211f925fc85f12c',
    "zone": "eu1",
    "display": {
      "lang": 'en'
    }
  }]);
});

Configure the layers manually

In case you want to control when the layers are loaded, just pass the list of layers to the setLayers method. Just make sure that doofinder is completely loaded in your page.

doofinder.suggestions.setLayers([{
  "queryInput": "#query",
  "hashid": '1955a94db43999fcc211f925fc85f12c',
  "zone": "eu1",
  "display": {
    "lang": 'en'
  }
}]);

Change options after load

When doofinder is loaded, dfSuggestionsLayers is replaced by an array of Doofinder Configuration Objects or, if run as a module on a requirejs environment, the dfSuggestionsLayers array is created and made accesible at the browser's window object. These objects can be used to change some configuration during the execution.

This could be useful, if you wanted to change the layer behavior depending on the user in session, the screen size…

So you can do this in two steps:

  1. Change an option in the property dfSuggestionsLayers[0].layerOptions.
  2. Execute dfSuggestionsLayers[0].configure().

If you have more than one layer, you could use dfSuggestionsLayers[k] as well (where k is the position of the layer you want to change in dfSuggestionsLayers).

Example:

Imagine you want to change the layer width. The code you need to do this would be:

dfSuggestionsLayers[0].layerOptions.display.width = "100%";
dfSuggestionsLayers[0].configure();