This document describes all the options you can use to configure the Doofinder Compact 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 dfCompactLayers = [{
queryInput: "#query",
hashid: '1955a94db43999fcc211f925fc85f12c',
zone: 'eu1',
}];
dfCompactLayers
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 dfCompactLayers = [
{
queryInput: "#query",
hashid: '1955a94db43999fcc211f925fc85f12c',
zone: 'eu1'
},
{
queryInput: "#query2",
hashid: '43999fcc85f12c1955a94dbc211f925f',
zone: 'eu1'
}
];
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 dfCompactLayers = [
{
queryInput: "#query",
hashid: '1955a94db43999fcc211f925fc85f12c',
zone: 'eu1', // note we've added a comma
searchParams: { // to add a new option
rpp: 50, // this also needs a comma
transformer: null // but no comma here…
} // nor here…
},
{
queryInput: "#query2",
hashid: '43999fcc85f12c1955a94dbc211f925f',
zone: 'eu1', // no comma in the last option
}
];
In order to make things simpler, we will represent single layer options in the rest of this document by omitting the dfCompactLayers
array so you’ll see only the layer options:
{
queryInput: "#query",
hashid: '1955a94db43999fcc211f925fc85f12c',
zone: 'eu1'
}
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 element in your page that will open the search layer. This will usually point to the text box used to search on your website. But it could point to any other element, like a link.
The best value for this option is a CSS id, which should be unique and only used once in the HTML of your page. Everytime a user clicks on it, a Compact layer with a searchbox and results list will overlay your page.
{
queryInput: '#query_input_id' // a unique CSS id
}
NOTICE: If you use too generic selectors the layer will attach to all of the matching elements. Use the layer installer from the Doofinder Admin if you don’t know how to set this value.
Use generic selectors when there’s no other way to match your text box or 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
}
}
}
suggestionHit
This function will be called each time a suggestion term is clicked.
{
callbacks: {
/**
* @param {String} suggestionText Text of the clicked suggestion
*/
suggestionHit: function(suggestionText) {
// your code
}
}
}
captureForm
Captures the submit
event of the form that contains the search box. This is useful if you have any kind of icons that submit the search form; this way you can add them the same behavior as in the searchbox when you press the ENTER
key.
This option is disabled by default.
WARNING: If your page uses a single form as entry point to the whole application (usually ASP forms), don’t enable this option or the behavior of the page will break.
{
redirections: {
captureForm: false // set to `true` to enable
}
}
If no parent form relative to the searchbox is found, the layer will fall back to the default behavior (capturing the ENTER
key press).
googleAnalytics
The layer can send search events to your Google Analytics account. This option manages how search-related events are sent or if this feature must be disabled.
This option may take different forms:
- Boolean: The easy way. Just true or false.
- true: This is the default value. The layer searches for any available Google Analytics tracker in your site and uses it to send search events. If you have more than one tracker in your site or you use a custom tracker name that can’t be detected by the layer, this is not the way to go.
- false: If you want to disable Google Analytics for the layer then use this.
- String: This way you can specify a Google Analytics Account ID or a custom tracker name.
- Account ID: A Google Analytics account id, like UA-XXXX-. An ad-hoc tracker will be created to send events to the specified account.
- Custom Tracker Name: This is useful when you want to use a specific tracker because there is more than one Google Analytics tracker in the page.
- Options Object: This gives more control on the way the layer works with Google Analytics. Currently you may set any of two options:
- account: This accepts a Google Analytics Account ID or a tracker name. See String above.
- trackPageView: A boolean value, false by default. If true then the layer will send search events as page views with a query parameter with the search terms so you can [configure Site Search]. This is independent of the events being tracked by default.
// Boolean
{
googleAnalytics: true // or false
}
// String: Account ID
{
googleAnalytics: 'UA-XXXXXXX-1'
}
// String: Tracker Name
{
googleAnalytics: 'myTracker'
}
// Object
{
googleAnalytics: {
account: 'UA-XXXXXXX-1',
trackPageView: true
}
}
To learn more about how Google Analytics works in Doofinder layers take a look at this article.
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'
}
redirections
Search results contain any redirection defined for the current search terms. If the user presses the ENTER
key in the search box, she will be redirected to the URL specified from the response.
To disable redirections just set this option to false:
{
redirections: false
}
If your searchbox is located inside a form you can configure redirections to capture the form’s submit
event. Continue reading.
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.
showInMobile
Instructs doofinder whether to force the desktop version of the layer in mobile phones.
This option is disabled by default.
{
showInMobile: false // set to `true` to enable
}
WARNING: You need the mobile add-on to use Doofinder in mobile devices.
typingStopDelay
Use this option to configure the delay in ms between when the user stops typing and the event is triggered. The default value is 1000
(1s).
It is strongly recommended not to use a value less than 1000
(1s).
{
typingStopDelay: 1000
}
WARNING: This option may cause important usability concerns. Use it at your own risk.
urlHash
The layer stores its status in the hash part of the URL. If you don’t want to generate it, set this option to false.
This option is enabled by default.
{
urlHash: true // set to `false` to disable
}
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.
{
display: {
translations: {
'Results': '…',
'Search…': '…',
'Sorry, no results found.': '…',
'View less…': '…',
'View more…': '…',
'Selected Filters': '…',
'CLOSE': '…',
'CLEAR': '…',
'FILTER': '…',
'Query Too Large': '…',
'Latest Searches': '…',
'Sort by': '…',
'Relevance': '…',
'Delete': '…',
'POPULAR SUGGESTIONS': '…',
'SEARCH RESULTS': '…',
'View all {{total}} results': '…',
'Previous': '…',
'Next': '…',
'Selected Filters': '…',
'Clear all': '…',
'Suggestions:': '…',
'Did you mean:': '…'
}
}
}
currency
This is an object defining how you want prices be formatted. It has 5 attributes:
- symbol: this is the symbol you want to use for your currency, it can be either an utf-8 symbol, like
'€'
or the html escaped sequence, like'€'
- decimal: The symbol used to separate the decimal part of the price. Usually
','
or'.'
. - thousand: The symbol used to separate thousands in the price. Usually
'.'
or','
. - precision: How many decimals you want your price to have.
- format: Where to put the currency symbol in relation with the price value. It is a format string: (
"%s %v"
) where%s
is changed by the currency symbol and%v
is changed by the price value. Say you have a price of 13 euros. Then if format is:"%s%v"
the price would be shown as€13
. - forceDecimals: true by default, forces precision also for integer values.
Say you have this currency option defined:
{
display: {
currency: {
symbol: '£',
decimal: ',',
thousand: '.',
precision: 2,
format: '%s%v'
}
}
}
So a price of 13211.889 would be displayed as £13.211,89 and a price of 13211 would be displayed as £13.211,00.
NOTICE: By default the layer takes this configuration from the Doofinder servers based on the details provided for the search engine.
If you want to disable decimal formatting for integer values, disable forceDecimals
:
{
display: {
currency: {
symbol: '£',
decimal: ',',
thousand: '.',
precision: 2,
format: '%s%v',
forceDecimals: false // this changed the default value!
}
}
}
So a price of 13211 would be displayed as £13.211.
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
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
}
}
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
}
}
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-compact df-compact-desktop" id="{{ mainContainerId }}" hidden>
<div class="df-layer__content">
<div class="df-main">
<div class="df-results-block" data-role="suggestion-list" hidden>
<div class="df-results-block__header">{{#translate}}POPULAR SUGGESTIONS{{/translate}}</div>
<div class="df-results-block__content" id="df-suggestions__{{ mainContainerId }}"></div>
</div>
<div class="df-results-block" data-role="result-list">
<div class="df-results-block__header">{{#translate}}SEARCH RESULTS{{/translate}}</div>
<div class="df-results-block__content df-card-results" id="df-results__{{ mainContainerId }}"></div>
</div>
<div id="df-results-link__{{ mainContainerId }}"></div>
<div id="df-banner__{{ mainContainerId }}"></div>
</div>
<div class="df-branding">
<a class="doofinderLogo" href="http://www.doofinder.com?mktcod=REF1" target="_blank">Powered by
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 284.333 76.333" xml:space="preserve" width="80" height="30">
<g>
<path class="doofinder-logo__doo" fill="#16406E" d="M38.807,40.114c-0.44,2.52-0.76,4.75-0.96,6.69c-0.201,1.94-0.3,3.45-0.3,4.53c0,0.441,0,0.81,0,1.11
c0,0.3,0.02,0.63,0.06,0.99c-1.32,0.24-2.621,0.36-3.9,0.36c-1.121,0-2.361-0.12-3.72-0.36c-0.081-0.319-0.16-0.699-0.24-1.14
c-0.081-0.44-0.12-1.1-0.12-1.98c0-0.36,0.009-0.78,0.03-1.26c0.02-0.48,0.069-0.979,0.15-1.5c-0.561,0.92-1.23,1.791-2.01,2.61
c-0.78,0.82-1.641,1.53-2.58,2.13c-0.94,0.6-1.95,1.08-3.03,1.44c-1.08,0.36-2.22,0.54-3.42,0.54c-2.64,0-4.62-0.84-5.94-2.52
c-1.32-1.68-1.98-3.9-1.98-6.66c0-3,0.45-5.9,1.35-8.7c0.9-2.799,2.24-5.28,4.02-7.44c1.779-2.16,3.99-3.89,6.63-5.19
c2.64-1.299,5.72-1.95,9.24-1.95c0.279,0,0.549,0.011,0.81,0.03c0.26,0.021,0.489,0.03,0.69,0.03c0.439-2.359,0.75-4.359,0.93-6
c0.18-1.64,0.27-3,0.27-4.08c0-0.44-0.01-0.81-0.03-1.11c-0.021-0.3-0.051-0.63-0.09-0.99c0.68-0.12,1.459-0.21,2.34-0.27
c0.879-0.06,1.64-0.09,2.28-0.09c1.16,0,2.439,0.12,3.84,0.36c0.2,0.6,0.3,1.36,0.3,2.28c0,1.761-0.24,3.9-0.72,6.42L38.807,40.114
z M32.387,28.954c-0.36-0.08-0.71-0.129-1.05-0.15c-0.34-0.02-0.67-0.03-0.99-0.03c-1.92,0-3.55,0.48-4.89,1.44
c-1.341,0.96-2.451,2.16-3.33,3.6c-0.88,1.44-1.521,2.991-1.92,4.65c-0.4,1.66-0.6,3.17-0.6,4.53c0,2.96,0.979,4.44,2.94,4.44
c1.92,0,3.699-1.17,5.34-3.51c1.64-2.34,2.84-5.63,3.6-9.87L32.387,28.954z"></path>
<path class="doofinder-logo__doo" fill="#16406E" d="M56.587,54.274c-4.121,0-7.15-1.08-9.09-3.24c-1.94-2.16-2.91-5.12-2.91-8.88c0-2.4,0.36-4.81,1.08-7.23
c0.72-2.42,1.8-4.6,3.24-6.54c1.44-1.94,3.25-3.52,5.43-4.74c2.18-1.22,4.729-1.83,7.65-1.83c4.16,0,7.209,1.101,9.15,3.3
c1.94,2.2,2.91,5.181,2.91,8.94c0,2.48-0.351,4.92-1.05,7.32c-0.7,2.4-1.77,4.56-3.21,6.48c-1.44,1.92-3.261,3.471-5.46,4.65
C62.126,53.683,59.546,54.274,56.587,54.274z M57.367,47.794c1.52,0,2.799-0.48,3.84-1.44c1.04-0.96,1.89-2.149,2.55-3.57
c0.66-1.419,1.129-2.919,1.41-4.5c0.28-1.58,0.42-3.009,0.42-4.29c0-3.68-1.5-5.52-4.5-5.52c-1.521,0-2.781,0.5-3.78,1.5
c-1,1-1.82,2.22-2.46,3.66c-0.64,1.44-1.09,2.96-1.35,4.56c-0.26,1.6-0.39,3.021-0.39,4.26
C53.107,46.014,54.526,47.794,57.367,47.794z"></path>
<path class="doofinder-logo__doo" fill="#16406E" d="M90.067,54.274c-4.121,0-7.15-1.08-9.09-3.24c-1.94-2.16-2.91-5.12-2.91-8.88c0-2.4,0.36-4.81,1.08-7.23
c0.72-2.42,1.8-4.6,3.24-6.54c1.44-1.94,3.25-3.52,5.43-4.74c2.18-1.22,4.729-1.83,7.65-1.83c4.16,0,7.209,1.101,9.15,3.3
c1.94,2.2,2.91,5.181,2.91,8.94c0,2.48-0.351,4.92-1.05,7.32c-0.7,2.4-1.77,4.56-3.21,6.48c-1.44,1.92-3.261,3.471-5.46,4.65
C95.606,53.683,93.026,54.274,90.067,54.274z M90.847,47.794c1.52,0,2.799-0.48,3.84-1.44c1.04-0.96,1.89-2.149,2.55-3.57
c0.66-1.419,1.129-2.919,1.41-4.5c0.28-1.58,0.42-3.009,0.42-4.29c0-3.68-1.5-5.52-4.5-5.52c-1.521,0-2.781,0.5-3.78,1.5
c-1,1-1.82,2.22-2.46,3.66c-0.64,1.44-1.09,2.96-1.35,4.56c-0.26,1.6-0.39,3.021-0.39,4.26
C86.587,46.014,88.006,47.794,90.847,47.794z"></path>
<g>
<path class="doofinder-logo__finder" fill="#FF7B29" d="M116.406,29.015h-4.98c0-1.08,0.08-2.139,0.24-3.18c0.16-1.04,0.459-2.139,0.9-3.3h4.98l0.12-0.48
c0.8-4.479,2.34-7.779,4.62-9.9c2.28-2.12,5.3-3.18,9.06-3.18c1.16,0,2.19,0.06,3.09,0.18c0.9,0.12,1.81,0.32,2.73,0.6
c-0.28,1.32-0.6,2.5-0.96,3.54c-0.36,1.041-0.82,2.08-1.38,3.12c-0.521-0.159-1.041-0.29-1.56-0.39c-0.52-0.1-1.08-0.15-1.68-0.15
c-0.72,0-1.371,0.09-1.95,0.27c-0.581,0.18-1.101,0.49-1.56,0.93c-0.46,0.44-0.86,1.06-1.2,1.86c-0.34,0.801-0.63,1.821-0.87,3.06
l-0.12,0.54h6.54c0,1.161-0.081,2.23-0.24,3.21c-0.16,0.98-0.46,2.07-0.9,3.27h-6.54l-4.32,24.24
c-0.521,2.919-1.23,5.34-2.13,7.26c-0.9,1.92-1.95,3.45-3.15,4.59c-1.2,1.14-2.56,1.94-4.08,2.4
c-1.521,0.459-3.161,0.69-4.92,0.69c-1.839,0-3.66-0.28-5.46-0.84c0.201-2.4,0.861-4.56,1.98-6.48c0.441,0.16,0.93,0.29,1.47,0.39
c0.54,0.1,0.97,0.15,1.29,0.15c0.76,0,1.479-0.11,2.16-0.33c0.68-0.22,1.31-0.66,1.89-1.32c0.58-0.66,1.1-1.57,1.56-2.73
c0.459-1.161,0.85-2.68,1.17-4.56L116.406,29.015z"></path>
</g>
<path class="doofinder-logo__finder" fill="#FF7B29" d="M139.667,29.014h-3.78c0-0.12-0.01-0.24-0.03-0.36c-0.021-0.12-0.03-0.26-0.03-0.42
c0-1.04,0.1-2.01,0.3-2.91c0.2-0.9,0.5-1.83,0.9-2.79h12.12l-5.46,31.02c-1.521,0.24-2.961,0.36-4.32,0.36
c-1.24,0-2.58-0.12-4.02-0.36L139.667,29.014z"></path>
<path class="doofinder-logo__finder" fill="#FF7B29" d="M154.867,35.854c0.439-2.52,0.77-4.749,0.99-6.69c0.22-1.939,0.33-3.45,0.33-4.53c0-0.44,0-0.81,0-1.11
c0-0.3-0.021-0.63-0.06-0.99c1.32-0.24,2.64-0.36,3.96-0.36c0.6,0,1.2,0.03,1.8,0.09s1.239,0.15,1.92,0.27
c0.08,0.321,0.159,0.7,0.24,1.14c0.08,0.44,0.12,1.101,0.12,1.98c0,0.36-0.01,0.72-0.03,1.08c-0.021,0.36-0.07,0.8-0.15,1.32
c0.48-0.84,1.08-1.64,1.8-2.4c0.72-0.759,1.54-1.419,2.46-1.98c0.92-0.56,1.91-1,2.97-1.32c1.059-0.319,2.13-0.48,3.21-0.48
c2.4,0,4.269,0.61,5.61,1.83c1.34,1.221,2.01,3.25,2.01,6.09c0,0.6-0.04,1.24-0.12,1.92c-0.081,0.681-0.18,1.4-0.3,2.16
l-3.48,19.68c-1.521,0.24-2.98,0.36-4.38,0.36c-1.401,0-2.781-0.12-4.14-0.36l3.36-19.02c0.159-0.8,0.24-1.56,0.24-2.28
c0-1.2-0.261-2.04-0.78-2.52c-0.521-0.48-1.26-0.72-2.22-0.72c-0.561,0-1.19,0.141-1.89,0.42c-0.7,0.28-1.41,0.87-2.13,1.77
c-0.72,0.9-1.42,2.17-2.1,3.81c-0.681,1.641-1.26,3.801-1.74,6.48l-2.22,12.06c-1.56,0.24-3.021,0.36-4.38,0.36
c-1.401,0-2.781-0.12-4.14-0.36L154.867,35.854z"></path>
<path class="doofinder-logo__finder" fill="#FF7B29" d="M214.627,40.114c-0.441,2.52-0.762,4.75-0.961,6.69c-0.201,1.94-0.301,3.45-0.301,4.53
c0,0.441,0,0.81,0,1.11c0,0.3,0.021,0.63,0.061,0.99c-1.32,0.24-2.619,0.36-3.9,0.36c-1.119,0-2.359-0.12-3.719-0.36
c-0.081-0.319-0.16-0.699-0.24-1.14c-0.081-0.44-0.12-1.1-0.12-1.98c0-0.36,0.009-0.78,0.03-1.26c0.02-0.48,0.069-0.979,0.15-1.5
c-0.561,0.92-1.23,1.791-2.01,2.61c-0.78,0.82-1.641,1.53-2.58,2.13c-0.94,0.6-1.95,1.08-3.03,1.44c-1.08,0.36-2.22,0.54-3.42,0.54
c-2.64,0-4.62-0.84-5.94-2.52c-1.32-1.68-1.98-3.9-1.98-6.66c0-3,0.45-5.9,1.35-8.7c0.9-2.799,2.24-5.28,4.02-7.44
c1.779-2.16,3.99-3.89,6.63-5.19c2.64-1.299,5.72-1.95,9.24-1.95c0.279,0,0.549,0.011,0.811,0.03c0.26,0.021,0.488,0.03,0.689,0.03
c0.439-2.359,0.75-4.359,0.93-6c0.18-1.64,0.27-3,0.27-4.08c0-0.44-0.01-0.81-0.029-1.11c-0.021-0.3-0.051-0.63-0.09-0.99
c0.68-0.12,1.459-0.21,2.34-0.27c0.879-0.06,1.641-0.09,2.279-0.09c1.16,0,2.439,0.12,3.84,0.36c0.201,0.6,0.301,1.36,0.301,2.28
c0,1.761-0.24,3.9-0.721,6.42L214.627,40.114z M208.207,28.954c-0.361-0.08-0.711-0.129-1.051-0.15c-0.34-0.02-0.67-0.03-0.99-0.03
c-1.92,0-3.55,0.48-4.89,1.44c-1.341,0.96-2.451,2.16-3.33,3.6c-0.88,1.44-1.521,2.991-1.92,4.65c-0.4,1.66-0.6,3.17-0.6,4.53
c0,2.96,0.979,4.44,2.94,4.44c1.92,0,3.699-1.17,5.34-3.51c1.64-2.34,2.84-5.63,3.601-9.87L208.207,28.954z"></path>
<path class="doofinder-logo__finder" fill="#FF7B29" d="M229.686,41.794c0.24,1.92,0.88,3.351,1.92,4.29c1.04,0.94,2.56,1.41,4.561,1.41
c1.599,0,3.009-0.169,4.229-0.51c1.22-0.339,2.51-0.79,3.87-1.35c0.64,0.801,1.069,1.77,1.29,2.91c0.22,1.14,0.33,2.35,0.33,3.63
c-0.681,0.32-1.47,0.61-2.37,0.87c-0.9,0.26-1.83,0.48-2.79,0.66c-0.96,0.18-1.92,0.32-2.88,0.42c-0.96,0.1-1.82,0.15-2.58,0.15
c-2.44,0-4.53-0.3-6.271-0.9c-1.739-0.6-3.18-1.449-4.319-2.55c-1.141-1.1-1.98-2.439-2.521-4.02c-0.54-1.58-0.81-3.33-0.81-5.25
c0-2.439,0.42-4.839,1.26-7.2c0.84-2.359,2.03-4.47,3.57-6.33c1.539-1.86,3.42-3.36,5.64-4.5c2.22-1.14,4.71-1.71,7.47-1.71
c1.32,0,2.551,0.161,3.69,0.48c1.14,0.32,2.13,0.81,2.97,1.47s1.5,1.47,1.98,2.43c0.479,0.96,0.72,2.08,0.72,3.36
c0,1.8-0.42,3.36-1.26,4.68c-0.84,1.32-1.961,2.44-3.36,3.36c-1.4,0.92-2.99,1.67-4.77,2.25c-1.78,0.58-3.63,1.011-5.55,1.29
L229.686,41.794z M233.105,35.674c1.52-0.24,2.76-0.549,3.72-0.93c0.96-0.379,1.72-0.8,2.28-1.26c0.56-0.459,0.939-0.93,1.14-1.41
s0.301-0.96,0.301-1.44c0-0.759-0.251-1.38-0.75-1.86c-0.501-0.48-1.17-0.72-2.011-0.72c-1.04,0-1.99,0.23-2.85,0.69
c-0.86,0.46-1.61,1.071-2.25,1.83c-0.641,0.76-1.19,1.63-1.65,2.61c-0.46,0.981-0.81,1.971-1.05,2.97L233.105,35.674z"></path>
<path class="doofinder-logo__finder" fill="#FF7B29" d="M254.886,35.854c0.439-2.52,0.77-4.749,0.99-6.69c0.219-1.939,0.33-3.45,0.33-4.53c0-0.44,0-0.81,0-1.11
c0-0.3-0.021-0.63-0.061-0.99c1.32-0.24,2.64-0.36,3.96-0.36c0.601,0,1.2,0.03,1.8,0.09c0.601,0.06,1.239,0.15,1.92,0.27
c0.08,0.321,0.16,0.7,0.24,1.14c0.08,0.44,0.12,1.101,0.12,1.98c0,0.36-0.01,0.72-0.03,1.08c-0.021,0.36-0.07,0.8-0.149,1.32
c0.399-0.72,0.899-1.43,1.5-2.13c0.6-0.7,1.27-1.33,2.01-1.89c0.739-0.56,1.56-1.01,2.46-1.35c0.9-0.339,1.89-0.51,2.97-0.51
c0.84,0,1.561,0.1,2.16,0.3c0.039,0.16,0.061,0.321,0.061,0.48c0,0.161,0,0.34,0,0.54c0,1.121-0.141,2.28-0.42,3.48
c-0.281,1.2-0.66,2.2-1.141,3c-0.24-0.039-0.5-0.08-0.78-0.12c-0.28-0.039-0.64-0.06-1.079-0.06c-1.641,0-2.991,0.28-4.051,0.84
c-1.06,0.561-1.93,1.35-2.609,2.37c-0.681,1.02-1.221,2.25-1.62,3.69c-0.4,1.44-0.761,3.04-1.08,4.8l-2.22,12.06
c-1.561,0.24-3.021,0.36-4.381,0.36c-1.4,0-2.78-0.12-4.14-0.36L254.886,35.854z"></path>
<circle class="doofinder-logo__finder" fill="#FF7B29" cx="145.924" cy="15.034" r="4.688"></circle>
</g>
</svg>
</a>
</div>
</div>
</div>
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
}
}
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>
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.
Results configuration
scrollOffset
Distance in px
from the bottom of the results content. When the user reached that point scrolling the results a new results page is triggered.
The default value for this option is 500
.
{
display: {
results: {
scrollOffset: 500 // no units allowed here
}
}
}
urlParams
Object (a dictionary) with parameters to be appended to the URL of each result.
{
display: {
results: {
urlParams: {
source: 'doofinder',
'campaign-id': 123456 // some keys need to be quoted
}
}
}
}
NOTICE: This only works if you use the {{#url-params}}{{/url-params}}
function in your results template (the default template uses it).
In the previous example, this URL:
http://www.example.com/products/P1
would be converted to:
http://www.example.com/products/P1?source=doofinder&campaign-id=123456
queryParam
This option makes the search parameters being added to the urlParams
in the specified key.
{
display: {
results: {
queryParam: 'q'
}
}
}
NOTICE: This only works if you use the {{#url-params}}{{/url-params}}
function in your results template (the default template uses it).
In the previous example, this URL:
http://www.example.com/products/P1
would be converted to:
http://www.example.com/products/P1?q=whatever-you-searched
initialLayout
The way the results are displayed by default when the layer loads. This option can be grid
or list
.
{
display: {
results: {
initialLayout: 'grid'
}
}
}
template
You can replace the default results template by your own template by using this option.
If you need to include custom fields from your data feed, you should check also the [transformer] option to see how to receive those fields in the json response from the server.
The templates are defined using the Mustache template system.
Here is an example which defines a very simple custom template that overrides the default:
layerOptions = {
display: {
results: {
template: '{{#results}}<h1>{{title}}</h1>{{/results}}'
}
}
}
Notice: To make templating easier, you can write your custom template inside a special <script type="text/x-mustache-template">
tag with a unique id. Then you can reference the template by id from the layer configuration script. The template must be declared before the Doofinder script.
Warning: Some templates are more sensitive to changes than others. Note that if you modify the default templates of the layer, the layer may malfunction in the future. To restore the correct operation of the layer simply deactivate the custom template in the layer options.
As you can see there are also some sections which are functions like: format-currency, remove-protocol, url-params and translate. You can also define your own functions with the Template Functions option.
{{#is_first}}
{{#banner}}
<div class="df-banner">
<a {{#blank}}target="_blank" rel="noopener noreferer"{{/blank}} href="{{link}}" data-role="banner" data-banner="{{id}}">
{{#image}}
<img src="{{#remove-protocol}}{{image}}{{/remove-protocol}}">
{{/image}}
{{#html_code}}
{{{html_code}}}
{{/html_code}}
</a>
</div>
{{/banner}}
{{/is_first}}
{{#total}}
{{#results}}
<div class="df-card" data-role="result">
<a class="df-card__main" href="{{#url-params}}{{{link}}}{{/url-params}}" data-role="result-link" data-dfid="{{dfid}}">
{{#image_link}}
<figure class="df-card__image">
<img src="{{#remove-protocol}}{{image_link}}{{/remove-protocol}}" alt="{{title}}">
</figure>
{{/image_link}}
<div class="df-card__content">
<div class="df-card__title">{{title}}</div>
<div class="df-card__description">{{{description}}}</div>
{{#price}}
<div class="df-card__pricing">
<span class="df-card__price {{#sale_price}}df-card__price--old{{/sale_price}}">
{{#format-currency}}{{price}}{{/format-currency}}
</span>
{{#sale_price}}
<span class="df-card__price df-card__price--new">
{{#format-currency}}{{sale_price}}{{/format-currency}}
</span>
{{/sale_price}}
</div>
{{/price}}
{{#df_rating}}
<div>
<div class="df-rating" title="{{df_rating}}">
<div class="df-rating__value" style="width: {{#rating-percent}}{{df_rating}}{{/rating-percent}}">
<i>★</i><i>★</i><i>★</i><i>★</i><i>★</i>
</div>
<div class="df-rating__placeholder">
<i>★</i><i>★</i><i>★</i><i>★</i><i>★</i>
</div>
</div>
</div>
{{/df_rating}}
</div>
</a>
</div>
{{/results}}
{{/total}}
{{^total}}
{{#noResultsHTML}}{{{noResultsHTML}}}{{/noResultsHTML}}
{{^noResultsHTML}}
<p class="df-no-results">{{#translate}}Sorry, no results found.{{/translate}}</p>
{{/noResultsHTML}}
{{/total}}
maxResults
In this layer, also, you can configure how many results you want to display when Doofinder does its first search. Default 2.
{
display: {
results: {
maxResults: 2
}
}
}
allResultsURL
You can specify an URL where redirect when the user click a suggestion or the View all link at the bottom of the layer. This URL can be defined as a string with the tag %query%. This tag will be replace by the query.
{
display: {
results: {
allResultsURL: 'https://example.com/more_results.php&q=%query%'
}
}
}
Or you can define a function that receives the query as a parameter.
{
display: {
results: {
allResultsURL: function(query) {
return 'https://www.google.es/search?q=' + query;
}
}
}
}
If allResultsURL is false or not defined, the View all link will not appear and when the user clicks a suggestion, the searched term will be replaced by this suggestion.
Suggestions
maxSuggestions
In case the suggestions are enabled in the control panel, allows to control how many of them should appear, by default, this number is two.
{
display: {
suggestions: {
maxSuggestions: 2
}
}
}
Header configuration
Layers come with a special header section which will be more or less complete depending on the type of layer you’re using.
The header is usually in charge of giving details like the number of results in the search response, or providing buttons for certain actions.
show
Indicates if the header must be displayed or not.
The default value for this option is true
.
display: {
header: {
show: true
}
}
template
display: {
header: {
template: '…'
}
}
Notice: To make templating easier, you can write your custom template inside a special <script type="text/x-mustache-template">
tag with a unique id. Then you can reference the template by id from the layer configuration script. The template must be declared before the Doofinder script.
Warning: Some templates are more sensitive to changes than others. Note that if you modify the default templates of the layer, the layer may malfunction in the future. To restore the correct operation of the layer simply deactivate the custom template in the layer options.
The default template is:
<b>{{#translate}}Results{{/translate }}:</b>
<span data-role="total">{{ total }}</span>
Mobile Version
If you have the mobile version enabled for your search engine you can tweak some aspects of the integration.
Under the mobile
key you can set or override most of the options of the layer. Most of the options available in the main layer are available for the mobile layer as well.
If you want to deactivate the mobile version for a layer just set the mobile option to false.
{
mobile: false
}
maxWidth
The maximum viewport width where the mobile version will be shown. By default 767px
.
{
mobile: {
maxWidth: 767
}
}
toggleInput
If you have different search boxes for desktop and mobile, you can set the toggleInput
option under the mobile
key.
NOTICE: In V5 this option could be set via queryInput or toggleInput indistinctly. Since V6 the only valid option is toggleInput.
{
mobile: {
toggleInput: '#mobile_search_box'
}
}
hashid
If you want to use a different SearchEngine for your mobile version you can set a different hashid.
{
mobile: {
hashid: '1955a94db43999fcc211f925fc85f12c'
}
}
voiceSearch
Voice Search is enabled by default in compatible mobile devices. Devices that don’t support Voice Search won’t see anything special in the UI.
The default value for this options is true. If you want to disable Voice Search for all users just set this option to false.
{
mobile: {
voiceSearch: false
}
}
Display Options
You can set the display options, since the mobile layer is fullscreen, positioning options have no sense.
initialSearch
Displays the top searches when the mobile layer is opened and no query has been done.
The value of this option is true by default, unless there’s a background image defined in the templateVars.
If you want to show an empty layer, set this option to false.
{
mobile: {
display: {
initialSearch: false
}
}
}
If you want to perform a custom search just put the search terms there:
{
mobile: {
display: {
initialSearch: 'red boots'
}
}
}
closeOnHit
Closes the mobile layer when a result is clicked. This is disabled by default but you should consider using it when your site is a one-page-application that loads URLs with AJAX without changing page location.
The default value of this option is false.
{
mobile: {
display: {
closeOnHit: false
}
}
}
template
You can customize your layer template like in the desktop version but the template in this case is different:
<div class="df-mobile"{{#images.body}} style="background-image:url('{{images.body}}');"{{/images.body}} id="{{ mainContainerId }}" hidden>
<div class="df-mobile__wrapper">
<div class="df-mobile__header" id="df-mobile__header__{{ mainContainerId }}">
{{#images.header}}
<div class="df-mobile__header__image">
<img src="{{ images.header }}">
</div>
{{/images.header}}
<form action="" method="get">
<div class="df-mobile__searchbox" data-empty="true">
{{#voicesearch}}
<button type="button" data-role="voicesearch">
<svg fill="#606569" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12,14c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3S9,3.34,9,5v6C9,12.66,10.34,14,12,14z"/>
<path d="M17,11c0,2.76-2.24,5-5,5s-5-2.24-5-5H5c0,3.53,2.61,6.43,6,6.92V21h2v-3.08c3.39-0.49,6-3.39,6-6.92H17z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
</button>
{{/voicesearch}}
{{#imagesearch}}
<button type="button" data-role="imagesearch" class="fileContainer">
<svg id="df-mobile__imagesearch_icon__{{ mainContainerId }}" fill="#606569" width="24" height="24" viewBox="0 0 24 24"
enable-background="new 0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="3.2"/>
<path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
<svg id="df-mobile__imagesearch_loading__{{ mainContainerId }}" class="spinner" width="24px" height="24px"
viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<circle class="path" fill="none" stroke-width="6"
stroke-linecap="round" cx="33" cy="33"
r="30"></circle>
</svg>
<input data-role="image-search-control" id="df-mobile__imagesearch__{{ mainContainerId }}" type="file" accept="image/*"/>
</button>
{{/imagesearch}}
<svg class="df-mobile__searchbox__loupe" fill="#606569" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
<input type="search" placeholder="{{#translate}}{{placeholderText}}{{/translate}}" id="df-mobile__searchbox__{{ mainContainerId }}" autocapitalize="off" autocomplete="off" autocorrect="off">
<button type="button" data-role="clear">{{#translate}}CLEAR{{/translate}}</button>
<button type="button" data-role="close">{{#translate}}CLOSE{{/translate}}</button>
</div>
<div class="df-mobile__header__actions" id="df-mobile__header__actions__{{ mainContainerId }}"></div>
<div class="df-mobile__suggestions" id="df-mobile-suggestions__{{ mainContainerId }}" data-role="suggestion-list" hidden>
</div>
</form>
</div>
<div class="df-mobile__content" id="df-mobile__content__{{ mainContainerId }}"></div>
<button class="df-mobile__action-button df-in df-out" type="button" data-role="close" data-scroll-in-out>
<svg fill="#606569" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
</button>
<button class="df-mobile__action-button df-in df-out" type="button" data-role="scrolltop" data-scroll-in-out>
<svg fill="#606569" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0V0z" fill="none"/>
<path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/>
</svg>
</button>
</div>
<div class="df-mobile__overlay" data-role="toggle-filters"></div>
<div class="df-mobile__aside">
<div class="df-mobile__aside__actions">
<button class="df-mobile__button" type="button" data-role="toggle-filters">{{#translate}}CLOSE{{/translate}}</button>
<button class="df-mobile__button" type="button" data-role="clear-filters">{{#translate}}CLEAR{{/translate}}</button>
</div>
<div id="df-mobile__aside__sorting__{{ mainContainerId }}"></div>
<div class="df-mobile__aside__content" id="df-mobile__aside__content__{{ mainContainerId }}"></div>
</div>
</div>
Notice: To make templating easier, you can write your custom template inside a special <script type="text/x-mustache-template">
tag with a unique id. Then you can reference the template by id from the layer configuration script. The template must be declared before the Doofinder script.
Warning: Some templates are more sensitive to changes than others. Note that if you modify the default templates of the layer, the layer may malfunction in the future. To restore the correct operation of the layer simply deactivate the custom template in the layer options.
{
mobile: {
display: {
template: document.getElementById('…').innerHTML
}
}
}
templateVars
Like in the desktop version of the layer, you can set variables to be used in the template. In this case some variables are available by default:
{
mobile: {
display: {
templateVars: {
placeholderText: 'Search…',
images: {
header: null,
body: null
}
}
}
}
}
placeholderText
This is a special variable that corresponds to the text that will be used as the placeholder for the search input in the mobile layer.
images
This is a special variable / object that you can use to configure some images to adapt the look and feel of the layer:
header
: will appear before the search box.body
: will appear as a centered background image in the layer. Using this option impliesmobile.display.showMostSearched
being false.
NOTICE: You’re not forced to use these values, they’re provided to avoid modifying the layer template just to add a custom header/body image. If you need a third image just add it and adapt the template to your needs.
templateFunctions
Like in the desktop version you can create your own template functions. Refer to templateFunctions for more information.
{
mobile: {
display: {
templateFunctions: {}
}
}
}
Results Configuration
template
You can set your own results template to show extra content in your results or shape the content as you want.
Refer to Results Template Configuration in the desktop version for more information.
{
mobile: {
display: {
results: {
template: document.getElementById('…').innerHTML
}
}
}
}
Facets Configuration
You can override almost any facets options from the desktop configuration for the mobile version of the layer. Refer to Facets Configuration for more details.
{
display: {
facets: {
startCollapsed: false
}
},
mobile: {
display: {
facets: {
startCollapsed: true
}
}
}
}
Advanced Concepts
Search Parameters
filter
If you want to include only results matching some condition you can use the filter parameter in your layer configuration.
See Filter Parameters in the Search API reference to learn more about filters.
{
searchParams: {
filter: {
categories: ['Awesome', 'Other'],
brand: ['My Brand'],
best_price: {
gte: 100
}
}
}
}
exclude
If you want to exclude results matching some condition you can use the exclude parameter in your layer configuration.
{
searchParams: {
exclude: {
categories: ['This not', 'Other'],
brand: ['Excluded brand']
}
}
}
sort
You can specify fields to sort results. See Sort Parameters:
{
searchParams: {
sort: [
{'_score': 'desc'},
{'price': 'asc'},
{'brand': 'desc'}
]
}
}
WARNING: In order to being able to sort by multi-word fields (like title), that field must be included into the Custom Sorting fields of the Advanced Settings of our administration panel.
type
If you want to restrict the searches to some of your data types. Just set this property:
In the example above you will be searching just products and posts.
query_name
If you want to execute always a specific kind of query you can set this option (see query_name in Dark magic parameters):
{
searchParams: {
query_name: 'fuzzy'
}
}
min_score
The minimum score required for results to be considered valid. Results with scoring below this won’t be included in the search results.
{
searchParams: {
min_score: 0.5
}
}
transformer
Doofinder search servers return the results transformed so layers can work without too much configuration.
The default transformer is basic
which populates these fields:
title
: The title of the product.type
: This usually will be product.hashid
: The unique identificator of your search engine.dfid
: The doofinder id of your product.link
: The link to your product.image_link
: The image source of the product.description
: The description of the product.price
: The price of the product.sale_price
: The sale price of the product, if any.
If you want to display any other data you’ve indexed or the original field names, first you have to set this option to null:
{
searchParams: {
transformer: null
}
}
This will make the server to return all your data when querying.
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-compact.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 dfCompactLayers = [{
queryInput: '#query',
hashid: '1955a94db43999fcc211f925fc85f12c',
zone: 'eu1',
display: {
lang: 'en'
}
}];
</script>
And this is what it does:
- First of all, the URL of the layer’s source code is saved in a variable.
- Then a function is called to create a <script> tag wherever the rest of <script> tags are in your site.
- Then it declares the layers to be used in the page in the dfCompactLayers variable.
- 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-compact.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.compact.setLayers([{
queryInput: '#query',
hashid: '1955a94db43999fcc211f925fc85f12c',
zone: 'eu1',
display: {
lang: 'en'
}
}]);
});
</script>
And this is what it does:
- First of all, the URL of the layer’s source code is saved in a variable.
- 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.
- 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-compact.7.latest.min.js'], function(doofinder){
doofinder.compact.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.compact.setLayers([{
queryInput: "#query",
hashid: '1955a94db43999fcc211f925fc85f12c',
zone: 'eu1',
"display": {
"lang": 'en'
}
}]);
Change options after load
When doofinder is loaded, dfCompactLayers is replaced by an array of Doofinder Configuration Objects or, if run as a module on a requirejs environment, the dfCompactLayers 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:
- Change an option in the property dfCompactLayers[0].layerOptions.
- Execute dfCompactLayers[0].configure().
If you have more than one layer, you could use dfCompactLayers[k] as well (where k is the position of the layer you want to change in dfCompactLayers).
Example:
Imagine you want to change the number of results displayed in the layer. The code you need to do this would be:
dfCompactLayers[0].layerOptions.results.maxResults = 5;
dfCompactLayers[0].configure();
How to modify the search response
In certain situations you may want to customize the search response to modify some data. To do that you can register response processors that will receive the response object as an argument and must return it (modified or not) as the result so it can be passed to the layer components for rendering.
WARNING: Be careful, if you perform resource-intensive operations the layer rendering may slow down. Try to perform very simple operations and only when there’s no other way to get the desired results.
The best way to register a processor is to use the loaded callback:
var changeTitle = function(result){
result.title += ' (processed)';
return result;
};
// …
{
callbacks: {
loaded: function(instance) {
// Register a processor that changes the title of the results
instance.layer.controller.processors.push(function(response){
response.results = response.results.map(changeTitle);
return response;
});
}
}
}
You can add more than one processor. All processors will be executed in order, receiving the result returned by the previous processor executed.