Skip to main content
Glama

Controtto

by contre95
DynamicSelect.js7.37 kB
/* * Created by David Adams * https://codeshack.io/dynamic-select-images-html-javascript/ * * Released under the MIT license */ class DynamicSelect { constructor(element, options = {}) { let defaults = { placeholder: "Select an option", columns: 1, name: "", width: "", height: "", data: [], onChange: function() { }, }; this.options = Object.assign(defaults, options); this.selectElement = typeof element === "string" ? document.querySelector(element) : element; for (const prop in this.selectElement.dataset) { if (this.options[prop] !== undefined) { this.options[prop] = this.selectElement.dataset[prop]; } } this.name = this.selectElement.getAttribute("name") ? this.selectElement.getAttribute("name") : "dynamic-select-" + Math.floor(Math.random() * 1000000); if (!this.options.data.length) { let options = this.selectElement.querySelectorAll("option"); for (let i = 0; i < options.length; i++) { this.options.data.push({ value: options[i].value, text: options[i].innerHTML, img: options[i].getAttribute("data-img"), selected: options[i].selected, html: options[i].getAttribute("data-html"), imgWidth: options[i].getAttribute("data-img-width"), imgHeight: options[i].getAttribute("data-img-height"), }); } } this.element = this._template(); this.selectElement.replaceWith(this.element); this._updateSelected(); this._eventHandlers(); } _template() { let optionsHTML = ""; for (let i = 0; i < this.data.length; i++) { let optionWidth = 100 / this.columns; let optionContent = ""; if (this.data[i].html) { optionContent = this.data[i].html; } else { optionContent = ` ${this.data[i].img ? `<img src="${this.data[i].img}" alt="${this.data[i].text}" class="${this.data[i].imgWidth && this.data[i].imgHeight ? "dynamic-size" : ""}" style="${this.data[i].imgWidth ? "width:" + this.data[i].imgWidth + ";" : ""}${this.data[i].imgHeight ? "height:" + this.data[i].imgHeight + ";" : ""}">` : ""} ${this.data[i].text ? '<span class="dynamic-select-option-text">' + this.data[i].text + "</span>" : ""} `; } optionsHTML += ` <div class="dynamic-select-option${this.data[i].value == this.selectedValue ? " dynamic-select-selected" : ""}${this.data[i].text || this.data[i].html ? "" : " dynamic-select-no-text"}" data-value="${this.data[i].value}" style="width:${optionWidth}%;${this.height ? "height:" + this.height + ";" : ""}"> ${optionContent} </div> `; } let template = ` <div class="dynamic-select ${this.name}"${this.selectElement.id ? ' id="' + this.selectElement.id + '"' : ""} style="${this.width ? "width:" + this.width + ";" : ""}${this.height ? "height:" + this.height + ";" : ""}"> <input type="hidden" name="${this.name}" value="${this.selectedValue}"> <div class="dynamic-select-header" style="${this.width ? "width:" + this.width + ";" : ""}${this.height ? "height:" + this.height + ";" : ""}"><span class="dynamic-select-header-placeholder">${this.placeholder}</span></div> <div class="dynamic-select-options" style="${this.options.dropdownWidth ? "width:" + this.options.dropdownWidth + ";" : ""}${this.options.dropdownHeight ? "height:" + this.options.dropdownHeight + ";" : ""}">${optionsHTML}</div> </div> `; let element = document.createElement("div"); element.innerHTML = template; return element; } _eventHandlers() { this.element .querySelectorAll(".dynamic-select-option") .forEach((option) => { option.onclick = () => { this.element .querySelectorAll(".dynamic-select-selected") .forEach((selected) => selected.classList.remove("dynamic-select-selected"), ); option.classList.add("dynamic-select-selected"); this.element.querySelector(".dynamic-select-header").innerHTML = option.innerHTML; this.element.querySelector("input").value = option.getAttribute("data-value"); this.data.forEach((data) => (data.selected = false)); this.data.filter( (data) => data.value == option.getAttribute("data-value"), )[0].selected = true; this.element .querySelector(".dynamic-select-header") .classList.remove("dynamic-select-header-active"); this.options.onChange( option.getAttribute("data-value"), option.querySelector(".dynamic-select-option-text") ? option.querySelector(".dynamic-select-option-text").innerHTML : "", option, ); }; }); this.element.querySelector(".dynamic-select-header").onclick = () => { this.element .querySelector(".dynamic-select-header") .classList.toggle("dynamic-select-header-active"); }; if ( this.selectElement.id && document.querySelector('label[for="' + this.selectElement.id + '"]') ) { document.querySelector( 'label[for="' + this.selectElement.id + '"]', ).onclick = () => { this.element .querySelector(".dynamic-select-header") .classList.toggle("dynamic-select-header-active"); }; } document.addEventListener("click", (event) => { if ( !event.target.closest("." + this.name) && !event.target.closest('label[for="' + this.selectElement.id + '"]') ) { this.element .querySelector(".dynamic-select-header") .classList.remove("dynamic-select-header-active"); } }); } _updateSelected() { if (this.selectedValue) { this.element.querySelector(".dynamic-select-header").innerHTML = this.element.querySelector(".dynamic-select-selected").innerHTML; } } get selectedValue() { let selected = this.data.filter((option) => option.selected); selected = selected.length ? selected[0].value : ""; return selected; } set data(value) { this.options.data = value; } get data() { return this.options.data; } set selectElement(value) { this.options.selectElement = value; } get selectElement() { return this.options.selectElement; } set element(value) { this.options.element = value; } get element() { return this.options.element; } set placeholder(value) { this.options.placeholder = value; } get placeholder() { return this.options.placeholder; } set columns(value) { this.options.columns = value; } get columns() { return this.options.columns; } set name(value) { this.options.name = value; } get name() { return this.options.name; } set width(value) { this.options.width = value; } get width() { return this.options.width; } set height(value) { this.options.height = value; } get height() { return this.options.height; } } document .querySelectorAll("[data-dynamic-select]") .forEach((select) => new DynamicSelect(select));

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/contre95/controtto'

If you have feedback or need assistance with the MCP directory API, please join our Discord server