supafolio-sdk

1.4.1 • Public • Published

Supadu

Supafolio JavaScript SDK

This JavaScript SDK is available for users looking to quickly and easily build predictive autocomplete search fields, product carousels, search results and full details pages through the use of easily configurable widgets.

Build Status Coverage Status npm version

Supafolio JavaScript SDK Preview


Table of Contents


Installation

The JavaScript SDK works on the frontend, it is UMD compatible and can be used it with any module loader. When not using any module loader, it will export a supafolio function in the window object.

jsDelivr

<link href="https://cdn.jsdelivr.net/npm/supafolio-sdk@0/dist/supafolio.min.css" rel="stylesheet"  />
<script src="https://cdn.jsdelivr.net/npm/supafolio-sdk@0/dist/supafolio.min.js" type="text/javascript"></script>

npm

$ npm install --save supafolio-sdk

You need to manually load the companion CSS file into your page.

Alternatively you can import the css in your JavaScript if you're using a module loader

import "node_modules/supafolio-sdk/dist/supafolio.min.css";

Features

  • Predictive autocomplete widget
    • Displays suggestions to end-users as they type
    • Shows top suggestion as a hint (i.e. background text)
    • Supports custom templates to allow for UI flexibility
    • Triggers custom events
  • Item lookup widget
    • Displays a list, grid or carousel of results to end-users
    • Number of results per row configurable
    • Features of the carousel can be customised (i.e. navigational dots)
    • Carousel triggers custom events
  • Full details widget
    • Allows end-users to create custom templates to display item data
    • Filter used to fetch data is configurable
  • Search results widget
    • Completely customise a search results using sub widgets
    • Search parameters management
    • Multiple types of filters to choose from
    • Pagination and / or Load More widgets
    • Supports custom created sub widgets

Usage

To initialise the Supafolio JavaScript SDK, you need a Supafolio account and the accompanying Application ID, API Key and Catalog ID.

Once you have this, in 30 seconds this basic usage example will show you how to add a simple widget to display a lookup carousel.

Initialise the client

You first need to initialise the client. For that you need your Application ID, API Key and Catalog ID. For demo purposes only you can use the example Application ID, API Key and Catalog ID shown below. If you want to apply static data from S3 and don't do any Algolia requests, you can pass a staticData boolean in the opts object e.g opts = { staticData: true }

// const supafolio = require( "supafolio-sdk" );
// import supafolio from "supafolio-sdk";
// or just use supafolio if you are using a <script> tag
const client = supafolio( "LZ2Q6SA8YD", "2ed4b5c343fb7251f8a86c87ae3e8b76", "demo", opts );

Use the addLookupWidget method to render a carousel of products in the Fiction collection.

NOTE: The container option is required with all widgets, it defines where on the page the widget should be rendered. The container option accepts a standard CSS selector or DOM element. It is referenced using document.querySelector which means, if a class name selector is used, the first one found will be the container.

client.addLookupWidget({
    container: "#products-lookup-wrapper",
    source: "products",
    collection: "Fiction",
    perRow: 5,
    templates: {
        item: `<img src="{{ item.image }}" alt="{{ item.title }}" />`
    }
});

Documentation

Predictive autocomplete widget

Adds a fast and fully-featured auto-completion menu to your search box displaying results "as you type".

Setup

There are 2 required options needed to add a predictive autocomplete widget container and sources. See below for option definitions.

client.addPredictiveWidget({
    container: "#predictive-wrapper",
    sources: ["products"],
});

Supafolio Predictive Widget

