coveo-search-ui
Version:
Coveo JavaScript Search Framework
130 lines (113 loc) • 3.98 kB
text/typescript
import * as Globalize from 'globalize';
import { first, rest, filter } from 'underscore';
import { Assert } from '../../misc/Assert';
import { l } from '../../strings/Strings';
import { $$ } from '../../utils/Dom';
import { IBreadcrumbValueElementKlass } from './BreadcrumbValueElement';
import { Facet } from './Facet';
import { FacetValue } from './FacetValue';
import { AccessibleButton } from '../../utils/AccessibleButton';
import { getHeadingTag } from '../../utils/AccessibilityUtils';
export interface IBreadcrumbValueListOptions {
headingLevel?: number;
}
export class BreadcrumbValueList {
private expanded: FacetValue[];
private collapsed: FacetValue[];
protected elem: HTMLElement;
private valueContainer: HTMLElement;
constructor(
public facet: Facet,
public facetValues: FacetValue[],
public breadcrumbValueElementKlass: IBreadcrumbValueElementKlass,
private readonly options?: IBreadcrumbValueListOptions
) {
this.setExpandedAndCollapsed();
this.elem = $$('div', {
className: 'coveo-facet-breadcrumb'
}).el;
const title = $$(getHeadingTag(this.options && this.options.headingLevel, 'span'));
title.addClass('coveo-facet-breadcrumb-title');
title.text(this.facet.options.title + ':');
this.elem.appendChild(title.el);
this.valueContainer = $$('ul', {
className: 'coveo-facet-breadcrumb-values'
}).el;
this.elem.appendChild(this.valueContainer);
}
public build(): HTMLElement {
this.buildExpanded();
if (this.collapsed.length != 0) {
this.buildCollapsed();
}
return this.elem;
}
public buildAsString(): string {
this.build();
if (this.elem) {
return (
`${this.facet.options.title}: ` +
$$(this.elem)
.findAll('.coveo-facet-breadcrumb-value')
.map((value: HTMLElement) => {
return $$(value).text();
})
.join(', ')
);
}
return '';
}
private buildExpanded() {
this.expanded.forEach((value: FacetValue) => {
const elementBreadcrumb = new this.breadcrumbValueElementKlass(this.facet, value).build();
this.valueContainer.appendChild(elementBreadcrumb.el);
});
}
private buildCollapsed() {
const numberOfSelected = filter(this.collapsed, (value: FacetValue) => value.selected).length;
const numberOfExcluded = filter(this.collapsed, (value: FacetValue) => value.excluded).length;
Assert.check(numberOfSelected + numberOfExcluded == this.collapsed.length);
const nMoreElement = $$(
'div',
{
className: 'coveo-facet-breadcrumb-value'
},
$$(
'span',
{
className: 'coveo-facet-breadcrumb-multi-count'
},
l('NMore', Globalize.format(numberOfSelected + numberOfExcluded, 'n0'))
)
);
const nMoreContainer = $$(
'li',
{
className: 'coveo-facet-breadcrumb-value-list-item'
},
nMoreElement
);
const collapsedBreadcrumbs = this.collapsed.map((value: FacetValue) => new this.breadcrumbValueElementKlass(this.facet, value));
const toolTip = collapsedBreadcrumbs.map(element => element.getBreadcrumbTooltip()).join('\n');
new AccessibleButton()
.withElement(nMoreElement)
.withTitle(toolTip)
.withSelectAction(() => {
nMoreElement.remove();
collapsedBreadcrumbs.forEach(breadcrumb => {
this.valueContainer.appendChild(breadcrumb.build().el);
});
})
.build();
this.valueContainer.appendChild(nMoreContainer.el);
}
private setExpandedAndCollapsed() {
if (this.facetValues.length > this.facet.options.numberOfValuesInBreadcrumb) {
this.collapsed = rest(this.facetValues, this.facet.options.numberOfValuesInBreadcrumb);
this.expanded = first(this.facetValues, this.facet.options.numberOfValuesInBreadcrumb);
} else {
this.collapsed = [];
this.expanded = this.facetValues;
}
}
}