75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
|
import { ApplicationController } from './application_controller';
|
||
|
|
||
|
export class SelectChampPositionTemplateController extends ApplicationController {
|
||
|
static targets = ['select', 'template'];
|
||
|
static values = {
|
||
|
templateId: String
|
||
|
};
|
||
|
// this element is updated via turbostream as the source of truth for all select
|
||
|
declare readonly templateIdValue: string;
|
||
|
|
||
|
declare readonly selectTargets: HTMLSelectElement[];
|
||
|
|
||
|
selectTargetConnected(selectElement: HTMLSelectElement) {
|
||
|
selectElement.addEventListener('blur', this);
|
||
|
selectElement.addEventListener('focus', this);
|
||
|
selectElement.addEventListener('change', this);
|
||
|
}
|
||
|
|
||
|
selectTargetDisconnected(selectElement: HTMLSelectElement) {
|
||
|
console.log('selectTargetDisconnected');
|
||
|
selectElement.removeEventListener('blur', this);
|
||
|
selectElement.removeEventListener('focus', this);
|
||
|
selectElement.removeEventListener('change', this);
|
||
|
}
|
||
|
|
||
|
handleEvent(event: Event) {
|
||
|
switch (event.type) {
|
||
|
case 'focus':
|
||
|
this.onFocus(event);
|
||
|
break;
|
||
|
case 'change':
|
||
|
this.onChange(event);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private onFocus(event: Event): void {
|
||
|
const focusedSelect = event.target as HTMLSelectElement;
|
||
|
const focusedSelectStableId = this.getStableIdForSelect(focusedSelect);
|
||
|
const template = this.element.querySelector<HTMLElement>(
|
||
|
`#${this.templateIdValue}`
|
||
|
);
|
||
|
|
||
|
if (template) {
|
||
|
const fragment = template.cloneNode(true) as HTMLSelectElement;
|
||
|
|
||
|
const options = Array.from(fragment.querySelectorAll('option'))
|
||
|
.map((option) => {
|
||
|
if (option.value == focusedSelectStableId) {
|
||
|
option.setAttribute('selected', 'selected');
|
||
|
}
|
||
|
|
||
|
return option.outerHTML;
|
||
|
})
|
||
|
.join('');
|
||
|
focusedSelect.innerHTML = options;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private onChange(event: Event): void {
|
||
|
const changedSelectTarget = event.target as HTMLSelectElement;
|
||
|
const stableIdDidChange =
|
||
|
changedSelectTarget.value !=
|
||
|
this.getStableIdForSelect(changedSelectTarget);
|
||
|
if (!stableIdDidChange) {
|
||
|
// prevent to bulble up
|
||
|
event.stopImmediatePropagation();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private getStableIdForSelect(select: HTMLSelectElement): string | null {
|
||
|
return select.getAttribute('data-selected');
|
||
|
}
|
||
|
}
|