Options

  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • sources - Required (Array) - This defines which index the predictive search will get your suggestions from.
    • Array can contain a simple string of the index. i.e. products, contributors or supplementals.
    • Array can contain an object for the index source to allow other options to be set.
      • name - Required (String) - The name of the index to query.
      • displayKey - (String) - The field to use when a suggestion is selected.
      • header- (String) - The label to use for the section header
      • suggestion: - (String) - The template to use for the suggestion,
      • hitsPerPage: - (Number) - The maximum number of results to return for a section.
  • highlightResult - (Boolean) - Defines whether the returned values should have the matches highlighted. Defaults to true.
  • placeholder - (String) - The placeholder text to add to the search box
  • inputID - (String) - Required if the input template is changed to identify the ID of the search input field to attach the autocomplete to.
  • templates - (Object) - Allows the default templates to be changed
    • input - (String) - The template used to render the search box
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the wrapping DOMElement. Defaults to supafolio-predictive-search-box.
    • input - (String) - The class used for the search input field. Defaults to supafolio-predictive-search-box__input.
  • options - (Object) - Options used to control the behaviour of the autocomplete
    • autoselect - (Boolean) - If true, the first rendered suggestion in the dropdown will automatically selected.
    • autoselectOnBlur - (Boolean) – If true, when the input is blurred, the first rendered suggestion in the dropdown will automatically selected.
    • hint(Boolean) – If false, the autocomplete will not show a hint. Defaults to true.
    • debug(Boolean) – If true, the autocomplete will not close on blur. Defaults to false.
    • openOnFocus - (Boolean) – If true, the dropdown menu will open when the input is focused. Defaults to false.
    • appendTo(String) – If set with a DOM selector, doesn't wrap the input and appends the wrapper and dropdown menu to the first DOM element matching the selector. It automatically positions the wrapper under the input, and sets it to the same width as the input. Can't be used with hint: true, because hint requires the wrapper around the input.
    • dropdownMenuContainer(String) – If set with a DOM selector, it overrides the container of the dropdown menu.
    • cssClasses - (Object) - Allows the default css classes to be changed.
      • root(String) – the root classes. Defaults to supafolio-autocomplete.
      • prefix(String) – the CSS class prefix of all nested elements. Defaults to supafolio.
      • noPrefix - (Boolean) – set this to true if you wish to not use any prefix. Without this option, all nested elements classes will have a leading dash. Defaults to false.
      • dropdownMenu(String) – the dropdown menu CSS class. Defaults to dropdown-menu.
      • input(String) – the input CSS class. Defaults to input.
      • hint(String) – the hint CSS class. Defaults to hint.
      • suggestions(String) – the suggestions list CSS class. Defaults to suggestions.
      • suggestion(String) – the suggestion wrapper CSS class. Defaults to suggestion.
      • cursor(String) – the cursor CSS class. Defaults to cursor.
      • dataset(String) – the dataset CSS class. Defaults to dataset.
      • empty(String) – the empty CSS class. Defaults to empty.
    • minLength – The minimum character length needed before suggestions start getting rendered. Defaults to 1.
    • autoWidth – This option allow you to control the width of autocomplete wrapper. When false the autocomplete wrapper will not have the width style attribute and you are be able to put your specific width property in your css to control the wrapper. Default value is true.

Events

The autocomplete component triggers the following custom events. These functions are added to the options object passed to addPredictiveWidget.

  • opened - (Function) - Triggered when the dropdown menu of the autocomplete is opened.
  • shown - (Function) - Triggered when the dropdown menu of the autocomplete is shown (opened and non-empty).
  • empty - (Function) - Triggered when all datasets are empty.
  • closed - (Function) - Triggered when the dropdown menu of the autocomplete is closed.
  • updated - (Function) - Triggered when a dataset is rendered.
  • selected - (Function) - Triggered when a suggestion from the dropdown menu is selected. The event handler will be invoked with 3 arguments: the event object, the suggestion object, and the name of the dataset the suggestion belongs to.

Item lookup widget

The lookup widget allows you to create either a list, grid or carousel of results based on a list of IDs, a named collection or a custom query filter.

Setup

There are 4 required options needed to add a item lookup autocomplete widget container, source, templates.item and either collection, objectIDs or filter. See below for option definitions.

client.addLookupWidget({
    container: "#products-lookup-wrapper",
    collection: "Fiction",
    source: "products",
    templates: {
      item: `<img src="{{ item.image }}" alt="{{ item.title }}" />`
    }
});

Supafolio Lookup Widget

Options

  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • source - Required (String) - This defines which index the lookup search will get your results from. i.e. products, contributors or supplementals.
  • filter - (String) - Used to set a query to fetch items. See examples below.
  • collection - (String) - Will return items which are in the defined collection.
  • objectIDs - (Array) - Accepts an array of IDs. Results matching those IDs are returned.
  • static - (Boolean) - Set to true to avoid requesting product data from Algolia.
  • ranking - (String) - States how the results should be ordered. Available static values are relevance:desc, relevance:asc, asEntered:desc, asEntered:asc. Other sort by options are based on replicas that have been set up for your data. i.e. if your data it set up to sort by publication date you could pass the publication date data attribute as publicationDate:desc or publicationDate:asc.
  • hitsPerPage - (Number) - Sets how many items to be returned. Maximum is 100. Defaults to 100.
  • perRow - (Number) - Sets how many items to render on each row of the layout grid. Defaults to 5.
  • distinct - (Boolean) - Allows items in the same data grouping to not all be returned. Defaults to false.
  • itemAlign - (String) - Define how to align content in the grid. Available values are left, center or right. Defaults to center.
  • carousel - (Object | Boolean) - Set to false to disable the carousel and instead render a grid or list. Set an Object of options to customise the behaviour of the carousel. The carousel is built using Flickity for a list of available options see the documentation. The Flickity object will be return if carousel is enabled, see example below.
  • resultHandler - (Function) - Method to change the item data passed to the template. A data object must be returned by this method.
  • templates - (Object) - Allows the default templates to be changed
    • item - (String) - The template used each result item. If not defined then a JSON string of the item will be output.
  • classes - (Object) - Allows the default css classes to be changed
    • columns - (String) - The class used for each of the grid columns generated. Defaults to supafolio-grid-columns.
Option examples
filter

Get products with the imprint Pan or Picador.

client.addLookupWidget({
    filter: "imprint:Pan OR imprint:Picador"
});

Get products with the imprint Pan or Picador and is an eBook format.

client.addLookupWidget({
    filter: "(imprint:Pan OR imprint:Picador) AND format:eBook"
});

Get products with the imprint Pan or Picador that is an eBook format and less than £10.

client.addLookupWidget({
    filter: "(imprint:Pan OR imprint:Picador) AND format:eBook AND prices.GBP < 10"
});
resultHandler

