coveo-search-ui
Version:
Coveo JavaScript Search Framework
224 lines (196 loc) • 7.84 kB
text/typescript
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();
}
}