Integration
We provide a JavaScript autocomplete widget which works directly with the JSON
API. No programming is necessary, just include the
script and CSS into your webpage and provide a simple configuration.
With a few lines of configuration, you can get a Hero Layout autocomplete widget like this:
With a few lines of configuration, you can get a Line Layout autocomplete widget like this:
With a few lines of configuration, you can get a Grid Layout autocomplete widget like this:
Autocomplete integration ¶
Paste this line into your
<head>
element:
<link rel="stylesheet" href="https://cdn.luigisbox.com/autocomplete.css"/>
1.
Add autocomplete.css
reference to your <head>
element.
Paste this line into your
<head>
element for faster autocomplete load:
<link rel="dns-prefetch" href="//live.luigisbox.com">
2.
Add dns-prefetch instructions for browsers, for faster autocomplete
experience.
3.
If you are currently using some other autocomplete system, disable it.
<form>
<input id="autocomplete"> <!-- your search box -->
</form>
<script>
function LBInitAutocomplete() {
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
]
}, '#autocomplete')
}
</script>
<script src="https://cdn.luigisbox.com/autocomplete.js" async onload="LBInitAutocomplete()"></script>
4.
Locate the HTML element of your search box, and add the initialization code
after its input
element.
5.
You can configure the autocomplete widget to enable extra features. See
Options reference for details and examples.
<script src="https://cdn.luigisbox.com/autocomplete.js" async="async"/>
<script>
window.addEventListener('CookiebotOnTagsExecuted', function (e) {
LBInitAutocomplete();
});
</script>
If you are using Cookiebot to manage cookie consent, we have seen cases where Cookiebot is interfering with the script onload event. If you initialize autocomplete via the onload event such as in the example above, the onload handler will never be executed. If you see this issue, try initializing via Cookiebot's CookiebotOnTagsExecuted
event.
Autocomplete parameters ¶
<script>
function LBInitAutocomplete() {
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
]
}, '#autocomplete', document, ['.selector-to-wait'])
}
</script>
AutoComplete
object accepts 4 main parameters:
REQUIRED1. settings as JSON object of defined options.
REQUIRED2. selector of input
element.
optional3. HTML document.
optional4. Array of selectors to wait for, when start of autocomplete.js depends on some HTML element:
Content Security Policy ¶
If your website is using Content Security Policy, you need to add following rules to allow Luigi's Box autocomplete.js to work.
CSP directive | Value |
---|---|
connect-src |
https://live.luigisbox.com |
script-src |
https://cdn.luigisbox.com |
style-src |
https://cdn.luigisbox.com |
Options reference ¶
In the HTML code, find the
input
element where users type the query and add an initialization script. This as a complex example which is showcasing many features, your integration will probably be much simpler.
<form>
<input id="autocomplete">
</form>
<script>
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: "item",
name: "",
size: 6,
attributes: ['category.hl->1', 'brand.last', 'ean']
},
{
type: "category",
name: "Categories",
size: 2,
attributes: ['categories_hierarchy.last-1<-2']
},
{
type: "article",
name: "Articles",
size: 2,
}
],
Actions: [
{
forRow: function(row) {
return row.type === 'item';
},
iconUrl: 'https://www.myshop.com/assets/buy.png',
title: 'Buy',
action: function(e, result) {
e.preventDefault();
$.post('/add-to-cart', {product_id: result.attributes.code})
}
}
],
Width: 500
}, '#autocomplete')
</script>
AutoComplete accepts these options:
Option | Comment | Example |
---|---|---|
Layout REQUIRED string |
String, which specifies what kind of layout will be used. Supported layouts are heromobile , hero , line or grid . If you do not specify this option, we will fallback to an obsolete layout, which is no longer supported and most of the features described here won't work. |
Layouts |
TrackerId REQUIRED string |
Identifier of your site within Luigi's Box. | |
Types REQUIRED array |
List of content types which should be searched and displayed. Each content type must have a separate configuration. See Types parameters. | Types parameters |
ShowAllTitle optional string deprecated |
If set, the widget will display a button which, when clicked, starts a new search (as if Enter was pressed in the input search box). Only supported in line and grid layouts. Title of the button will be set to value of this parameter. This option is now deprecated, see Localisation. |
Submit button |
Width optional number |
Autocomplete width (px). If not set, the autocomplete widget will inherit width of the search box input element. | |
Variant optional string |
String label, which distinguishes different Autocomplete configurations. Use this when you want to test different configurations in an AB test. | A/B test different Autocomplete configurations |
DidYouMean optional function |
Function that gets called with three parameters input , matches and resultSetType , which returns a text information to show on the top of the search results to distinguish different match modes: exact match (we found exactly what was typed as a query), fuzzy/partial match (we found only similar results when considering typos and misspellings) or mixed match (a combination of exact and partial matches). |
Did you mean? |
FollowSuggestedUrl optional boolean |
Boolean indicating whether to redirect users to a url suggested by the server, which could be a matching category page or a Fixit url. (default: false) | |
CloseWhenQueryIsEmpty optional boolean |
Boolean - by default true , if set to false , AutoComplete will not close when user clears input (with backspace for example) and top recommendations will be shown instead. |
|
Hint optional function deprecated |
Function that gets called with the current query as an argument and must return a string, which is displayed on the top of the search results, telling the users how to proceeed if they want to perform a regular search request (e.g., press enter). This option is now deprecated, see Localisation. | Display search hint |
GATrackingCode optionalstring |
String, which specifies Google Analytics Tracking Code for reporting custom events. By default we send 'display', 'click' on product and 'conversion' (if you configured custom Actions) to a specified Google Analytics account. | Google Analytics tracking |
TypingSuggestions optional boolean |
Boolean, if true, the searchbox will show simulated typing of example queries, drawing attention to the searchbox. | Typing Suggestions |
FormatForDisplay optional function |
function(result), called for each result before it is displayed and provides a way to update result attributes when necessary, or to not display the result at all (return null ). |
Format text |
Select optional function |
function(event, result, row), called when result is selected (either by clicking or by keyboard selection). Allows custom action on selection - cancel the event by calling event.preventDefault and handle the selection yourself. |
Google Analytics tracking |
BeforeRender function |
function(query, results), called before autocomplete widget is rendered and must return an array of results. | Sort results before rendering |
AfterRender optional function |
function(query, results), called when autocomplete widget is rendered. | Google Analytics tracking |
BeforeOpen optional function |
Callback function, called before autocomplete widget is shown. It is called before the widget opens, e.g., when you type first letter into the search box which cases the widget to appear. | |
AfterClose optional function |
Callback function, called after autocomplete widget is closed (either explicitely, or implicitely, because there are no results to be shown). | |
Actions optional array |
Array of actions that may be applicable for a row. Each element of the array is an object with the following properties see Action properties. | Buy, Expandable list. |
Align optionalstring |
String, with two options: input or center . Setting Align to center will keep the widget centered on then screen. Setting align to input will keep the widget's left side aligned with the left side of the search box. See the associated recipe for pictures. Supported only in Grid layout. |
Grid Layout - Align option |
GridPosition optionalstring |
String, with two options: left or right . This option drives the column layout of the grid. Settings this option to left will place the "main" type (usually products) with images and prices on left side while the other types will be in the right column. With GridPosition: right the main type will be on the right side, and the other types in the left column. See the associated recipe for pictures. |
Position of Grid layout |
_Attributes optional function |
[DEPRECATED, use attributes configuration within Types parameter] Function returning a list of additional attributes to show in results. Each item of the list should be a hash with two keys: value is what will be displayed, value.untouched is what will be shown in tooltip, and therefore should be without any <em> tags. |
|
PriceFilter optional object deprecated |
Object with key-value pairs - locale , decimals , prefixed , symbol . This option is now deprecated, see Localisation. |
Price Filter |
NoResultsMessage optional function deprecated |
Function, where you can specify your custom no results message in Hero Layout. This option is now deprecated, see Localisation. | No Results Message |
ShowHeroProduct optional boolean |
Boolean - by default true , specifies whether the hero product is displayed separately in its own wrapper. |
Show Hero Product |
PlaceholderText optional string deprecated |
String - by default Search for... , specifies placeholder that will be displayed in the search box. Supported layout is only heromobile . This option is now deprecated, see Localisation. |
|
ShowAllCallback optional function |
Search-form submission callback. Useful if autocomplete should submit the searchbox in a non-standard way, e.g. when the enclosing form is missing. |
Submitting search outside form context |
AutoReposition optional boolean |
Boolean, default false . When enabled, Autocomplete widget is recalculating its position based on the input field, to be nicely aligned in every situation (after resizing, scrolling...). |
Auto reposition |
Locale REQUIRED string |
If set, appropriate localisation patterns will be used. This is useful if your website has multiple language versions. | Localisation |
Translations optional object |
Object used as dictionary, including locale keys and translation themselves. | Localisation |
Types parameters ¶
Types parameter | Comment | Example |
---|---|---|
type REQUIRED string |
Type identifier (e.g., item or category ). |
|
context optional |
This option can be used to request a specific autocomplete type when you are using filtering. You must always set the type parameter to the real type, and context parameter to the requested filtered type. Note that this feature requires that you have indexed your data in a specific way. See Autocomplete filtering for more details |
|
name REQUIRED string or function |
Title shown at the top of the autocomplete section where items of this type will be shown. | Dynamic section titles |
size optional number |
How many items of that particular type you want to show. | |
placement optional string |
Position, where results will be placed. If one of the types has placement defined, it has to be defined in all other types.Only supported placement parameters are: main - items will be placed in the main section in Grid layout and wrapped with luigi-ac-main class, others - items will be placed in the sidebar section in Grid layout and wrapped with luigi-ac-others class. Placement is also supported in Line layout and is especially useful when using the 2-column variant, because it lets you precisely specify which column a type should go into. |
Custom placement, 2-column layout |
attributes optional array |
Array of attribute expressions which will be evaluated to show item attributes alongside its title. Supported only in Line layout. See example on the right, or the Attributes expressions section. | Display additional attributes |
recommend optional object |
Display autocomplete section populated by most popular items when user clicks into the search field without typing a query. Value is an object which may contain name and size keys for specifying different name at the top of the section and how many top items to display. If you use an empty object, name and size values will be inherited from the parent type configuration. |
Display recommended items |
defaultFilters optional |
Object with key/value pairs, representing the filters to apply when querying for autocomplete suggestions. | Filtering in autocomplete |
filters optional |
Custom function which must return key/value pairs, representing the filters to apply when querying for autocomplete suggestions. | Filtering in autocomplete |
heroName optional string Hero layout only |
String which specifies separate title for Hero product. | Show Hero Product |
Action properties ¶
Actions property | Comment |
---|---|
forRow optional function |
function(row) which must return a boolean indicating if the action is applicable for the given row (passed as a function parameter). If this function retuns false than all other parameters have no effect. |
iconUrl optional string |
Full URL address of an image that will appear as the action icon. We recommend using a 60x60 px PNG image with transparent background. |
title optional string |
Text that will appear on mouseover action over the icon. |
action optional function |
function(event, result), called when user clicks the icon. This function is passed 2 arguments, the JavaScript event and the result object. It is a responsibility of this function to do the necessary work, e.g., put item to cart. |
Returning self reference ¶
The AutocComplete constructor returns references to all created widgets, so you can access its public functions and options. The references are returned as an array, one object for each HTML selector that was matched by the provided input box selector.
<script>
var ac = AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: "item",
name: "",
size: 6,
},
],
}, '#autocomplete')
ac[0].Close();
ac[0].Reposition();
</script>
Public functions ¶
AutoComplete widget provides these public functions. You'll need to obtain a reference to the widget first, before you can call these functions.
Function | Comment | Example |
---|---|---|
Reposition function |
Reposition the widget and align it with your search input box. You don't need to call this function under normal circumstances. A typical use case for this function is when your website layout changes due to a user interaction and you need to reposition the autocomplete widget. A case we see quite often is that you have a fixed "bar" at the top of the page with a notification which the user can close. This can lead to a situation where a user types query into the search box, the autocomplete widget renders itself aligned under the bottom, and then the user closes the notification bar, which causes the page content to shift a few pixels up, and suddenly the widget is not aligned properly. In this case, you can call the Reposition() function when the bar is closed to fix the alignment. | |
OpenEmpty function |
Opens an empty widget, with just the bare UI. You must provide your own HTML which will be rendered as the body of the autocomplete. This is useful in situation where you want to render the autocomplete widget with your custom content and keep all the standard behaviour and listeners active. | Custom message on no results |
Destroy function |
Destroys the widget, removes event listeners and drops caches. This function is useful mostly for SPAs where you need to reconfigure the widget between page loads, or remove the autocomplete completely for certain pages. |
Layouts ¶
We provide these built-in layouts:
Layout | Comment | Example |
---|---|---|
Hero | Specify Layout: 'hero' or Layout: 'heromobile' , for more responsive mobile versions, in options. |
Hero Layout |
Line | Specify Layout: 'line' in options. |
Line Layout |
Grid | Specify Layout: 'grid' in options. |
Grid Layout |
Obsolete | Note that if you do not explicitely set Layout: 'line' , Layout: 'grid' or Layout: 'hero' or Layout: 'heromobile' , then we will fallback to an obsolete layout, which is no longer supported and most of the features will not work. |
Shared public CSS classes ¶
Class | Comment |
---|---|
luigi-ac-main |
Wraps the (visually) "main" section of the widget. See Custom placement of items for more details. |
luigi-ac-others |
Wraps the (visually) less important section of the widget. See Custom placement of items for more details. |
luigi-ac-item |
All "rows" in autocomplete widget are wrapped in this class. |
luigi-ac-header |
Wraps results header. |
luigi-ac-product |
Class for each product. |
luigi-ac-category |
Class for each item which is not a product or query. |
luigi-ac-query |
Class for each item which is type query. |
luigi-ac-image |
Class for each item's image. |
luigi-ac-title or luigi-ac-text |
Class for each item's title. |
luigi-ac-attrs |
Wraps attributes. |
luigi-ac-attr |
Class for each attribute. |
luigi-ac-price |
Wraps price of an item. |
luigi-ac-button |
Wraps button block for 'Show All Items'. |
Hero layout ¶
AutoComplete({
Layout: 'hero',
TrackerId: '1234-5678',
Locale: 'en',
ShowHeroProduct: true,
Types: [
{
type: 'item',
placement: 'main',
size: 7,
attributes: ['category']
},
{ type: 'query',
size: 4,
placement: 'others',
},
{
type: 'category',
size: 3,
placement: 'others',
},
{
type: 'brand',
size: 5,
placement: 'others',
}
]
}, '#luigi-ac-input')
Public CSS classes ¶
We provide these classes in hero layout as part of the widget's public interface:
Class | Comment |
---|---|
luigi-ac-hero |
Wraps the autocomplete widget for Hero layout. |
luigi-ac-hero-color |
Class for styling queries and caret with top strip. Basically this class defines main color of this layout. |
luigi-ac-hero-color-clickable |
Class for styling "show all products" button and queries rectangles. |
luigi-ac-actions and luigi-ac-action |
Wraps actions like 'Buy' or 'Sell'. |
luigi-ac-first-main |
Wrapper for "Hero product" - the first one appeared. |
luigi-ac-rest-main |
Wrapper for all other products except "Hero product". |
Line layout ¶
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
},
{
type: 'category',
name: 'Categories'
}
]
}, '#luigi-ac-input')
Public CSS classes ¶
We provide these classes as part of the widget's public interface:
Class | Comment |
---|---|
luigi-ac-line |
Wraps the autocomplete widget for Line layout. |
luigi-ac-actions and luigi-ac-action |
Wraps actions like 'Buy' or 'Sell'. |
Grid layout ¶
Grid layout consists of two parts – a main "grid" part with images and prices, and an additional, more condensed column.
AutoComplete({
Layout: 'grid',
ShowBranding: true,
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Products'
},
{
type: 'category',
name: 'Categories'
}
]
}, '#luigi-ac-input')
Public CSS classes ¶
We provide these classes as part of the widget's public interface:
Class | Comment |
---|---|
luigi-ac-grid |
Wraps the autocomplete widget for Grid layout. |
Position of Grid layout ¶
This can be done by defining GridPosition: left
or GridPosition: right
as autocomplete widget's option.
Default position of grid is left
, that means, that items with defined placement: 'main'
are on left side, but you can explicitly define that state.
If placement
is not defined, then first specified type is considered main
and will be on the left side. Other types will be on the right side.
Grid layout autocomplete with GridPosition: 'left'
AutoComplete({
Layout: 'grid',
ShowBranding: true,
GridPosition: 'left',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item', placement: 'main', name: 'Products'
},
{
type: 'category', name: 'Categories'
},
{
type: 'query', name: 'Queries'
},
]
}, '#luigi-ac-input')
Grid layout autocomplete with GridPosition: 'right'
AutoComplete({
Layout: 'grid',
ShowBranding: true,
GridPosition: 'right',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item', placement: 'main', name: 'Products'
},
{
type: 'category', name: 'Categories'
},
{
type: 'query', name: 'Queries'
},
]
}, '#luigi-ac-input')
Align Grid to center or with search box ¶
This can be done by defining Align: 'center'
or Align: 'input'
as autocomplete widget's option.
Default state of Grid layout is Align: center
.
If you want to move the autocomplete along with input search box, set Align: 'input'
, otherwise it will be centered on the page.
Grid layout autocomplete with Align: 'input'. See, that left side of the autocomplete is aligned same as input search box.
AutoComplete({
Layout: 'grid',
ShowBranding: true,
TrackerId: '1234-5678',
Locale: 'en',
Align: 'input',
Types: [
{
type: 'item', placement: 'main', name: 'Products'
},
]
}, '#luigi-ac-input')
Grid layout autocomplete with Align: 'center'. See, that the autocomplete is centered on the page.
AutoComplete({
Layout: 'grid',
ShowBranding: true,
TrackerId: '1234-5678',
Locale: 'en',
Align: 'center',
Types: [
{
type: 'item', placement: 'main', name: 'Products'
},
]
}, '#luigi-ac-input')
Custom placement of items ¶
Grid Layout Line Layout
This can be done by defining placement: 'main'
or placement: 'others'
parameter in Types. These are the only two supported placements.
Note, that if it used for one of the Types, it has to be defined for all other Types to have an effect.
If placement
is not defined, then first specified type or type 'item' is considered "main" and will be wrapped with luigi-ac-main
class.
If placement
is defined, then items set to placement: main
will be wrapped with luigi-ac-main
class. Note that these items expect images.
If placement
is defined, then items set to placement: others
will be wrapped with luigi-ac-others
class.
Typical usage of this placement in Line Layout is for example Two-column layout.
Grid layout autocomplete with custom placement of "item" and "category" in the middle
AutoComplete({
Layout: 'grid',
ShowBranding: true,
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item', placement: 'main'
},
{
type: 'category', placement: 'main', name: 'Categories'
},
{
type: 'query', placement: 'others', name: 'Queries'
},
]
}, '#luigi-ac-input')
Grid layout autocomplete with custom placement of all Types in the middle
AutoComplete({
Layout: 'grid',
ShowBranding: true,
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item', placement: 'main'
},
{
type: 'category', placement: 'main', name: 'Categories'
},
{
type: 'query', placement: 'main', name: 'Queries'
},
]
}, '#luigi-ac-input')
Attribute expressions ¶
Grid Layout Line Layout
Attribute expressions allow you to specify which item attributes will be shown in the second line of a single autocomplete row.
A generic form of attribute expression is attribute.start->after<-behind
.
Attribute expressions operate on arrays of values and consist of 4 parts:
Part | Comment |
---|---|
attributeREQUIRED | Which attribute will be shown in autocomplete |
startoptional | Required, when you want to define behind or after context. So attribute->10<-5 is not valid. |
behind contextoptional | Consist of <- and positive number. |
after contextoptional | Consist of -> and positive number. |
->
delimites after
context and <-
delimits behind
context.
For example, expression category.hl->1<-1
operating on ['Electronics', 'Smart <em>TV</em>', 'LED', '50"']
will find the first highlighted value (i.e. the value which matched the query) and
take one value after it and one value before it. In this case, the result would
be Electronics, Smart <em>TV</em>, LED
shown in the second line, under the
item's title.
Autocomplete for showing one highlighted category, last brand and second to last category from hierarchy
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items',
attributes: ['category.hl', 'brand.last', 'categories.hierarchy.last-1']
}
]
}, '#luigi-ac-input')
For start value, you can use one of the following:
Value | Comment | Example |
---|---|---|
a number | interpreted as an index into the value array. First value is indexed as 0. | category.1 |
hl |
which is interpreted as index of highlighted value, or index of last value if nothing was highlighted. | category.hl |
last |
index of last value | category.last |
last-1 |
index of second to last value | category.last-1 |
Some note on edge cases and limitations:
- if you specify non-existent attribute name, that expression will be skipped
- if you specify start position which is out of bounds for the current item, that expression will be skipped
- behind or after context will never go out of bounds, if you write
category.0->1000
this will show all category values and is equivalent to just writing (category
)
For some examples see Display additional attributes.
Styling recipes
2-column layout ¶
Line Layout
We provide two main div
elements for products: luigi-ac-main
and luigi-ac-others
.
You can write your own CSS style for these elements, as well as for other luigi
classes.
Note, that this is still a line
layout which (unlike grid
layout) supports Actions
configuration.
Position of items with custom CSS styles
<style>
.luigi-ac-main {
position: relative;
float: left;
width: 275px;
background: #f7f7f8 !important;
}
.luigi-ac-others {
position: relative;
float: right;
width: 225px;
margin-top: 0;
}
</style>
Adjust footer if you want
<style>
.luigi-ac-line .luigi-ac-footer {
position: relative;
margin-top: 452px;
}
</style>
With button ¶
If you want to include button inside the autocomplete widget, you need to style .luigi-ac-button-block
and .luigi-ac-fotter
.
Adjust width of autocomplete widget if you want
<style>
.luigi-ac-line {
width: 700px !important;
}
</style>
Position of items in 2-column layout with button
<style>
.luigi-ac-main {
position: relative;
float: left;
width: 60%;
background: #f7f7f8 !important;
}
.luigi-ac-others {
float: right;
width: 40%;
margin-top: 0
}
.luigi-ac-line .luigi-ac-footer {
position: relative;
bottom: 0;
width: 100%;
padding-top: 65px;
}
.luigi-ac-line .luigi-ac-button-block {
position: absolute;
left: 0;
bottom: 40px;
z-index: 10;
}
</style>
Adjusting line layout responsivness ¶
Line Layout
You may want to adjust the responsive breakpoints to better fit your site.
Autocomplete with customized responsive behavior
<style>
@media screen and (max-width: 900px) {
.luigi-ac {
width: 97% !important;
left: 5px !important;
}
}
</style>
Adjusting grid layout responsivness ¶
Grid Layout
Autocomplete with customized responsive behavior
<style type="text/css">
@media (min-width: 992px) {
.luigi-ac {
max-width: 1050px !important;
}
.luigi-ac-products {
width: 75% !important;
}
.luigi-ac-others {
width: 25% !important;
}
}
@media (max-width: 576px) {
.luigi-ac-product {
width: 50% !important;
}
}
@media (max-width: 304px) {
.luigi-ac-product {
width: 100% !important;
}
}
</style>
The grid layout has responsive styling built-in and will adapt to different screen sizes by default. You may want to adjust the responsive breakpoints to better fit your site.
Bigger pictures in grid ¶
Grid Layout
Autocomplete with custom CSS styles for bigger pictures with adjusted position
<style type="text/css">
.luigi-ac-product, .luigi-ac-other {
flex-wrap: wrap !important;
}
.luigi-ac-description {
justify-content: flex-start !important;
flex: auto !important;
text-align: center !important;
}
.luigi-ac-product {
width:25% !important;
}
.luigi-ac-image {
width: 100% !important;
height: 110px !important;
}
.luigi-ac-image img {
width:120px !important;
}
</style>
Custom highlight and hover colors ¶
Hero Layout Grid Layout Line Layout
Autocomplete with custom CSS styles for hover color
<style>
.luigi-ac-item:hover,.luigi-ac-item.active,.luigi-ac-other:hover,.luigi-ac-active {
background: #ECF0FF !important;
}
</style>
Autocomplete with custom CSS style for highlighted phrase
<style>
.luigi-ac-highlight {
background: rgb(244, 230, 233) !important;
}
</style>
Recipes
In this section you can see some examples of our autocomplete.
Dynamic section titles ¶
Hero Layout Grid Layout Line Layout
Types.name
can be set to a function where you can return title string in a custom format. For example, you can show many items are displayed in each section.
Line layout with custom function for Types parameter name
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: function(results, $t) { return 'Showing ' + results.length + ' items.'}
},
{
type: 'category',
size: 2,
name: function(results, $t) { return 'Showing ' + results.length + ' categories.'}
},
],
}, '#luigi-ac-input')
Submit button deprecated ¶
Hero Layout Grid Layout Line Layout
Submit button to show all products
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
},
{
type: 'category',
name: 'Categories'
}
],
ShowAllTitle: 'Show all products',
}, '#luigi-ac-input')
If you need a button for show all products to be visible, simply addShowAllTitle
option.ShowAllTitle
option is deprecated, button is visible by default. If you need to hide it, set translation forshowAllTitle
to empty string. See Localisation for more info.
A/B test different Autocomplete configurations ¶
Example AB test configuration, this is variant A with line layout. Note that the Variant name is arbitrary.
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Variant: 'LuigisLine',
Types: [
{
type: 'item',
name: 'Items'
},
{
type: 'category',
name: 'Categories'
}
],
}, '#luigi-ac-input')
Example AB test configuration, this is variant B with grid layout. Note that the Variant name is arbitrary.
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Variant: 'LuigisGrid',
Types: [
{
type: 'item',
name: 'Items'
},
{
type: 'category',
name: 'Categories'
}
],
}, '#luigi-ac-input')
Grid Layout Line Layout
If you want to AB test different Autocomplete configurations, mark each configuration with a unique Variant. You will then see results of your AB test in Luigi's Box application.
For example, if you want to know if your visitors would convert better from line or grid layout, you can create a configuration for line layout, mark it with a Variant and serve it to 50% of your visitors, and server the other 50% of your visitors a grid layout configuration. After a few days, you will see which configuration leads to higher conversion.
Did you mean? ¶
Hero Layout Grid Layout Line Layout
You can specify DidYouMean as a function which is called with three arguments
input
,matches
andresultTypes
.resultTypes
has three types and you can specify text for each one, which will be displayed on top of the search results in autocomplete widget.
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items',
attributes: ['category', 'brand']
},
],
DidYouMean: function(input, matches, resultSetType) {
switch (resultSetType) {
case 'exact_only':
return "Showing exact results for <span>\"" + input + "\"</span>.";
case 'partial_only':
return "We did not find results for <span>\"" + input + "\"</span>. Showing results for <span>" + matches.map(function(match) {
return "\"" + match + "\"";
}).join(', ') + "</span>";
case 'mixed':
return "Showing exact results for <span>\"" + input + "\"</span> and also showing some results for <span>" + matches.map(function(match) {
return "\"" + match + "\"";
}).join(', ') + "</span>";
default:
return '';
}
}
}, '#luigi-ac-input')
Exact match information ¶
Partial match information ¶
Exact and partial match information ¶
Display search hint deprecated ¶
Grid Layout Line Layout
You can specify text of a hint for performing regular search.- This option is now deprecated, see Localisation.
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
],
Hint: function(query) {
return "To perform a regular search for <span>\"" + query + "\"</span> press Enter"
},
}, '#luigi-ac-input')
Display additional attributes ¶
Hero Layout Grid Layout Line Layout
You can specify attributes in your autocomplete by adding
attributes
as option.You also can add attributes by specifing it in array like:
attributes:['category']
attributes:['category', 'brand']
attributes:['category.hl', 'brand.hl', query.hl->2]
For more information please see section Attribute expressions.
Example with showing highlighted category and brand as attributes
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items',
attributes: ['category.hl', 'brand.hl']
}
],
}, '#luigi-ac-input')
Display recommended items ¶
Hero Layout Grid Layout Line Layout
We provide recommended items, if you add
recommend:{}
as option in autocomplete.Recommended items are shown on click in input empty input field. If you start typing, than recommended items are hidden and results will be shown based on your query.
This option accepts specific name or size of displayed items.
"Show all products" button is not shown for recommened items.
Example with recommended items/top items
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items',
recommend: {
name: 'Recommended items',
size: 6
},
},
{
type: 'category',
name: 'Categories',
recommend: {
name: 'Recommended categories',
size: 2
},
},
],
}, '#luigi-ac-input')
Format texts as you want ¶
Hero Layout Grid Layout Line Layout
You can format text as you want by specifing option
FormatForDisplay
.This option could be used, if you want to move some additional text to title, subtitle or wherever you want.
Example with manufacturer present in title within '( )'
AutoComplete({
Layout: 'grid',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
],
FormatForDisplay: function(result) {
var allAttributes = result.attributes;
if (result.type !== "submit") {
if (allAttributes['brand']) {
allAttributes.title += ' ('+'manufactured by: '+allAttributes['brand'][0]+')'
}
}
return result;
},
}, '#luigi-ac-input')
You can use this CSS for better output
<style>
.luigi-ac-name {
font-size: 15px !important;
text-decoration: none !important;
}
</style>
Sort results before rendering ¶
Hero Layout Grid Layout Line Layout
You can change the results, query, or do some other action in custom callback
BeforeRender
.Remember, that this function needs to return a final
results
which has to be an array of objects.In most cases, you just modify the
results
attributes, sort the results, or add your custom result.
Example of sorting results by price (from the cheapest)
AutoComplete({
Layout: 'grid',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
],
BeforeRender: function(query, results) {
results = results.sort(function(a, b) {
return (a.attributes.price_amount > b.attributes.price_amount) ? 1 : (b.attributes.price_amount > a.attributes.price_amount) ? -1 : 0;
});
return results;
},
}, '#luigi-ac-input')
Submitting search outside 'form' context ¶
Hero Layout Grid Layout Line Layout
- The default implementation of search submission relies on the fact that the search box input field is placed within a
form
element, which is simply submitted. If this is not the case, you will have to provide a custom submission implementation withShowAllCallback
.
Example of form submission by emulating Enter
AutoComplete({
Layout: 'grid',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
],
ShowAllCallback: function() {
var input = document.querySelector("#searchbox");
var ev = document.createEvent('Event');
ev.initEvent('keydown');
ev.which = ev.keyCode = 13;
input.dispatchEvent(ev);
},
}, '#luigi-ac-input')
Auto reposition ¶
Hero Layout Grid Layout Line Layout
- If the position of the search box changes dynamically, e.g. as the user scrolls down the search box will resize or slightly move, you need to set up
AutoReposition
, to keep the autocomplete widget aligned with the searchbox. The default behavior is off, and widget position is computed on initialization.
Note, that when you enable this option, the input box position will be periodically re-checked in an endless loop.
Following examples illustrate AutoReposition when input position is being changed while scrolling. Input field has an absolute position.
NOT using AutoReposition ¶
Widget position remains the same because its position is computed on initialization and it is re-computed only on another render (when you click in the input box or search for another word) and NOT while scrolling.
Using AutoReposition ¶
Widget position is being re-computed based on the position of the input box while scrolling.
Example
AutoComplete({
Layout: 'grid',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
],
AutoReposition: true
}, '#luigi-ac-input')
Typing Suggestions ¶
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
TypingSuggestions: true,
Types: [
{
type: 'item',
name: 'Items'
},
]
}, '#luigi-ac-input')
Hero Layout Grid Layout Line Layout
Price Filter deprecated ¶
AutoComplete({
Layout: 'hero',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
],
PriceFilter: {
locale: 'cs',
decimals: 0,
prefixed: false,
symbol: ' Kč'
}
}, '#luigi-ac-input')
Hero Layout Grid Layout Line Layout
To adjust how prices are formatted, setupPriceFilter
configuration.- This option is now deprecated, see Localisation.
Key | value |
---|---|
locale | String which specifies locale for your price. For example: 'cs', 'sk' or 'hu'. |
decimals | Integer for how many decimal places should be displayed. |
prefixed | Boolean for displaying price symbol (currency) before or after the price value. |
symbol | String which specifies your own symbol for price. For example: '€' or 'Kč'. |
Localisation ¶
AutoComplete({
Layout: 'hero',
TrackerId: '1234-5678',
Locale: 'en', // current language of website
Translations: {
en: {
// override translations you want to change
showAllTitle: 'Show me more!',
showBuyTitle: '', // set to empty string to disable button
},
// you can define your own language and use it in Locale option
esperanto: {
// define all translations
// ...
}
}
}, '#luigi-ac-input')
To customize texts and settings depending on language version of your website, you can use Locale
and Translations
options.
First step is to set Locale
option to string containing locale key. We provide default dictionaries for following languages: en
, de
, sk
, cz
, pl
, hu
, ro
. You can also define your own locale in Translations
option and use it.
Translations
option should be object with locales keys, each locale key containing dictionary for specific language. This object will be merged with our default translations, so you need to specify only translations you want to override. If you are using custom locale key, you need to define all translations.
This is default dictionary for english, use it as reference for overriding / creating dictionaries:
{
"showAllTitle": "Show all products",
"showBuyTitle": "Add to basket",
"placeholderText": "Search for...",
"hint": "Press Enter to search for :query",
"noResultsMessage": "Your search term :query did not match any of our products. Please try another search term.",
"noResultsMessageOne": "We only found one product for query :query.",
"types": {
"item": {
"name": "Products",
"recommendHeroName": "Top products",
"heroName": "Top product",
"recommendName": "Top product"
},
"query": {
"name": "Queries",
"recommendName": "Top queries"
},
"category": {
"name": "Categories",
"recommendName": "Top categories"
},
"brand": {
"name": "Brands",
"recommendName": "Top brands"
},
"article": {
"name": "Articles",
"recommendName": "Top articles"
}
},
"priceFilter": {
"minimumFractionDigits": 0,
"maximumFractionDigits": 2,
"locale": "en",
"prefixed": true,
"symbol": "$"
}
}
Show Hero Product ¶
Hero Layout
Example with Hero Product
AutoComplete({
Layout: 'hero',
TrackerId: '1234-5678',
Locale: 'en',
ShowHeroProduct: true,
Types: [
{
type: 'item',
placement: 'main',
size: 7,
attributes: ['category']
},
{
type: 'category',
placement: 'others',
size: 4,
}
]
}, '#luigi-ac-input')
- With Hero Product -
ShowHeroProduct: true
- Without Hero Product -
ShowHeroProduct: false
Hero with buy buttons ¶
Hero Layout
Example with Buy buttons
AutoComplete({
Layout: 'hero',
TrackerId: '1234-5678',
Locale: 'en',
ShowHeroProduct: true,
Types: [
{
type: 'item',
placement: 'main',
size: 7,
attributes: ['category']
},
{
type: 'category',
placement: 'others',
size: 4,
}
],
Actions: [
{
forRow: function(row) {
return !row.type || row.type === 'item' || row.type === 'product'
},
iconUrl: 'https://cdn.luigisbox.com/autocomplete/assets/cart.svg',
iconText: 'Buy',
title: 'Buy',
action: function(e, result) {
e.preventDefault();
console.log('buy', result);
}
}
]
}, '#luigi-ac-input')
If you want to use buy buttons in Hero layout, you need to specify
Actions
.You can also implement it all by yourself in our
AfterRender
callback by appending custom HTML elements with your listeners to the widget.
Hero layout message on no results ¶
Hero Layout
NoResultsMessage: function(query, numberOfResults) {
if (numberOfResults == 0) {
return 'No results found for query'+' "'+query+'" '+'.'
} else {
return 'Only one product found for query'+' "'+query+'" '+'.'
}
}
- This option is now deprecated, see Localisation.
Custom message on no results ¶
AfterRender: function(query, results) {
if (results && results.length === 0) {
this.OpenEmpty("<div style='padding: 1rem'>Lorem ipsum</div>");
}
}
Grid Layout Line Layout
The default behavior of the widget in Grid & Line layout is to close itself and
not render anything. If you want to provide your custom message in case of no
results, you can use the public OpenEmpty
function in combination with the
AfterRender
callback. Call OpenEmpty
with your custom HTML code that will
be rendered as the widget body.
Action with buy ¶
Hero Layout Grid Layout Line Layout
- In this example, you can allow buy action directly from autocomplete.
Example with buy action
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
}
],
Actions: [
{
forRow: function(row) {
return !row.type || row.type === 'item' || row.type === 'product'
},
iconUrl: '/buy.jpg',
iconText: 'H',
title: 'Buy',
action: function(e, result) {
e.preventDefault();
console.log('buy', result);
}
}
]
}, '#luigi-ac-input')
Filtering in autocomplete ¶
defaultFilters option ¶
Example with defaultFilters
AutoComplete({
Layout: 'grid',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Products',
defaultFilters: {
category: 'her',
set: ['summer dress', 'skirts']
}
},
{
type: 'category',
name: 'Category'
}
],
}, '#luigi-ac-input')
You can explicitely set filters to scope autocomplete results to only when the specified attributes match the provided values. You can specify as many attributes and as many values as necessary. The provided value of the attribute can be either a scalar, or an array. If you specify an array, the request is interpreted such that all individual values from the array must match for the result to match.
This filtering is similar to what you can achieve with autocomplete contexts, but unlike contexts, it does not require any changes on your part in how you index the data.
filters option ¶
Example with filters
AutoComplete({
Layout: 'grid',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Products',
filters: function() {
var customFilters = {
category: 'her',
set: ['summer dress', 'skirts']
}
return customFilters;
}
},
{
type: 'category',
name: 'Category'
}
],
}, '#luigi-ac-input')
You can use your own code to define logic for using filters in autocomplete. Functionality is the same as defaultFilters, but this is dynamic.
Google Analytics tracking ¶
You can use default
as a string value GATrackingCode: 'default'
and our widget will take care of sending events to your first Google analytics account that will be found in ga
object.
Example with sending default GA events
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
},
{
type: 'category',
name: 'Categories'
},
],
GATrackingCode: 'UA-123-456'
}, '#luigi-ac-input')
Example with sending more specific GA events
AutoComplete({
Layout: 'line',
TrackerId: '1234-5678',
Locale: 'en',
Types: [
{
type: 'item',
name: 'Items'
},
{
type: 'category',
name: 'Categories'
},
],
Select: function(event, item, row) {
ga('send', 'event', 'AutoComplete', 'click', item.attributes.item_id);
},
AfterRender: function(query) {
ga('send', 'event', 'AutoComplete', 'display');
}
}, '#luigi-ac-input')
By default we send 'display', 'click' on product and 'conversion' to a specified Google Analytics account, if GATrackingCode option is set. However, if you need more control over the events, you can send custom events using the callbacks provided by autocomplete.js.
You can use
AfterRender
function to send event when autocomplete widget is displayed and aSelect
function to send an event when an autocomplete item is clicked. You can also (optionally) send the item ID, so you know exactly what was clicked.
See Google Analytics events documentation for more details on reporting functions.
Pricing API integration ¶
If you are using different pricing levels depending on the signed-in user, one of the strategies that you can use to render correct user prices in autocomplete is using your pricing API.
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 20px;
height: 20px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
position: absolute;
left: 50%;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
Start by defining a loader element which will render instead of prices.
.luigi-ac .luigi-ac-price-new {
visibility: hidden;
}
Hide the prices in autocomplete via CSS.
FormatForDisplay: function(result) {
if (result && result.attributes && result.attributes.price_amount) {
result._after_price = "<div class='loader'></div>"
}
}
And display the loading indicator
AfterRender: function(query, results) {
if (results && results.length > 0) {
var renderedResults = document.querySelectorAll('.luigi-ac-product');
// collect IDs of the found products, here, we are using the id attribute
var ids = [];
results.forEach(function(result) {
if (result.attributes.id) {
ids.push(result.attributes.id)
}
})
var xhttp = new XMLHttpRequest();
xhttp.onload = function() {
var jsonParsed = JSON.parse(this.responseText);
// Update the HTML for each result with the price from the pricing API
renderedResults.forEach(function(result) {
var productId = Number(result.querySelector('.luigi-ac-attr--id').textContent)
if (jsonParsed[productId]) {
result.querySelector('.luigi-ac-price-new').innerText = jsonParsed[productId];
}
})
// Show the (now updated) prices
var prices = document.querySelectorAll('.luigi-ac-price-new');
for (var i = 0; i < prices.length; i++) {
prices[i].style.visibility = 'visible';
}
// Hide the loaders
var loaders = document.querySelectorAll('.luigi-ac .loader');
for (var i = 0; i < loaders.length; i++) {
loaders[i].style.display = 'none';
}
}
var apiUrl = 'https://yourdomain.example/api/pricing?ids='+ids.join(',');
xhttp.open("GET", apiUrl);
xhttp.send();
}
}
When autocomplete widget renders, fire an XHR request to your pricing API and use the result to replace the loaders with per-customer prices. This code assumes that the pricing API response is an object where the keys are product IDs, and values are fully-formatted prices.
In order to have the .luigi-ac-attr--id
element available in the product
tile, configure it in attributes
for the type. See Display additional
attributes for more information.
Compatibility
Luigi's Box autocomplete widget is compatible with all modern browsers, however, some third-party scripts are known to cause problems.
Mootools ¶
Mootools is overriding a native Function.prototype.bind
function in an
incompatible way. If you try to use Luigi's Box autocomplete widget on a
website that is using Mootools, the widget will not work.
You can however use a simple workaround and save the original bind
function,
before you load Mootools. Put this script tag <script>window._bind =
Function.prototype.bind;</script>
before the script tag that loads
mootols. It will save the original bind
function into a _bind
variable. If
we detect that your website is using Mootools, we will automatically fallback
to this _bind
function and the widget will work.