import { Facets } from "./Facets.js";
import { UiElement } from "../ui/UiElement.js";
import { createElement } from "../utils/utils.js";
import { resolveTemplate } from "../utils/template/resolveTemplate.js";
import "./FacetsUi.css";
export { FacetsUi };
/**
* Handling of defined and selected facets with an additional Ui Element.
* Listen to the "change" event to add it to the SearchRequest
*
* @author rkoppe <roland.koppe@awi.de>
* @author rhess <roland.koppe@awi.de>
* @memberof vef.search
*/
class FacetsUi extends Facets {
facetsElement = null;
selectedElement = null;
facets = {};
options = {
facetTitle:
`<h2>{title}</h2>`,
facetTemplate:
`<li>{label} <span>({value})</span></li>`,
selectTemplate:
`<li>{label} <span>X</span></li>`
};
/**
* options = {
* facetTitle: "<h2>{title}</h2>",
* facetTemplate: "<li>{label} <span>({value})</span></li>",
* selectTemplate: "<li>{label} <span>X</span></li>"
* }
*
* @param {string | HTMLElement} facetsTarget
* @param {string | HTMLElement} selectedTarget
* @param {object} options
*/
constructor(facetsTarget, selectedTarget, options) {
super();
if (options) this.options = Object.assign(this.options, options);
this.initElement_(facetsTarget, selectedTarget);
}
/**
* Init the HTML Ui Element
* @private
*/
initElement_(facetsTarget, selectedTarget) {
this.facetsElement = new UiElement(facetsTarget);
this.facetsElement.getElement().classList.add('facets-ui', 'facets-available');
this.selectedElement = new UiElement(selectedTarget);
this.selectedElement.getElement().classList.add('facets-ui', 'facets-selected');
}
/**
* Defines the given title for the given path.
* This is useful for root facet entries.
*
* @param {string} path
* @param {string} title
*/
defineFacet(path, title) {
this.facets[path] = title;
return this;
}
/**
* Selects a facet for restriction.
*
* @param {string} path
* @param {boolean} triggerEvents default=true
*/
selectFacet(facet, triggerEvents = true) {
if (!super.selectFacet(facet, triggerEvents)) return false;
const html = resolveTemplate(this.options.selectTemplate, facet);
const element = createElement(html);
element.data = facet;
element.setAttribute('path', facet.path);
element.addEventListener("click", () => this.deselectFacet(facet.path));
this.selectedElement.getElement().appendChild(element);
return facet;
}
/**
* Removes the facet identified by path from selected facets.
*
* @param {string | object} path path or facet
* @param {boolean} triggerEvents default=true
*/
deselectFacet(facet, triggerEvents = true) {
facet = super.deselectFacet(facet, triggerEvents);
if (!facet) return false;
const element = this.selectedElement.getElement().querySelector('[path = "' + facet.path + '"]');
element.remove();
return facet;
}
/**
* Sets all available facets.
*
* @param {Object} facets
*/
setAvailableFacets(facets) {
super.setAvailableFacets(facets);
// clear ui element
const container = this.facetsElement.getElement();
container.innerHTML = "";
for (let i = 0; i < facets.length; ++i) {
const facet = facets[i];
if (facet.children && facet.children.length) {
facet.title = this.facets[facet.path];
const html = resolveTemplate(this.options.facetTitle, facet);
const element = createElement(html);
container.appendChild(element);
// facet list container
const ul = createElement('<ul>');
container.appendChild(ul);
for (let j = 0; j < facet.children.length; ++j) {
const child = facet.children[j];
const html = resolveTemplate(this.options.facetTemplate, child);
const element = createElement(html);
element.data = child;
element.setAttribute('path', child.path);
element.addEventListener("click", () => this.selectFacet(child));
ul.appendChild(element);
}
}
}
}
getFacetsElement() {
return this.facetsElement;
}
getSelectedElement() {
return this.selectedElement;
}
}