UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

224 lines (196 loc) • 7.84 kB
import FacetSliderModuleDefinition = require('../FacetSlider/FacetSlider'); import FacetModuleDefinition = require('./Facet'); import { IFacetSettingsKlass, FacetSettings } from './FacetSettings'; import { IFacetSortKlass, FacetSort } from './FacetSort'; import { $$ } from '../../utils/Dom'; import { l } from '../../strings/Strings'; import { IAnalyticsFacetOperatorMeta, IAnalyticsFacetMeta, analyticsActionCauseList } from '../Analytics/AnalyticsActionListMeta'; import 'styling/_FacetHeader'; import { SVGIcons } from '../../utils/SVGIcons'; import { SVGDom } from '../../utils/SVGDom'; import { AccessibleButton } from '../../utils/AccessibleButton'; export interface IFacetHeaderOptions { facetElement: HTMLElement; facet?: FacetModuleDefinition.Facet; title: string; field: string; enableClearElement: boolean; enableCollapseElement: boolean; icon?: string; facetSlider?: FacetSliderModuleDefinition.FacetSlider; settingsKlass?: IFacetSettingsKlass; sortKlass?: IFacetSortKlass; availableSorts?: string[]; } export class FacetHeader { public element: HTMLElement; public iconElement: HTMLElement; public waitElement: HTMLElement; public collapseElement: HTMLElement; public expandElement: HTMLElement; public operatorElement: HTMLElement; public eraserElement: HTMLElement; public settings: FacetSettings; public sort: FacetSort; constructor(public options: IFacetHeaderOptions) { this.element = document.createElement('div'); $$(this.element).addClass('coveo-facet-header'); } public build(): HTMLElement { let titleSection = $$('div', { className: 'coveo-facet-header-title-section' }); if (this.options.icon != undefined) { this.iconElement = this.buildIcon(); titleSection.append(this.iconElement); } titleSection.append(this.buildTitle()); this.waitElement = this.buildWaitAnimation(); titleSection.append(this.waitElement); this.element.appendChild(titleSection.el); let settingsSection = $$('div', { className: 'coveo-facet-header-settings-section' }); this.eraserElement = this.buildEraser(); settingsSection.append(this.eraserElement); if (this.options.facet) { this.operatorElement = this.buildOperatorToggle(); settingsSection.append(this.operatorElement); $$(this.operatorElement).toggle(this.options.facet.options.enableTogglingOperator); } if (this.options.settingsKlass) { this.sort = this.settings = new this.options.settingsKlass(this.options.availableSorts, this.options.facet); settingsSection.append(this.settings.build()); } else if (this.options.sortKlass) { this.sort = new this.options.sortKlass(this.options.availableSorts, this.options.facet); } this.element.appendChild(settingsSection.el); return this.element; } public switchToAnd(): void { if (this.options.facet) { this.options.facet.options.useAnd = true; this.rebuildOperatorToggle(); this.updateOperatorQueryStateModel(); } } public switchToOr(): void { if (this.options.facet) { this.options.facet.options.useAnd = false; this.rebuildOperatorToggle(); this.updateOperatorQueryStateModel(); } } public collapseFacet(): void { if (this.collapseElement && this.expandElement) { $$(this.collapseElement).hide(); $$(this.expandElement).show(); } $$(this.options.facetElement).addClass('coveo-facet-collapsed'); } public expandFacet(): void { if (this.collapseElement && this.expandElement) { $$(this.expandElement).hide(); $$(this.collapseElement).show(); } $$(this.options.facetElement).removeClass('coveo-facet-collapsed'); } public updateOperatorQueryStateModel(): void { if (this.options.facet && this.options.facet.options.enableTogglingOperator) { let valueToSet = ''; if (this.options.facet.getSelectedValues().length != 0 || this.options.facet.getExcludedValues().length != 0) { valueToSet = this.options.facet.options.useAnd ? 'and' : 'or'; } this.options.facet.queryStateModel.set(this.options.facet.operatorAttributeId, valueToSet); } } private rebuildOperatorToggle(): void { const newElement = this.buildOperatorToggle(); if (this.operatorElement) { $$(this.operatorElement).replaceWith(newElement); } this.operatorElement = newElement; } private buildIcon(): HTMLElement { let cssClassForIcon; if (this.options.icon) { cssClassForIcon = 'coveo-icon-custom ' + this.options.icon; } else { cssClassForIcon = 'coveo-icon ' + this.options.field.substr(1); } this.iconElement = document.createElement('div'); $$(this.iconElement).addClass(cssClassForIcon); return this.iconElement; } private buildWaitAnimation(): HTMLElement { this.waitElement = $$('div', { className: 'coveo-facet-header-wait-animation' }, SVGIcons.icons.loading).el; SVGDom.addClassToSVGInContainer(this.waitElement, 'coveo-facet-header-wait-animation-svg'); this.waitElement.style.visibility = 'hidden'; return this.waitElement; } private buildOperatorToggle(): HTMLElement { const label = l('SwitchTo', this.options.facet.options.useAnd ? l('Or') : l('And')); const icon = $$('span', { className: 'coveo-' + (this.options.facet.options.useAnd ? 'and' : 'or') }, SVGIcons.icons.orAnd); SVGDom.addClassToSVGInContainer(icon.el, 'coveo-or-and-svg'); const toggle = $$('div', { className: 'coveo-facet-header-operator', title: label }); toggle.append(icon.el); new AccessibleButton() .withElement(toggle) .withLabel(label) .withSelectAction(() => this.handleOperatorClick()) .build(); return toggle.el; } private handleOperatorClick(): void { if (this.options.facet.options.useAnd) { this.options.facet.switchToOr(); } else { this.options.facet.switchToAnd(); } if (this.options.facet.getSelectedValues().length != 0) { const operatorNow = this.options.facet.options.useAnd ? 'AND' : 'OR'; const operatorBefore = this.options.facet.options.useAnd ? 'OR' : 'AND'; this.options.facet.triggerNewQuery(() => this.options.facet.usageAnalytics.logSearchEvent<IAnalyticsFacetOperatorMeta>(analyticsActionCauseList.facetToggle, { facetId: this.options.facet.options.id, facetField: this.options.field.toString(), facetOperatorBefore: operatorBefore, facetOperatorAfter: operatorNow, facetTitle: this.options.title }) ); } } private buildTitle(): HTMLElement { const title = $$('div', { className: 'coveo-facet-header-title' }); title.text(this.options.title); title.setAttribute('role', 'heading'); title.setAttribute('aria-level', '2'); title.setAttribute('aria-label', `${l('FacetTitle', this.options.title)}.`); return title.el; } public buildEraser(): HTMLElement { const eraser = $$('div', { className: 'coveo-facet-header-eraser' }, SVGIcons.icons.mainClear); SVGDom.addClassToSVGInContainer(eraser.el, 'coveo-facet-header-eraser-svg'); new AccessibleButton() .withElement(eraser.el) .withLabel(l('Clear', this.options.title)) .withClickAction(() => this.onEraserClick()) .withEnterKeyboardAction(() => this.onEraserClick()) .build(); return eraser.el; } private onEraserClick() { const cmp = this.options.facet || this.options.facetSlider; cmp.reset(); cmp.usageAnalytics.logSearchEvent<IAnalyticsFacetMeta>(analyticsActionCauseList.facetClearAll, { facetId: cmp.options.id, facetField: cmp.options.field.toString(), facetTitle: cmp.options.title }); cmp.queryController.executeQuery(); } }