define(["jquery", "backbone", "semantic", "models/accordion/AccordionItem"], (
$,
Backbone,
Semantic,
AccordionItem,
) => {
// Base class for the view
const BASE_CLASS = "accordion-item";
/**
* @class AccordionItemView
* @classdesc A view representing an accordion item with a title and content
* @classcategory Views/Accordion
* @augments Backbone.View
* @class
* @since 2.31.0
* @screenshot views/accordion/AccordionItemViewView.png
*/
const AccordionItemView = Backbone.View.extend(
/** @lends AccordionItemView.prototype */
{
/** @inheritdoc */
type: "AccordionItemView",
/** @inheritdoc */
className: BASE_CLASS,
/** @inheritdoc */
tagName: "div",
/**
* An HTML string to use for an icon indicating that the accordion item is
* collapsible.
* @type {string}
*/
dropdownIconTemplate: `<i class="${Semantic.CLASS_NAMES.accordion.icon}"></i>`,
/** @inheritdoc */
initialize(options) {
this.model = options?.model || new AccordionItem();
},
/* Hide the dropdown icon */
hideIcon() {
this.iconEl.style.display = "none";
},
/* Show the dropdown icon */
showIcon() {
this.iconEl.style.display = "inline-block";
},
/** @inheritdoc */
render() {
// Icon
const iconContainer = document.createElement("div");
iconContainer.innerHTML = this.dropdownIconTemplate;
const iconEl = iconContainer.firstChild;
this.iconEl = iconEl;
// Title
const titleSpan = document.createElement("span");
titleSpan.innerHTML = this.model.get("title");
const titleContainer = document.createElement("div");
titleContainer.classList.add(Semantic.CLASS_NAMES.accordion.title);
titleContainer.appendChild(iconEl);
titleContainer.appendChild(titleSpan);
this.titleContainer = titleContainer;
// Content
const contentContainer = document.createElement("div");
contentContainer.classList.add(Semantic.CLASS_NAMES.accordion.content);
this.contentContainer = contentContainer;
// Put it all together
this.el.appendChild(titleContainer);
this.el.appendChild(contentContainer);
this.updateContent(this.model.get("content"));
return this;
},
/**
* Change the content of the accordion item.
* @param {string|HTMLElement|Backbone.View} content - The content to
* display.
* @param {boolean} [clear] - Whether to clear the existing content.
*/
updateContent(content, clear = true) {
const { contentContainer } = this;
if (!contentContainer) return;
if (clear) {
contentContainer.innerHTML = "";
this.hideIcon();
contentContainer.style.padding = "0";
}
if (!content) return;
if (typeof content === "string") {
contentContainer.innerHTML = content;
} else if (content instanceof HTMLElement) {
contentContainer.appendChild(content);
} else if (content instanceof Backbone.View) {
contentContainer.appendChild(content.render().el);
}
this.showIcon();
contentContainer.style.padding = "";
},
/*
* Remove the view, DOM elements, and its associated popups.
*/
remove() {
$(this.titleContainer).popup("destroy");
this.titleContainer.remove();
this.contentContainer.remove();
Backbone.View.prototype.remove.call(this);
},
},
);
return AccordionItemView;
});