Add an SEO friendly version of the title to the item.

client.addLookupWidget({
    resultHandler( item ) {
        item.seoTitle = client.helpers.seoURL( item.title );
        return item;
    }
});
carousel

Trigger the Flickity resize method to resize the carousel and re-position cells.

client.addLookupWidget( options ).then( carousel => {
    carousel.resize();
});

Full details widget

Queries the API for a specific record to create a page which renders all the data for that record.

Setup

There are 4 required options needed to add a full details widget container, source, objectID and templates.item. See below for option definitions.

client.addDetailsWidget({
    container: "#products-details-wrapper",
    objectID: "9781447294627",
    source: "products",
    templates: {
      item: `<div>
                 <img src="{{ item.image }}" alt="{{ item.title }}" />
                 <h1>{{item.title}}</h1>
                 <h2>{{item.subtitle}}</h2>
                 <h3>{{item.contributorByLine}}</h3>
                 <div >{{{item.description}}}</div>
             </div>`   
    }
});

Supafolio Details Widget

Options

  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • source - Required (String) - This defines which index the item will be returned from. i.e. products, contributors or supplementals.
  • objectID - Required (String) - A single result matching this ID will be returned.
  • getContributorSupplementals - Required (Boolean) - If true, a second query will be made on calls for products to get all the supplementals for matching contributors. Defaults to false.
  • resultHandler - (Function) - Method to change the item data passed to the template. A data object must be returned by this method.
  • templates - (Object) - Allows the default templates to be changed
    • item - (String) - The template used the result item. If not defined then a JSON string of the item will be output.
  • classes - (Object) - Allows the default css classes to be changed
    • columns - (String) - The class used for each of the grid columns generated. Defaults to supafolio-grid-columns.
  • static - (Object) - (Optional) Determines if indexes should not be queried from Algolia
    • products - (Boolean) - Set to true to avoid requesting product data from Algolia
    • contributors - (Boolean) - Set to true to avoid requesting contributor data from Algolia

NOTE: The product/contributor link information is part of the contributor record and can be accessed on the method from inside resultHandler method.

Search results widget

The search results widget is set up slightly differently to the other widgets. A search results page is made up of individual components, also known as widgets. Widgets are UI components for either the search input (search bar, facets/filters, etc.) or the search output (actual results). See below of a

Each widget is independent, and their rendering is bound to the search. They have the following lifecycle:

  • Configuration - each widget can add new query parameters.
  • Initial rendering - before the initial search, the widget may update the UI.
  • Rendering - on each search, after the results come back, the widgets update themselves.

Setup

Initialisation

There is only 1 required option needed to add a search details widget source. See below for option definitions.

const search = client.search({
    source: "products"
});
Options
  • source - Required (String) - This defines which index the lookup search will get your results from. i.e. products, contributors or supplementals.
  • searchFunction - (Function) - A hook that will be called each time a search needs to be done, with the helper as a parameter. It’s your responsibility to call helper.search(). This option allows you to avoid doing searches at page load for example.
  • searchParameters - (Object) - Additional parameters to pass to the Search API. For a list of available options see the documentation
  • urlSync - (Object | Boolean) - Allows the current search to be synchronised with the browser url. Defaults to true. Set to false to disable url synchronisation. Set an Object of options to customise the behaviour of the url synchronisation.
    • mapping - (Object) - Object used to define replacement query parameter to use in place of another. Keys are current query parameters and value the new value, e.g. { q: 'query' }.
    • threshold - (Number) - Idle time in ms after which a new state is created in the browser history. Defaults to 700. The url is always updated at each keystroke but we only create a "previous search state" (activated when click on back button) every 700ms of idle time.
    • tracked - (Array) - Accepts an array of strings. Parameters that will be synchronised in the URL. Defaults to ["query", "attribute:*", "index", "page", "hitsPerPage"]. attribute:* means all the faceting attributes will be tracked. You can track only some of them by using attribute:imprint, attribute:categories.

NOTE: URL synchronisation provides two benefits:

  • Working back/next browser buttons
  • Copy and share the current search url

NOTE: By default the URL parameter of the result page is p. This is a reserved query parameter in WordPress. If you have urlSync enabled you will need to provide a mapping of p to a new custom query parameter. i.e. mapping: { p: "supafolio_page" }.

Add widgets

To build your search results page, you need to combine several widgets. Start by adding a searchBox widget, a results widget, and a pagination widget to build a basic results page.

search.addWidget(
    search.widgets.searchBox({
        container: "#search-box-wrapper"
    })
);

Note: The Supafolio JavaScript SDK comes with built-in widgets, but you can also build your own custom widgets:

search.addWidget({
    getSearchParameters() {},
    init() {},
    render() {}
});

You can also add multiple at the same time.

search.addWidget(
    search.widgets.searchBox({
        container: "#search-box-wrapper"
    }),
    search.widgets.stats({
        container: "#stats-wrapper"
    })
);
Start

Once all the widgets have been added to the search instance, start the rendering by calling the start() method.

search.start();

Supafolio Details Widget

Search Widgets

