@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
160 lines (116 loc) • 3.33 kB
JavaScript
import { passThrough } from "../../core/function/passThrough.js";
import { UUID } from "../../engine/ecs/guid/UUID.js";
import View from '../View.js';
/**
* @template T
*/
class DropDownSelectionView extends View {
/**
* @template T
* @param {List<T>} model
* @param {function(T):string} [transform]
* @param {function(T)} [changeListener]
*/
constructor(model, { transform, changeListener } = {}) {
super();
this.model = model;
const elRoot = this.el = document.createElement('select');
elRoot.classList.add('ui-drop-dow-selection-view');
if (transform === undefined) {
this.transfrom = passThrough;
} else {
this.transfrom = transform;
}
this.bindSignal(this.model.on.added, this.handleAdded, this);
this.bindSignal(this.model.on.removed, this.handleRemoved, this);
if (changeListener !== undefined) {
elRoot.addEventListener('change', (event) => {
const id = event.target.value;
const v = this.getValueById(id);
changeListener(v);
});
}
/**
* ID mapping
* @private
* @type {Map<T, string>}
*/
this.mapping = new Map();
}
/**
* @private
* @param {String} el
* @param {number} index
*/
handleAdded(el, index) {
const text = this.transfrom(el);
const id = UUID.string();
this.mapping.set(el, id);
const element = document.createElement('option');
element.setAttribute('value', id);
element.innerText = text;
this.el.appendChild(element);
}
/**
* @private
* @param {string} el
*/
handleRemoved(el) {
const $el = this.el;
let children = $el.children;
let length = children.length;
const id = this.mapping.get(el);
for (let i = 0; i < length; i++) {
let child = children[i];
if (child.value === id) {
$el.removeChild(child);
return;
}
}
}
clearOptions() {
const children = this.el.children;
while (children.length > 0) {
let child = children[0];
this.el.removeChild(child);
}
}
/**
*
* @param {string} id
* @return {T}
*/
getValueById(id) {
let result = null;
this.mapping.forEach((_id, el) => {
if (_id === id) {
result = el;
}
});
return result;
}
/**
*
* @return {T}
*/
getSelectedValue() {
const id = this.el.options[this.el.selectedIndex].value;
return this.getValueById(id);
}
/**
*
* @param {T} v
*/
setSelectedValue(v) {
this.el.selectedIndex = this.model.indexOf(v);
}
link() {
this.model.forEach(this.handleAdded, this);
super.link();
}
unlink() {
super.unlink();
this.clearOptions();
}
}
export default DropDownSelectionView;