Last active
May 31, 2017 12:24
-
-
Save timkelty/7186587110e649b210d3f948e5420b5f to your computer and use it in GitHub Desktop.
Add facet count to refinement list header
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React from 'react'; | |
| import ReactDOM from 'react-dom'; | |
| import cx from 'classnames'; | |
| import filter from 'lodash/filter'; | |
| import RefinementList from 'instantsearch.js/dist-es5-module/src/components/RefinementList/RefinementList.js'; | |
| import connectRefinementList from 'instantsearch.js/dist-es5-module/src/connectors/refinement-list/connectRefinementList.js'; | |
| import defaultTemplates from 'instantsearch.js/dist-es5-module/src/widgets/refinement-list/defaultTemplates.js'; | |
| import getShowMoreConfig from 'instantsearch.js/dist-es5-module/src/lib/show-more/getShowMoreConfig.js'; | |
| import { | |
| bemHelper, | |
| prepareTemplateProps, | |
| getContainerNode, | |
| prefixKeys, | |
| } from 'instantsearch.js/dist-es5-module/src/lib/utils.js'; | |
| const bem = bemHelper('ais-refinement-list'); | |
| const renderer = ({ | |
| containerNode, | |
| cssClasses, | |
| transformData, | |
| templates, | |
| renderState, | |
| collapsible, | |
| autoHideContainer, | |
| showMoreConfig, | |
| searchForFacetValues, | |
| }) => ({ | |
| refine, | |
| items, | |
| createURL, | |
| searchForItems, | |
| isFromSearch, | |
| instantSearchInstance, | |
| canRefine, | |
| toggleShowMore, | |
| isShowingMore, | |
| hasExhaustiveItems, | |
| canToggleShowMore, | |
| }, isFirstRendering) => { | |
| if (isFirstRendering) { | |
| renderState.templateProps = prepareTemplateProps({ | |
| transformData, | |
| defaultTemplates, | |
| templatesConfig: instantSearchInstance.templatesConfig, | |
| templates, | |
| }); | |
| return; | |
| } | |
| // Pass count of currently selected items to the header template | |
| const headerFooterData = { | |
| header: { | |
| facetsCount: items.length, | |
| refinedFacetsCount: filter(items, {isRefined: true}).length, | |
| }, | |
| }; | |
| ReactDOM.render( | |
| <RefinementList | |
| collapsible={collapsible} | |
| createURL={createURL} | |
| cssClasses={cssClasses} | |
| facetValues={items} | |
| headerFooterData={headerFooterData} | |
| shouldAutoHideContainer={autoHideContainer && canRefine === false} | |
| templateProps={renderState.templateProps} | |
| toggleRefinement={refine} | |
| searchFacetValues={searchForFacetValues ? searchForItems : undefined} | |
| searchPlaceholder={searchForFacetValues.placeholder || 'Search for other...'} | |
| isFromSearch={isFromSearch} | |
| showMore={showMoreConfig !== null} | |
| toggleShowMore={toggleShowMore} | |
| isShowingMore={isShowingMore} | |
| hasExhaustiveItems={hasExhaustiveItems} | |
| canToggleShowMore={canToggleShowMore} | |
| />, | |
| containerNode | |
| ); | |
| }; | |
| const usage = `Usage: | |
| refinementList({ | |
| container, | |
| attributeName, | |
| [ operator='or' ], | |
| [ sortBy=['isRefined', 'count:desc', 'name:asc'] ], | |
| [ limit=10 ], | |
| [ cssClasses.{root, header, body, footer, list, item, active, label, checkbox, count}], | |
| [ templates.{header,item,footer} ], | |
| [ transformData.{item} ], | |
| [ autoHideContainer=true ], | |
| [ collapsible=false ], | |
| [ showMore.{templates: {active, inactive}, limit} ], | |
| [ collapsible=false ], | |
| [ searchForFacetValues.{placeholder, templates: {noResults}}], | |
| })`; | |
| export default function refinementList({ | |
| container, | |
| attributeName, | |
| operator = 'or', | |
| sortBy = ['isRefined', 'count:desc', 'name:asc'], | |
| limit = 10, | |
| cssClasses: userCssClasses = {}, | |
| templates = defaultTemplates, | |
| collapsible = false, | |
| transformData, | |
| autoHideContainer = true, | |
| showMore = false, | |
| searchForFacetValues = false, | |
| } = {}) { | |
| if (!container) { | |
| throw new Error(usage); | |
| } | |
| const showMoreConfig = getShowMoreConfig(showMore); | |
| if (showMoreConfig && showMoreConfig.limit < limit) { | |
| throw new Error('showMore.limit configuration should be > than the limit in the main configuration'); // eslint-disable-line | |
| } | |
| const showMoreLimit = showMoreConfig && showMoreConfig.limit || limit; | |
| const containerNode = getContainerNode(container); | |
| const showMoreTemplates = showMoreConfig ? prefixKeys('show-more-', showMoreConfig.templates) : {}; | |
| const searchForValuesTemplates = searchForFacetValues ? searchForFacetValues.templates : {}; | |
| const allTemplates = {...templates, ...showMoreTemplates, ...searchForValuesTemplates}; | |
| const cssClasses = { | |
| root: cx(bem(null), userCssClasses.root), | |
| header: cx(bem('header'), userCssClasses.header), | |
| body: cx(bem('body'), userCssClasses.body), | |
| footer: cx(bem('footer'), userCssClasses.footer), | |
| list: cx(bem('list'), userCssClasses.list), | |
| item: cx(bem('item'), userCssClasses.item), | |
| active: cx(bem('item', 'active'), userCssClasses.active), | |
| label: cx(bem('label'), userCssClasses.label), | |
| checkbox: cx(bem('checkbox'), userCssClasses.checkbox), | |
| count: cx(bem('count'), userCssClasses.count), | |
| }; | |
| const specializedRenderer = renderer({ | |
| containerNode, | |
| cssClasses, | |
| transformData, | |
| templates: allTemplates, | |
| renderState: {}, | |
| collapsible, | |
| autoHideContainer, | |
| showMoreConfig, | |
| searchForFacetValues, | |
| }); | |
| try { | |
| const makeWidget = connectRefinementList(specializedRenderer); | |
| return makeWidget({ | |
| attributeName, | |
| operator, | |
| limit, | |
| showMoreLimit, | |
| sortBy, | |
| }); | |
| } catch (e) { | |
| throw new Error(e); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const search = instantsearch({ | |
| appId: 'H3U05083AD', | |
| apiKey: 'fe0fa59fe90d5b76bd19729b71399058', | |
| indexName: 'products', | |
| searchParameters: { | |
| disjunctiveFacetsRefinements: { | |
| 'productType.name': ['Kayak'], | |
| } | |
| }, | |
| searchFunction: (helper) => { | |
| console.log(helper.state); | |
| helper.search(); | |
| } | |
| }); | |
| search.addWidget(instantsearch.widgets.refinementList({ | |
| container: '#rf1', | |
| attributeName: 'manufacturer.title', | |
| templates: { | |
| header: function(data) { | |
| let hdg = `<h5 class="ais-refinement-list--title">${title}</h5>`; | |
| let facetsCount = data.refinedFacetsCount ? `${data.refinedFacetsCount}/${data.facetsCount}` : data.facetsCount; | |
| facetsCount = facetsCount ? `<span class="ais-refinement-list--facetsCount">${facetsCount}</span>` : ''; | |
| return `${hdg}${facetsCount}`; | |
| }, | |
| })); | |
| search.start(); |
Author
Author
refinement-list.jsx is copied straight from
The only change is passing the facetsCount to the header/footer templates: https://gist.github.com/timkelty/7186587110e649b210d3f948e5420b5f#file-refinement-list-jsx-L56
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
refinement-list.jsxis copied straight fromThe only change is passing the
facetsCountto the header/footer templates: https://gist.github.com/timkelty/7186587110e649b210d3f948e5420b5f#file-refinement-list-jsx-L56