UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

204 lines (163 loc) 5.97 kB
import 'styling/DynamicFacet/_DynamicFacetValues'; import { $$ } from '../../../utils/Dom'; import { findWhere, find, escape } from 'underscore'; import { DynamicFacetValue } from './DynamicFacetValue'; import { IFacetResponse } from '../../../rest/Facet/FacetResponse'; import { FacetValueState } from '../../../rest/Facet/FacetValueState'; import { l } from '../../../strings/Strings'; import { IDynamicFacet, IValueCreator, IDynamicFacetValue, IDynamicFacetValues } from '../IDynamicFacet'; import { DynamicFacetValueShowMoreLessButton } from './DynamicFacetValueMoreLessButton'; import { Utils } from '../../../utils/Utils'; import { getDynamicFacetHeaderId } from '../DynamicFacetHeader/DynamicFacetHeader'; export interface IDynamicFacetValueCreatorKlass { new (facet: IDynamicFacet): IValueCreator; } export class DynamicFacetValues implements IDynamicFacetValues { private facetValues: IDynamicFacetValue[]; private list = $$('ul', { className: 'coveo-dynamic-facet-values', 'aria-labelledby': getDynamicFacetHeaderId(this.facet.options.id), role: 'group' }).el; private valueCreator: IValueCreator; constructor(private facet: IDynamicFacet, creatorKlass: IDynamicFacetValueCreatorKlass) { this.valueCreator = new creatorKlass(this.facet); this.resetValues(); } public createFromResponse(response: IFacetResponse) { this.facetValues = response.values.map((facetValue, index) => this.valueCreator.createFromResponse(facetValue, index)); } public reorderValues(order: string[]) { this.facetValues = Utils.reorderValuesByKeys(this.facetValues, order, value => value.value); } public resetValues() { this.facetValues = this.valueCreator.getDefaultValues(); } public get allFacetValues() { return this.facetValues; } public get allValues() { return this.facetValues.map(facetValue => facetValue.value); } public get selectedValues() { return this.facetValues.filter(value => value.isSelected).map(({ value }) => value); } private get selectedDisplayValues() { return this.facetValues.filter(value => value.isSelected).map(({ displayValue }) => displayValue); } public get activeValues() { return this.facetValues.filter(value => !value.isIdle); } private get displayedValues() { return this.facetValues.filter(value => !value.isIdle || value.numberOfResults > 0); } public get hasSelectedValues() { return !!findWhere(this.facetValues, { state: FacetValueState.selected }); } public get hasActiveValues() { return !!this.activeValues.length; } public get hasIdleValues() { return !!findWhere(this.facetValues, { state: FacetValueState.idle }); } public clearAll() { this.facetValues.forEach(value => value.deselect()); } public get hasValues() { return !!this.allFacetValues.length; } public get hasDisplayedValues() { return !!this.displayedValues.length; } public hasSelectedValue(arg: string | DynamicFacetValue) { const value = typeof arg === 'string' ? arg : arg.value; const foundValue = find(this.facetValues, facetValue => facetValue.equals(value)); return foundValue && foundValue.isSelected; } public get(arg: string | DynamicFacetValue) { const value = typeof arg === 'string' ? arg : arg.value; const facetValue = find(this.facetValues, facetValue => facetValue.equals(value)); if (facetValue) { return facetValue; } const newFacetValue = this.valueCreator.createFromValue(value); if (!newFacetValue) { return null; } this.facetValues.push(newFacetValue); return newFacetValue; } public focus(value: string) { const facetValue = find(this.facetValues, facetValue => facetValue.equals(value)); if (!facetValue) { return; } facetValue.focus(); } private buildShowLess() { const showLess = new DynamicFacetValueShowMoreLessButton({ className: 'coveo-dynamic-facet-show-less', ariaLabel: l('ShowLessFacetResults', this.facet.options.title), label: l('ShowLess'), action: () => { this.facet.enableFreezeFacetOrderFlag(); this.facet.showLessValues(); } }); return showLess.element; } private buildShowMore() { const showMore = new DynamicFacetValueShowMoreLessButton({ className: 'coveo-dynamic-facet-show-more', ariaLabel: l('ShowMoreFacetResults', this.facet.options.title), label: l('ShowMore'), action: () => { this.facet.enableFreezeFacetOrderFlag(); this.facet.showMoreValues(); } }); return showMore.element; } private get shouldEnableShowLess() { const hasMoreValuesThenDefault = this.facetValues.length > this.facet.options.numberOfValues; return hasMoreValuesThenDefault && this.hasIdleValues; } private appendShowMoreLess(fragment: DocumentFragment) { if (!this.facet.options.enableMoreLess) { return; } if (this.shouldEnableShowLess) { fragment.appendChild(this.buildShowLess()); } if (this.facet.moreValuesAvailable) { fragment.appendChild(this.buildShowMore()); } } private appendSelectedCollapsedValues(fragment: DocumentFragment) { if (!this.hasSelectedValues) { return; } const selectedValues = this.selectedDisplayValues.join(', '); fragment.appendChild( $$( 'li', { className: 'coveo-dynamic-facet-collapsed-values', ariaLabel: `${l('CurrentSelections')}: ${selectedValues}` }, escape(selectedValues) ).el ); } public render() { const fragment = document.createDocumentFragment(); $$(this.list).empty(); this.displayedValues.forEach(facetValue => { fragment.appendChild(facetValue.renderedElement); }); this.appendShowMoreLess(fragment); this.appendSelectedCollapsedValues(fragment); this.list.appendChild(fragment); return this.list; } }