Search Box Widget

The search box widget is where you users type their search queries.

search.addWidget(
    search.widgets.searchBox({
        container: "#search-box-wrapper"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • placeholder - (String) - The placeholder text to add to the search box
  • wrapInput - (Boolean) - Wrap the input in a div. Defaults to true.
  • clearRefinementsOnSearch - (Boolean) - If true all refinements will be remove when a new query is typed. Defaults to true.
  • inputID - (String) - Required if the input template is changed to identify the ID of the search input field.
  • templates - (Object) - Allows the default templates to be changed
    • searchBox - (String) - The template used to render the search box
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the wrapping DOMElement. Defaults to supafolio-search-box.
    • input - (String) - The class used for the search input field. Defaults to supafolio-search-box__input.

Results Widget

The results widget is the main component that displays results from Supafolio.

search.addWidget(
    search.widgets.results({
        container: "#results-wrapper"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • perRow - (Number) - Sets how many items to render on each row of the layout grid.
  • itemAlign - (String) - Define how to align content in the grid. Available values are left, center or right. Defaults to center.
  • loadMore - Required (String | DOMElement) - CSS selector or DOM element defining where the linked load more button is located. This is used when using a load more widget instead of the pagination widget for page navigation.
  • resultHandler - (Function) - Method to change the item data passed to the template. A data object must be returned by this method.
  • templates - (Object) - Allows the default templates to be changed
    • empty - (String) - The template used when there are item found
    • item - (String) - The template used to render the result item
  • classes - (Object) - Allows the default css classes to be changed
    • columns - (String) - The class used for each of the grid columns generated. Defaults to supafolio-grid-columns.

Sort By Selector Widget

The sort by selector widget lets you reorder your results. You need multiple indices for this to work.

search.addWidget(
    search.widgets.sortBySelector({
        container: "#sort-by-wrapper"
        options: [
          { value: "prices_gbp_desc", label: "Highest price" },
          { value: "prices_gbp_asc", label: "Lowest price" }
        ]
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • options - Required (Array) - This defines which the options to add to the dropdown. Expects objects defining a value and label.
    • value Required (String) - The name of the index to target
    • label Required (String) - The label displayed in the dropdown
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • selectID - (String) - Required if the select template is changed to identify the ID of the select field.
  • templates - (Object) - Allows the default templates to be changed
    • sortBySelector - (String) - The template used render the select

Per Page Selector Widget

The per page selector widget lets you select the number of results you want displayed at once.

search.addWidget(
    search.widgets.perPageSelector({
        container: "#per-page-wrapper"
        options: [
          { value: 1, label: "1 per page" },
          { value: 10, label: "10 per page" },
          { value: 100, label: "100 per page" }
        ]
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • options - Required (Array) - This defines which the options to add to the dropdown. It must contain the default value based on the search parameters set. Details to 20. Expects objects defining a value and label.
    • value Required (Number) - Number of hits to display per page
    • label Required (String) - Label to display in the option
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • selectID - (String) - Required if the select template is changed to identify the ID of the select field.
  • templates - (Object) - Allows the default templates to be changed
    • perPageSelector - (String) - The template used render the select

Pagination Widget

The pagination widget provides the ability to navigate through results pages.

search.addWidget(
    search.widgets.pagination({
        container: "#pagination-wrapper"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • padding - (Number) - The number of pages to display on each side of the current page. Defaults to 3.
  • showFirstLast - (Boolean) - Define if the first and last links should be displayed. Defaults to true
  • hideSinglePage - (Boolean) - If true, the pagination will be hidden if there is only one page of results. Defaults to false
  • scrollTo - (String | DOMElement | Boolean) - Where to scroll after a click, set to false to disable. Defaults to body.
  • scrollToTransition - (Boolean) - If true, the scroll to will transition rather than jump to position. Defaults to false.
  • labels - (Object) - Text to display in the various links (first, previous, next, last).
    • first (String) - Label for the first link
    • previous (String) - Label for the previous link
    • next (String) - Label for the next link
    • last (String) - Label for the last link
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the element wrapping the pagination items. Defaults to supafolio-pagination__wrapper.
    • item - (String) - The class used for each item. Defaults to supafolio-pagination__item.
    • link - (String) - The class used for each item link. Defaults to supafolio-pagination__link.
    • active - (String) - The class used for each item which is clickable. Defaults to supafolio-pagination__item--active.
    • disabled - (String) - The class used for each item which is not clickable. Defaults to supafolio-pagination__item--disabled.
    • first - (String) - The class used for the item which takes the user to the first page. Defaults to supafolio-pagination__item--first.
    • previous - (String) - The class used for the item which takes the user to the previous page. Defaults to supafolio-pagination__item--previous.
    • page - (String) - The class used for the item which takes the user to a new page. Defaults to supafolio-pagination__item--pages.
    • next - (String) - The class used for the item which takes the user to the next page. Defaults to supafolio-pagination__item--next.
    • last - (String) - The class used for the item which takes the user to the last page. Defaults to supafolio-pagination__item--last.

Load More Widget

The load more widget displays a button to load more results. It will display the results as one continuous long page. It's usage is particularly recommended in a mobile context. Even though it is not incompatible, it does not go well with the pagination widget.

search.addWidget(
    search.widgets.loadMore({
        container: "#load-more-wrapper"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • preloader - (Boolean) - If false, no preloader will be rendered when the button is clicked. Defaults to true.
  • label - (String) - The text label of the button.
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the div wrapping the button. Defaults to supafolio-load-more__wrapper.
    • disabled - (String) - The class used for button is disabled i.e. when there are no more pages to load. Defaults to "supafolio-load-more__wrapper--disabled.
    • button - (String) - The class used for load more button. Defaults to supafolio-load-more__button.

NOTE: A load more widget must be linked to the results widget using the loadMore option of the results widget.

Stats Widget

This widget lets you display how many results matched the query and how fast the search was.

search.addWidget(
    search.widgets.stats({
        container: "#stats-wrapper"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • statsHandler - (Function) - Method to change the data passed to the template. A data object must be returned by this method.
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the div wrapping the stats. Defaults to supafolio-stats__wrapper.
    • time - (String) - The class used for query time. Defaults to supafolio-stats__time.
  • templates - (Object) - Allows the default templates to be changed
    • stats - (String) - The template used render the stats. Provided with hasManyResults, hasNoResults, hasOneResult, resultsPerPage, totalResults, totalPages, currentPage, processingTimeMS and query.

Clear All Widget

This widget clears the query and all the refinements that are currently applied.

search.addWidget(
    search.widgets.clearAll({
        container: "#clear-all-wrapper"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • label - (String) - The text label of the button.
  • excludes - (Array) - Expects an array of Strings. A list of attribute which should not be cleared.
  • autoHide - (Boolean) - Hide the container when no refinements are found. Defaults to true.
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the div wrapping the button. Defaults to supafolio-clear-all__wrapper.
    • button - (String) - The class used for clear all button. Defaults to supafolio-clear-all__button.

Refinement List Filter Widget

This filtering widget lets the user refine the search results. You can specify if you want filters to be OR'ed or AND'ed. For example, if you filter on a and b with OR, results with either the value a or b will match.

search.addWidget(
    search.widgets.refinementFilter({
        container: "#refinement-filter-wrapper",
        attribute: "categories.name",
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • attribute - Required (String) - Name of the attribute to filter against.
  • operator - (String) - How to apply refinements. Possible values: or, and, equals. The equals operator is used when you want to create a refinement list where only one filter can be selected at a time. Defaults to or.
  • sortBy - (Array | Function) - Array of strings expected. Defines how to sort refinements. Possible values: count:asc, count:desc, name:asc, name:desc, isRefined. You can also use a sort function that behaves like the standard Javascript compareFunction. Defaults to ["isRefined", "name:asc"]. For instances where equals is set as the operator it defaults to ["count:desc", "name:desc"].
  • limit - (Number) - How many filter values to get. When the show more feature is activated this is the minimum number of filters requested. Defaults to 10.
  • showMore - (Object | Boolean) - Set to false to disable show more button. Set an Object of options to customise the behaviour of the show more button. Defaults to true.
    • open - (Boolean) - If true, the show more will be open by default. Defaults to false.
    • moreLabel - (String) - The button label when the show more is closed.
    • lessLabel - (String) - The button label when the show more is open.
    • limit - (Number) - Max number of filter values to display when show more is clicked
  • collapsible - (Object | Boolean) - Set to true to allow the filter header to hide the body when clicked. Set an Object of options to customise the behaviour of the collapsible state. Defaults to false.
    • collapsed - (Boolean) - If true, the filter will be closed by default. Defaults to false.
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • resultHandler - (Function) - Method to change the filter passed to the template. A data object must be returned by this method.
  • templates - (Object) - Allows the default templates to be changed
    • header - (String) - The template used to render the header
    • item - (String) - The template used to render each filter
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the element wrapping the filter. Defaults to supafolio-refinement-filter__wrapper.
    • header - (String) - The class used for the filter header. Defaults to supafolio-refinement-filter__item--header.
    • body - (String) - The class used for the filter body. Defaults to supafolio-refinement-filter__body.
    • list - (String) - The class used for the list of filters. Defaults to supafolio-refinement-filter__list.
    • item - (String) - The class used for each filter. Defaults to supafolio-refinement-filter__item.
    • active - (String) - The class used for each filter which is clickable. Defaults to supafolio-refinement-filter__item--active.
    • single - (String) - The class used for each filter when the operator is equals. Defaults to supafolio-refinement-filter__item--single.
    • multiple - (String) - The class used for each filter when the operator is or or and. Defaults to supafolio-refinement-filter__item--multiple.
    • link - (String) - The class used for the filter link. Defaults to supafolio-refinement-filter__link.
    • button - (String) - The class used for show more button. Defaults to supafolio-refinement-filter__show-more-btn.
    • collapsible - (String) - The class used for the header when collapsible is set to true. Defaults to supafolio-refinement-filter__header--collapsible.

Hierarchical Menu Filter Widget

The hierarchical menu is a widget that lets the user explore a tree-like structure. This is commonly used for multi-level categorisation of products on e-commerce websites. From a UX point of view, we suggest not displaying more than two or three levels deep.

search.addWidget(
    search.widgets.hierarchicalMenuFilter({
        container: "#hierarchical-menu-wrapper"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • attributes - (Array) - Expects Strings. Array of attributes to use to generate the hierarchy of the menu. Defaults to ["hierarchicalCategories.lvl0", "hierarchicalCategories.lvl1", "hierarchicalCategories.lvl2"].
  • sortBy - (Array | Function) - Array of strings expected. Defines how to sort refinements. Possible values: count:asc, count:desc, name:asc, name:desc, isRefined. You can also use a sort function that behaves like the standard Javascript compareFunction. Defaults to ["isRefined", "name:asc"].
  • limit - (Number) - How many filter values to get. When the show more feature is activated this is the minimum number of filters requested. Defaults to 10.
  • separator - (String) - Separator used in the attributes to separate level values. Defaults to >.
  • rootPath - (String) - Prefix path to use if the first level is not the root level.
  • showParentLevel - (Boolean) - Show the parent level of the current refined value. Defaults to true.
  • collapsible - (Object | Boolean) - Set to true to allow the filter header to hide the body when clicked. Set an Object of options to customise the behaviour of the collapsible state. Defaults to false.
    • collapsed - (Boolean) - If true, the filter will be closed by default. Defaults to false.
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • resultHandler - (Function) - Method to change the filter passed to the template. A data object must be returned by this method.
  • templates - (Object) - Allows the default templates to be changed
    • header - (String) - The template used to render the header
    • item - (String) - The template used to render each filter
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the element wrapping the filter. Defaults to supafolio-hierarchical-menu-filter__wrapper.
    • header - (String) - The class used for the filter header. Defaults to supafolio-hierarchical-menu-filter__item--header.
    • body - (String) - The class used for the filter body. Defaults to supafolio-hierarchical-menu-filter__body.
    • list - (String) - The class used for the list of filters. Defaults to supafolio-hierarchical-menu-filter__list.
    • item - (String) - The class used for each filter. Defaults to supafolio-hierarchical-menu-filter__item.
    • active - (String) - The class used for each filter which is clickable. Defaults to supafolio-hierarchical-menu-filter__item--active.
    • link - (String) - The class used for the filter link. Defaults to supafolio-hierarchical-menu-filter__link.
    • collapsible - (String) - The class used for the header when collapsible is set to true. Defaults to supafolio-hierarchical-menu-filter__header--collapsible.

Numeric Refinement Filter Widget

This widget lets the user refine search results based on a numerical attribute. You can specify a specific number or a range.

search.addWidget(
    search.widgets.numericRefinementFilter({
        container: "#numeric-refinement-wrapper",
        attribute: "prices.GBP",
        filters: [
          {name: 'All' },
          { end: 7.48, name: 'less than £7.49' },
          { start: 7.49, end: 7.49, name: 'exactly £7.49' },
          { start: 7.50, name: 'more than £7.49' }
        ]
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • attribute - Required (String) - Name of the attribute to filter against.
  • filters - Required (Array) - This defines the filters to render. Expects objects defining a name. If no start or end is defined the filter will clear the refinement.
    • name Required (String) - The name of the filter
    • start (Number) - Low bound of the option (>=)
    • end (Number) - High bound of the option (<=)
  • collapsible - (Object | Boolean) - Set to true to allow the filter header to hide the body when clicked. Set an Object of options to customise the behaviour of the collapsible state. Defaults to false.
    • collapsed - (Boolean) - If true, the filter will be closed by default. Defaults to false.
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • resultHandler - (Function) - Method to change the filter passed to the template. A data object must be returned by this method.
  • templates - (Object) - Allows the default templates to be changed
    • header - (String) - The template used to render the header
    • item - (String) - The template used to render each filter
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the element wrapping the filter. Defaults to supafolio-numeric-refinement-filter__wrapper.
    • header - (String) - The class used for the filter header. Defaults to supafolio-numeric-refinement-filter__item--header.
    • body - (String) - The class used for the filter body. Defaults to supafolio-numeric-refinement-filter__body.
    • list - (String) - The class used for the list of filters. Defaults to supafolio-numeric-refinement-filter__list.
    • item - (String) - The class used for each filter. Defaults to supafolio-numeric-refinement-filter__item.
    • active - (String) - The class used for each filter which is clickable. Defaults to supafolio-numeric-refinement-filter__item--active.
    • link - (String) - The class used for the filter link. Defaults to supafolio-numeric-refinement-filter__link.
    • collapsible - (String) - The class used for the header when collapsible is set to true. Defaults to supafolio-numeric-refinement-filter__header--collapsible.

Toggle Filter Widget

This widget provides an on/off filtering feature based on an attribute value. Note that if you provide an “off” option, it will be refined at initialisation.

search.addWidget(
    search.widgets.toggleFilter({
        container: "#toggle-wrapper",
        attribute: "primaryFormat",
        filter: {
            label: "is primary format?",
            on: 1
        }
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.

  • attribute - Required (String) - Name of the attribute to filter against.

  • filter - Required (Object) - This defines the filter to render. Expects objects defining a label.

    • label Required (String) - The label of the filter
    • on (Number | Boolean | String) - The value to filter on when checked. Defaults to true.
    • off (Number | Boolean | String) - Value to filter on when unchecked. By default when switching to off, no refinement will be asked. So you will get both true and false results. If you set the off value to false then you will get only objects having false has a value for the selected attribute.
  • collapsible - (Object | Boolean) - Set to true to allow the filter header to hide the body when clicked. Set an Object of options to customise the behaviour of the collapsible state. Defaults to false.

    • collapsed - (Boolean) - If true, the filter will be closed by default. Defaults to false.
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.

  • resultHandler - (Function) - Method to change the filter passed to the template. A data object must be returned by this method.

  • templates - (Object) - Allows the default templates to be changed

    • header - (String) - The template used to render the header
    • item - (String) - The template used to render each filter
  • classes - (Object) - Allows the default css classes to be changed

    • wrapper - (String) - The class used for the element wrapping the filter. Defaults to supafolio-toggle-filter__wrapper.
    • header - (String) - The class used for the filter header. Defaults to supafolio-toggle-filter__item--header.
    • body - (String) - The class used for the filter body. Defaults to supafolio-toggle-filter__body.
    • item - (String) - The class used for each filter. Defaults to supafolio-toggle-filter__item.
    • active - (String) - The class used for each filter which is clickable. Defaults to supafolio-toggle-filter__item--active.
    • link - (String) - The class used for the filter link. Defaults to supafolio-toggle-filter__link.
    • collapsible - (String) - The class used for the header when collapsible is set to true. Defaults to supafolio-toggle-filter__header--collapsible.

Range Slider Filter Widget

The range slider widget lets users filter results within a numerical range, based on an attribute. The min and max values are automatically computed using the data in the index.

search.addWidget(
    search.widgets.rangeSliderFilter({
        container: "#range-slider-wrapper",
        attribute: "prices.GBP"
    })
);
Options
  • container - Required (String | DOMElement) - CSS selector or DOM element defining where the widget will be rendered.
  • attribute - Required (String) - Name of the attribute to filter against.
  • pips - (Boolean | Object) - Show slider pips. Defaults to true.
    • density (Number) - The number of pips
    • values (Array) - Expects Numbers. At which percentage to show a labelled pip
  • tooltips - (Boolean | Function) - Method to format the tooltips show above the slider handles Set to false to disable tooltips. Defaults to true,
  • step - (Number) - Every handle move will jump that number of steps. Note if set to 0 the slider will be fluent. Defaults to 1,
  • dragRange - (Boolean) - Set to false to disable the drag on the range between the min and max handles. Defaults to true,
  • collapsible - (Object | Boolean) - Set to true to allow the filter header to hide the body when clicked. Set an Object of options to customise the behaviour of the collapsible state. Defaults to false.
    • collapsed - (Boolean) - If true, the filter will be closed by default. Defaults to false.
  • autoHide - (Boolean) - Hide the container when no results match. Defaults to true.
  • resultHandler - (Function) - Method to change the filter passed to the template. A data object must be returned by this method.
  • templates - (Object) - Allows the default templates to be changed
    • header - (String) - The template used to render the header
    • item - (String) - The template used to render each filter
  • classes - (Object) - Allows the default css classes to be changed
    • wrapper - (String) - The class used for the element wrapping the filter. Defaults to supafolio-range-slider-filter__wrapper.
    • header - (String) - The class used for the filter header. Defaults to supafolio-range-slider-filter__item--header.
    • body - (String) - The class used for the filter body. Defaults to supafolio-range-slider-filter__body.
    • slider - (String) - The class used for the slider container. Defaults to supafolio-range-slider-filter__link.
    • collapsible - (String) - The class used for the header when collapsible is set to true. Defaults to supafolio-range-slider-filter__header--collapsible.

Cheatsheet

Templates

Providing templates

Passing in a big template string into the widget config can tend to get quite unmanageable, especially for the full details widget. Instead, create your template in a script tag with an ID and then select that in the widget config e.g.

<script type="text/html" id="item-template">
    <div class="supafolio-details-item">
        <div class="supafolio-details-item__image-wrapper">
            <img class="supafolio-details-item__image" src="{{item.image}}" alt="{{item.title}}" />
        </div>
        <div class="supafolio-details-item__content">
            <h1 class="details-item__title">{{item.title}}</h1>
            <h2 class="details-item__subtitle">{{item.subtitle}}</h2>
            <h3 class="details-item__contributor-by-line">{{item.contributorByLine}}</h3>
            <div class="details-item__description">{{{item.description}}}</div>
        </div>
    </div>
</script>
client.addDetailsWidget({
    container: "#product-details-wrapper",
    objectID: "9781447294627",
    source: "product",
    templates: {
        item: document.querySelector("#item-template").innerHTML
    }
});

Rendering HTML values in templates

The templates engine uses Handlebars JS, it uses expressions to render data properties. This is done with the use of curly braces, For example, {{title}} would print the title property in the current context. The use of 2 curly braces tells handlebars to print the value as plain text. If the data property contains HTML you can use 3 curly braces to let handlebars know is needs to evaluate the html when it's printed. i.e. {{{description}}}.

For more information please see the documentation

Looping data in templates

To loop through a data array or object you can use the built-in each helper.

For arrays:

{{#each myArray}}
    Index: {{@index}} Value = {{this}}
{{/each}}

For objects:

{{#each myObject}}
    Key: {{@key}} Value = {{this}}
{{/each}}

For more information please see the documentation

Helpers

Date manipulation

Convert a timestamp to a formatted date string

client.helpers.formatTimestamp( 1484197200 );
// Outputs: 12/01/2017

Convert a timestamp to a formatted date string

client.helpers.formatTimestamp( 1484197200 );
// Outputs: 12/01/2017
client.helpers.formatTimestamp( 1484197200, "y-m-d" );
// Outputs: 2017-12-01

Convert a Date to a formatted date string

client.helpers.formatDate( new Date( "12/01/2017" ) );
// Outputs: 12/01/2017
client.helpers.formatDate( new Date( "12/01/2017" ), "y-m-d" );
// Outputs: 2017-12-01

Convert a timestamp to a Date

client.helpers.convertTimestampToDate( 1484197200 );
// Outputs: Thu Jan 12 2017 05:00:00 GMT+0000 (GMT)

Get a timestamp for the start of a date i.e. 00:00:00 of that day - useful for filtering by dates i.e. coming soon on ecommerce websites

client.helpers.getStartOfDate( client.helpers.convertTimestampToDate( 1484197200 ) );
// Outputs: 1484179200000

Get a timestamp for the end of a date i.e. 23:59:59 of that day - useful for filtering by dates i.e. coming soon on ecommerce websites

client.helpers.getEndOfDate( client.helpers.convertTimestampToDate( 1484197200 ) );
// Outputs: 1484265599999

String manipulation

Convert a string to an SEO friendly string - useful for adding data to urls

client.helpers.seoURL( "The messy title's of Books! - part 1..." );
// Outputs: the-messy-titles-of-books-part-1

Resize an image URL (Note, this will only work for Supafolio's image service)

client.helpers.resizeImage( "https://timeinc-us.imgix.net/covers/9781618931566.jpg?w=298", 350 );
// Outputs: https://timeinc-us.imgix.net/covers/9781618931566.jpg?w=350

Custom searches

Get a product by ISBN

search.getByISBN( "9781447294627" ).then( result => {
    if( !result.length ) {
        console.error( "Not found" );
        return;
    }

    const product = result.shift();
} );

Execute a custom search

search.execute( {
    params: {
        query: "search",
        hitsPerPage: 3
    }
} ).then( result => {
    if( !result.hits || !result.hits.length ) {
        console.error( "Not found" );
        return;
    }

    const results = result.hits;
} );

Execute a multiple custom searches

search.execute( [
    {
        params: {
            query: "search 1",
            hitsPerPage: 3
        }
    },
    {
        params: {
            query: "search 2",
            hitsPerPage: 3
        }
    }
] ).then( response => {
    let results1 = response.results[0];
    let results2 = response.results[1];;

    if( !results1.hits || !results1.hits.length ) {
        console.error("Search 1 not found");
    }

    if( !results2.hits || !results2.hits.length ) {
        console.error("Search 2 not found");
    }

    results1 = results1.hits;
    results2 = results2.hits;
} );

Styles

Change the colour of the load more preloader

.supafolio-load-more__preloader {
  border-top-color: rgba(#FFF, 0.65);
  border-bottom-color: rgba(#FFF, 0.15);
  border-left-color: rgba(#FFF, 0.65);
  border-right-color: rgba(#FFF, 0.15);
}

Rule uses for grid columns

.supafolio-grid-columns {
  bottom: 0;
  box-sizing: border-box;
  display: inline-block;
  padding: 0 2%;
  vertical-align: top;
}

FAQ

  • How do I initialise the library?

Simply pass you account details into supafolio

const client = supafolio( "LZ2Q6SA8YD", "2ed4b5c343fb7251f8a86c87ae3e8b76", "demo" );
  • Are there any concerns about JavaScript Delivered Content and SEO?

We recommend all data come through the front-end, served by JavaScript. We recommend this because it is much better for the user experience and happy users are returning users.

In the past, there has been a big concern that web crawlers are unable to see this content. But in 2015, Google announced that they indeed can see it. It is important to note, however, that Google still recommends having individual URLs for the “pages” that the JavaScript response creates.

To do this, you will use the browser APIs that allow you to manipulate the browser history. This is also a good UX principle independent of the SEO benefits (which is generally the case!). Note that we do this automatically with our Search results widget when URL sync is enabled.

However, as the URL above mentions, if you want to be 100% safe then you can pre-render pages on the backend and serve it up to the search engine crawlers. This will increasingly be unnecessary as the web crawlers get better at executing JavaScript.


License

License

Readme

Keywords

none

Package Sidebar

Install

npm i supafolio-sdk

Weekly Downloads

12

Version

1.4.1

License

SEE LICENSE IN LICENSE.md

Unpacked Size

1.29 MB

Total Files

8

Last publish

Collaborators

  • supadu