![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
instantsearch.js
Advanced tools
instantsearch.js is a library of widgets to build high performance instant search experiences using Algolia
instantsearch.js is a library for building performant and instant search experiences with Algolia. It provides a set of widgets and tools to create highly customizable search interfaces.
Search Box
The search box widget allows users to input their search queries. It connects to the Algolia index and fetches results based on the user's input.
const search = instantsearch({
indexName: 'instant_search',
searchClient: algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey')
});
search.addWidget(
instantsearch.widgets.searchBox({
container: '#searchbox'
})
);
search.start();
Hits
The hits widget displays the search results. It can be customized to show different attributes of the search results and highlight the matching parts of the query.
search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
templates: {
item: '<div>{{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}</div>'
}
})
);
Refinement List
The refinement list widget allows users to filter search results based on specific attributes, such as categories. It provides checkboxes for each attribute value.
search.addWidget(
instantsearch.widgets.refinementList({
container: '#refinement-list',
attribute: 'categories'
})
);
Pagination
The pagination widget enables users to navigate through pages of search results. It provides controls for moving to the next or previous page and jumping to specific pages.
search.addWidget(
instantsearch.widgets.pagination({
container: '#pagination'
})
);
react-instantsearch is a library for building Algolia search interfaces in React. It provides React components that wrap instantsearch.js widgets, making it easier to integrate with React applications. Compared to instantsearch.js, it is more suitable for React-based projects.
searchkit is a suite of UI components built in React to create search experiences powered by Elasticsearch. It offers a similar set of features to instantsearch.js but is designed to work with Elasticsearch instead of Algolia.
instantsearch.js is a library of widgets to build high performance instant search experiences using Algolia
API is unstable. We welcome any idea and pull request.
npm install instantsearch.js --save
<script>
instantsearch.js is available on jsDelivr:
<script src="//cdn.jsdelivr.net/instantsearch.js/0/instantsearch.min.js"></script>
var instantsearch = require('instantsearch.js');
var search = instantsearch({
appId: appId, // Mandatory
apiKey: apiKey, // Mandatory
indexName: indexName, // Mandatory
numberLocale: 'fr-FR' // Optional, defaults to 'en-EN',
urlSync: { // optionnal, activate url sync if defined
useHash: false
}
});
// add a widget
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
placeholder: 'Search for libraries in France...'
})
);
// start
search.start();
function mySuperWidget(opts) {
return {
getConfiguration: function(searchParameters) {
return {
// helper params
}
},
init: function(initialState, helper) {
// helper: see http://algolia.github.io/algoliasearch-helper-js/docs/
// called before first `helper.on('result');`
},
render: function(results, state, helper) {
// content: see http://algolia.github.io/algoliasearch-helper-js/docs/SearchResults.html
// helper: see http://algolia.github.io/algoliasearch-helper-js/docs/
// called at each `helper.on('result')`
}
}
}
search.addWidget(mySuperWidget());
Most of the widgets accept a template
or templates
option that let you
change the default rendering.
template
can be defined either as a Mustache (Hogan) string or as a function receiving
the widget data.
See the documentation of each widget to see which data is passed to the template.
// Mustache template example
search.addWidget(
instantsearch.widgets.stats({
container: '#stats',
templates: {
body: '<div>You have {{nbHits}} results, fetched in {{processingTimeMS}}ms.</div>'
}
})
);
// Function template example
search.addWidget(
instantsearch.widgets.stats({
container: '#stats',
templates: {
body: function(data) {
return '<div>You have ' + data.nbHits + 'results, fetched in ' + data.processingTimMS +'ms.</div>'
}
}
})
);
In order to help you when defining your templates, instantsearch.js
exposes
a few helpers. All helpers are accessible in the Mustache templating through
{{#helpers.nameOfTheHelper}}{{valueToFormat}}{{/helpers.nameOfTheHelper}}
. To
use them in the function templates, you'll have to call
search.templatesConfig.helpers.nameOfTheHelper
where search
is your current
instantsearch
instance.
Here is the list of the currently available helpers:
formatNumber
: Will accept a number as input and returned the formatted
version of the number in the locale defined with the numberLocale
config
option (defaults to en-EN
).
eg. 100000
will be formatted as 100 000
with en-EN
Here is the syntax of a helper (render
is using search.templatesConfig.compileOptions
):
search.templatesConfig.helpers.emphasis = function(text, render) {
return '<em>' + render(text) + '</em>';
};
In your helper, this
always refers to the data:
search.templatesConfig.helpers.discount = function(/*text, render*/) {
var discount = this.price * 0.3;
return '$ -' + discount;
};
You can configure the options passed to Hogan.compile
by using search.templatesConfig.compileOptions
. We accept all compile options.
Theses options will be passed to the Hogan.compile
calls when you pass a custom template.
To help get you started, we provide a default theme for the widgets. This is
just a css
file that you have to add to your page to add basic styling.
It is available from jsDelivr:
<link rel="stylesheet" href="//cdn.jsdelivr.net/instantsearch.js/0/themes/default.min.css">
<!-- or the unminified version -->
<link rel="stylesheet" href="//cdn.jsdelivr.net/instantsearch.js/0/themes/default.css">
It contains (empty) selectors for all the possible markup added by the widgets, so you can use it as a base for creating your own custom theme. We will provide more themes in the future.
npm run dev
# open http://localhost:8080
# make changes in your widgets, or in example/app.js
npm test # jsdom + lint
npm run test:watch # jsdom
npm run test:watch:browser # chrome
npm run test:watch:browser -- --browsers ChromeCanary # force Chrome Canary
The main configuration of instantsearch.js is done through a configuration object. The minimal configuration is made a of three attributes :
instantsearch({
appId: 'my_application_id',
apiKey: 'my_search_api_key',
indexName: 'my_index_name'
});
It can also contain other optionnal attributes to enable other features.
For the display of numbers, the locale will be determined by the browsers or forced in the configuration :
instantsearch({
appId: 'my_application_id',
apiKey: 'my_search_api_key',
indexName: 'my_index_name',
numberLocale: 'en-US'
});
At the start of instantsearch, the search configuration is based on the input of each widget and the URL. It is also possible to change the defaults of the configuration through an object that can contain any parameters understood by the Algolia API.
instantsearch({
appId: 'my_application_id',
apiKey: 'my_search_api_key',
indexName: 'my_index_name',
searchParameters: {
typoTolerance: 'strict'
}
});
Instantsearch let you synchronize the url with the current search parameters. In order to activate this feature, you need to add the urlSync object. It accepts 3 parameters :
All those parameters are optional and a minimal configuration looks like :
instantsearch({
appId: 'my_application_id',
apiKey: 'my_search_api_key',
indexName: 'my_index_name',
urlSync: {}
});
/**
* Instantiate a searchbox
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {string} [options.placeholder] Input's placeholder
* @param {Object} [options.cssClasses] CSS classes to add
* @param {string} [options.cssClasses.root] CSS class to add to the wrapping div (if wrapInput set to `true`)
* @param {string} [options.cssClasses.input] CSS class to add to the input
* @param {string} [options.cssClasses.poweredBy] CSS class to add to the poweredBy element
* @param {boolean} [poweredBy=false] Show a powered by Algolia link below the input
* @param {boolean} [wrapInput=true] Wrap the input in a div.ais-search-box
* @param {boolean|string} [autofocus='auto'] autofocus on the input
* @return {Object}
*/
<input id="search-box" />
Or
<div id="search-box"></div>
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
placeholder: 'Search for products',
poweredBy: true
})
);
<div class="ais-search-box">
<input class="ais-search-box--input">
<div class="ais-search-box--powered-by">
Powered by
<a class="ais-search-box--powered-by-link">Algolia</a>
</div>
</div>
.ais-search-box {
}
.ais-search-box--input {
}
.ais-search-box--powered-by {
}
.ais-search-box--powered-by-link {
}
/**
* Display various stats about the current search state
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {Object} [options.cssClasses] CSS classes to add
* @param {string} [options.cssClasses.root] CSS class to add to the root element
* @param {string} [options.cssClasses.header] CSS class to add to the header element
* @param {string} [options.cssClasses.body] CSS class to add to the body element
* @param {string} [options.cssClasses.footer] CSS class to add to the footer element
* @param {string} [options.cssClasses.time] CSS class to add to the element wrapping the time processingTimeMs
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.header=''] Header template
* @param {string|Function} [options.templates.body] Body template
* @param {string|Function} [options.templates.footer=''] Footer template
* @param {Function} [options.transformData] Function to change the object passed to the `body` template
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
* @return {Object}
*/
<div id="stats"></div>
search.addWidget(
instantsearch.widgets.stats({
container: '#stats',
cssClasses: {
time: 'label label-info'
}
})
);
<div class="ais-stats">
<div class="ais-stats--header ais-header">[custom header template]</div>
<div class="ais-stats--body">
42 results found in <span class="ais-stats--time">42ms</span>
</div>
<div class="ais-stats--footer ais-footer">[custom footer template]</div>
</div>
.ais-stats {
}
.ais-stats--header {
}
.ais-stats--body {
}
.ais-stats--time {
font-size: small;
}
.ais-stats--footer {
}
This widget will let you change the current index being targeted. This is especially useful for changing the current sort order. If you need your results ordered following a special rule (like price ascending or price descending), you'll need several indices. This widget lets you easily change it.
/**
* Instantiate a dropdown element to choose the current targeted index
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {Array} options.indices Array of objects defining the different indices to choose from.
* @param {string} options.indices[0].name Name of the index to target
* @param {string} options.indices[0].label Label displayed in the dropdown
* @param {Object} [options.cssClasses] CSS classes to be added
* @param {string} [options.cssClasses.root] CSS classes added to the parent <select>
* @param {string} [options.cssClasses.item] CSS classes added to each <option>
* @param {boolean} [hideContainerWhenNoResults=false] Hide the container when no results match
* @return {Object}
*/
<div id="index-selector"></div>
search.addWidget(
instantsearch.widgets.indexSelector({
container: '#index-selector',
indices: [
{name: 'instant_search', label: 'Most relevant'},
{name: 'instant_search_price_asc', label: 'Lowest price'},
{name: 'instant_search_price_desc', label: 'Highest price'}
],
cssClasses: {
root: 'form-control'
}
})
);
<select class="ais-index-selector">
<option class="ais-index-selector--item">Most relevant</option>
<option class="ais-index-selector--item">Lowest price</option>
<option class="ais-index-selector--item">Highest price</option>
</select>
.ais-index-selector {
}
.ais-index-selector--item {
}
This widget will let you change the current number of results being displayed per page.
/**
* Instantiate a dropdown element to choose the number of hits to display per page
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {Array} options.options Array of objects defining the different values and labels
* @param {number} options.options[0].value number of hits to display per page
* @param {string} options.options[0].label Label to display in the option
* @param {Object} [options.cssClasses] CSS classes to be added
* @param {string} [options.cssClasses.root] CSS classes added to the parent <select>
* @param {string} [options.cssClasses.item] CSS classes added to each <option>
* @param {boolean} [hideContainerWhenNoResults=false] Hide the container when no results match
* @return {Object}
*/
<div id="hits-per-page-selector"></div>
search.addWidget(
instantsearch.widgets.hitsPerPageSelector({
container: '#hits-per-page-selector',
options: [
{value: 6, label: '6 per page'},
{value: 12, label: '12 per page'},
{value: 24, label: '24 per page'}
],
cssClasses: {
select: 'form-control'
}
})
);
<select class="ais-hits-per-page-selector">
<option class="ais-hits-per-page-selector--item">6 per page</option>
<option class="ais-hits-per-page-selector--item">12 per page</option>
<option class="ais-hits-per-page-selector--item">24 per page</option>
</select>
.ais-hits-per-page-selector {
}
.ais-hits-per-page-selector--item {
}
/**
* Add a pagination menu to navigate through the results
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {string|string[]} [options.cssClass] CSS class to be added to the wrapper element
* @param {Object} [options.labels] Text to display in the various links (prev, next, first, last)
* @param {string} [options.labels.prev] Label for the Previous link
* @param {string} [options.labels.next] Label for the Next link
* @param {string} [options.labels.first] Label for the First link
* @param {string} [options.labels.last] Label for the Last link
* @param {number} [maxPages=20] The max number of pages to browse
* @param {string|DOMElement|boolean} [scrollTo='body'] Where to scroll after a click, set to `false` to disable
* @param {boolean} [showFirstLast=true] Define if the First and Last links should be displayed
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
* @return {Object}
*/
<div id="pagination"></div>
search.addWidget(
instantsearch.widgets.pagination({
container: '#pagination',
cssClass: 'pagination',
labels: {
prev: '< Previous',
next: 'Next >',
first: '<< First',
last: 'Last >>'
},
maxPages: 10,
showFirstLast: true
})
);
/**
* Display the list of results (hits) from the current search
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {Object} [options.cssClasses] CSS classes to add
* @param {string} [options.cssClasses.root] CSS class to add to the wrapping element
* @param {string} [options.cssClasses.empty] CSS class to add to the wrapping element when no results
* @param {string} [options.cssClasses.item] CSS class to add to each result
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.empty=''] Template to use when there are no results.
* @param {string|Function} [options.templates.item=''] Template to use for each result.
* @param {Object} [options.transformData] Method to change the object passed to the templates
* @param {Function} [options.transformData.empty=''] Method used to change the object passed to the empty template
* @param {Function} [options.transformData.item=''] Method used to change the object passed to the item template
* @param {number} [hitsPerPage=20] The number of hits to display per page
* @return {Object}
*/
<div id="hits"></div>
search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
templates: {
empty: 'No results'
item: '<div><strong>{{name}}</strong> {{price}}</div>'
},
transformData: {
item: function(data) {
data.price = data.price + '$';
return data;
}
},
hitsPerPage: 20
})
);
<div class="ais-hits">
<div class="ais-hits--item">Hit content</div>
...
<div class="ais-hits--item">Hit content</div>
</div>
<!-- If no results -->
<div class="ais-hits ais-hits__empty">
No results
</div>
.ais-hits {
}
.ais-hits--item {
}
.ais-hits__empty {
}
This widget is used to add filtering of results on a boolean value. Let's say
you want to only display elements that are eligible to free shipping. You'll
just have to instantiate this widget with a facetName
of free_shipping
(with
free_shipping
being a boolean attribute in your records.
When toggling on this widget, only hits with Free Shipping will be displayed. When switching it off, all items will be displayed.
Note that we are not toggling from true
to false
here, but from true
to
undefined
.
/**
* Instantiate the toggling of a boolean facet filter on and off.
* Note that it will not toggle between `true` and `false, but between `true`
* and `undefined`.
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {string} options.facetName Name of the attribute for faceting (eg. "free_shipping")
* @param {string} options.label Human-readable name of the filter (eg. "Free Shipping")
* @param {Object} [options.cssClasses] CSS classes to add
* @param {string|string[]} [options.cssClasses.root] CSS class to add to the root element
* @param {string|string[]} [options.cssClasses.header] CSS class to add to the header element
* @param {string|string[]} [options.cssClasses.body] CSS class to add to the body element
* @param {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
* @param {string|string[]} [options.cssClasses.list] CSS class to add to the list element
* @param {string|string[]} [options.cssClasses.item] CSS class to add to each item element
* @param {string|string[]} [options.cssClasses.active] CSS class to add to each active element
* @param {string|string[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
* @param {string|string[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
* @param {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.header=''] Header template
* @param {string|Function} [options.templates.item] Item template
* @param {string|Function} [options.templates.footer=''] Footer template
* @param {Function} [options.transformData] Function to change the object passed to the item template
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
* @return {Object}
*/
<div id="free-shipping"></div>
search.addWidget(
instantsearch.widgets.toggle({
container: '#free-shipping',
facetName: 'free_shipping',
label: 'Free Shipping',
templates: {
body: '<label><input type="checkbox" {{#isRefined}}checked{{/isRefined}} />{{label}}</label>'
}
})
);
<div class="ais-toggle">
<div class="ais-toggle--header ais-header">[custom header template]</div>
<div class="ais-toggle--body">
<div class="ais-toggle--list">
<div class="ais-toggle--item">
<label class="ais-toggle--label">
<input type="checkbox" class="ais-toggle--checkbox" value="your_value"> Your value
<span class="ais-toggle--count">42</span>
</label>
</div>
</div>
</div>
<div class="ais-toggle--footer ais-footer">[custom footer template]</div>
</div>
.ais-toggle {
}
.ais-toggle--header {
}
.ais-toggle--body {
}
.ais-toggle--list {
}
.ais-toggle--item {
}
.ais-toggle--item__active {
}
.ais-toggle--label {
}
.ais-toggle--checkbox {
}
.ais-toggle--count {
}
.ais-toggle--footer {
}
/**
* Instantiate a list of refinements based on a facet
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {string} options.facetName Name of the attribute for faceting
* @param {string} [options.operator='or'] How to apply refinements. Possible values: `or`, `and`
* @param {string[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
* @param {string} [options.limit=1000] How much facet values to get
* @param {Object} [options.cssClasses] CSS classes to add
* @param {string|string[]} [options.cssClasses.root] CSS class to add to the root element
* @param {string|string[]} [options.cssClasses.header] CSS class to add to the header element
* @param {string|string[]} [options.cssClasses.body] CSS class to add to the body element
* @param {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
* @param {string|string[]} [options.cssClasses.list] CSS class to add to the list element
* @param {string|string[]} [options.cssClasses.item] CSS class to add to each item element
* @param {string|string[]} [options.cssClasses.active] CSS class to add to each active element
* @param {string|string[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
* @param {string|string[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
* @param {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.header] Header template
* @param {string|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
* @param {string|Function} [options.templates.footer] Footer template
* @param {Function} [options.transformData] Function to change the object passed to the item template
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
* @return {Object}
*/
<div id="brands"></div>
search.addWidget(
instantsearch.widgets.refinementList({
container: '#brands',
facetName: 'brands'
})
);
<div class="ais-refinement-list">
<div class="ais-refinement-list--header ais-header">[custom header template]</div>
<div class="ais-refinement-list--body">
<div class="ais-refinement-list--list">
<div class="ais-refinement-list--item">
<label class="ais-refinement-list--label">
<input type="checkbox" class="ais-refinement-list--checkbox" value="your_value"> Your value
<span class="ais-refinement-list--count">42</span>
</label>
</div>
<div class="ais-refinement-list--item ais-refinement-list--item__active">
<label class="ais-refinement-list--label">
<input type="checkbox" class="ais-refinement-list--checkbox" value="your_selected_value" checked="checked"> Your selected value
<span class="ais-refinement-list--count">42</span>
</label>
</div>
</div>
</div>
<div class="ais-refinement-list--footer ais-footer">[custom footer template]</div>
</div>
.ais-refinement-list {
}
.ais-refinement-list--header {
}
.ais-refinement-list--body {
}
.ais-refinement-list--list {
}
.ais-refinement-list--item {
}
.ais-refinement-list--item__active {
}
.ais-refinement-list--label {
}
.ais-refinement-list--checkbox {
}
.ais-refinement-list--count {
}
.ais-refinement-list--footer {
}
/**
* Create a menu out of a facet
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {string} options.facetName Name of the attribute for faceting
* @param {string[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
* @param {string} [options.limit=100] How many facets values to retrieve
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
* @param {string|string[]} [options.cssClasses.root] CSS class to add to the root element
* @param {string|string[]} [options.cssClasses.header] CSS class to add to the header element
* @param {string|string[]} [options.cssClasses.body] CSS class to add to the body element
* @param {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
* @param {string|string[]} [options.cssClasses.list] CSS class to add to the list element
* @param {string|string[]} [options.cssClasses.item] CSS class to add to each item element
* @param {string|string[]} [options.cssClasses.active] CSS class to add to each active element
* @param {string|string[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
* @param {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.header=''] Header template
* @param {string|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
* @param {string|Function} [options.templates.footer=''] Footer template
* @param {Function} [options.transformData] Method to change the object passed to the item template
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
* @return {Object}
*/
<div id="categories"></div>
search.addWidget(
instantsearch.widgets.menu({
container: '#categories',
facetName: 'categories'
})
);
<div class="ais-menu">
<div class="ais-menu--header ais-header">[custom header template]</div>
<div class="ais-menu--body">
<div class="ais-menu--list">
<div class="ais-menu--item">
<a class="ais-menu--link" href="/url">
Your value
<span class="ais-menu--count">42</span>
</a>
</div>
<div class="ais-menu--item ais-menu--item__active">
<a class="ais-menu--link" href="/url">
Your active value
<span class="ais-menu--count">42</span>
</a>
</div>
</div>
</div>
<div class="ais-menu--footer ais-footer">[custom footer template]</div>
</div>
.ais-menu {
}
.ais-menu--header {
}
.ais-menu--body {
}
.ais-menu--list {
}
.ais-menu--item {
}
.ais-menu--item__active {
}
.ais-menu--link {
}
.ais-menu--count {
}
.ais-menu--footer {
}
/**
* Instantiate a slider based on a numeric attribute
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {string} options.facetName Name of the attribute for faceting
* @param {boolean|Object} [options.tooltips=true] Should we show tooltips or not.
* The default tooltip will show the formatted corresponding value without any other token.
* You can also provide
* tooltips: {format: function(formattedValue, rawValue) {return '$' + formattedValue}}
* So that you can format the tooltip display value as you want
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.header=''] Header template
* @param {string|Function} [options.templates.footer=''] Footer template
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, body
* @param {string|string[]} [options.cssClasses.root] CSS class to add to the root element
* @param {string|string[]} [options.cssClasses.body] CSS class to add to the body element
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
* @return {Object}
*/
<div id="price"></div>
search.addWidget(
instantsearch.widgets.rangeSlider({
container: '#price',
facetName: 'price',
tooltips: {
format: function(formattedValue) {
return '$' + formattedValue;
}
}
})
);
/**
* Instantiate a price ranges on a numerical facet
* @param {string|DOMElement} options.container Valid CSS Selector as a string or DOMElement
* @param {string} options.facetName Name of the attribute for faceting
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, range
* @param {string|string[]} [options.cssClasses.root] CSS class to add to the root element
* @param {string|string[]} [options.cssClasses.header] CSS class to add to the header element
* @param {string|string[]} [options.cssClasses.body] CSS class to add to the body element
* @param {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
* @param {string|string[]} [options.cssClasses.range] CSS class to add to the range element
* @param {string|string[]} [options.cssClasses.input] CSS class to add to the min/max input elements
* @param {string|string[]} [options.cssClasses.button] CSS class to add to the button element
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.range] Range template
* @param {Object} [options.labels] Labels to use for the widget
* @param {string|Function} [options.labels.button] Button label
* @param {string|Function} [options.labels.currency] Currency label
* @param {string|Function} [options.labels.to] To label
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
* @return {Object}
*/
search.addWidget(
instantsearch.widgets.priceRanges({
container: '#price-ranges',
facetName: 'price'
})
);
/**
* Create a hierarchical menu using multiple attributes
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {string[]} options.attributes Array of attributes to use to generate the hierarchy of the menu.
* You need to follow some conventions:
* @param {string[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
* @param {number} [options.limit=100] How much facet values to get
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
* @param {string|string[]} [options.cssClasses.root] CSS class to add to the root element
* @param {string|string[]} [options.cssClasses.header] CSS class to add to the header element
* @param {string|string[]} [options.cssClasses.body] CSS class to add to the body element
* @param {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
* @param {string|string[]} [options.cssClasses.list] CSS class to add to the list element
* @param {string|string[]} [options.cssClasses.item] CSS class to add to each item element
* @param {string|string[]} [options.cssClasses.active] CSS class to add to each active element
* @param {string|string[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
* @param {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
* @param {Object} [options.templates] Templates to use for the widget
* @param {string|Function} [options.templates.header=''] Header template (root level only)
* @param {string|Function} [options.templates.item] Item template
* @param {string|Function} [options.templates.footer=''] Footer template (root level only)
* @param {Function} [options.transformData] Method to change the object passed to the item template
* @param {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
* @return {Object}
*/
All the attributes
should be added to attributesForFaceting
in your index settings.
Your index's objects must be formatted in a way that is expected by the hierarchicalMenu
widget:
{
"objectID": "123",
"name": "orange",
"categories": {
"lvl0": "fruits",
"lvl1": "fruits > citrus"
}
}
search.addWidget(
instantsearch.widgets.hierarchicalMenu({
container: '#products',
attributes: ['categories.lvl0', 'categories.lvl1', 'categories.lvl2']
})
);
<div class="ais-hierarchical-menu">
<div class="ais-hierarchical-menu--header ais-header">[custom header template]</div>
<div class="ais-hierarchical-menu--body">
<div class="ais-hierarchical-menu--list ais-hierarchical-menu--list__lvl0">
<div class="ais-hierarchical-menu--item">
<a class="ais-hierarchical-menu--link" href="/url">
Your value
<span class="ais-hierarchical-menu--count">42</span>
</a>
</div>
<div class="ais-hierarchical-menu--item ais-hierarchical-menu--item__active">
<a class="ais-hierarchical-menu--link" href="/url">
Your active value
<span class="ais-hierarchical-menu--count">42</span>
</a>
<div class="ais-hierarchical-menu--list ais-hierarchical-menu--list__lvl1">
<div class="ais-hierarchical-menu--item">
<a class="ais-hierarchical-menu--link" href="/url">
Your subvalue 1
<span class="ais-hierarchical-menu--count">10</span>
</a>
</div>
<div class="ais-hierarchical-menu--item">
<a class="ais-hierarchical-menu--link" href="/url">
Your subvalue 2
<span class="ais-hierarchical-menu--count">32</span>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="ais-hierarchical-menu--footer ais-footer">[custom footer template]</div>
</div>
.ais-hierarchical-menu {
}
.ais-hierarchical-menu--header {
}
.ais-hierarchical-menu--body {
}
.ais-hierarchical-menu--list {
}
.ais-hierarchical-menu--list__lvl0 {
}
.ais-hierarchical-menu--list__lvl1 {
}
.ais-hierarchical-menu--item {
}
.ais-hierarchical-menu--item__active {
}
.ais-hierarchical-menu--link {
}
.ais-hierarchical-menu--count {
}
.ais-hierarchical-menu--footer {
}
We natively support IE10+ and all other modern browsers without any dependency need on your side.
To get < IE10 support, please insert this code in the <head>
:
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<!--[if lte IE 9]>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
<![endif]-->
We use the polyfill.io.
FAQs
InstantSearch.js is a JavaScript library for building performant and instant search experiences with Algolia.
The npm package instantsearch.js receives a total of 223,635 weekly downloads. As such, instantsearch.js popularity was classified as popular.
We found that instantsearch.js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.