Skip to content

Commit

Permalink
feat: SignalInputController now works as expected on radio button gro…
Browse files Browse the repository at this point in the history
…ups. Add some extra functionality to ensure that values sync up when the SignalInputController connects before the SignalVisibilityControllers. Add a configurable debounceIntervalValue to SignalInputController
  • Loading branch information
Sub-Xaero committed Nov 23, 2021
1 parent 1052ae5 commit 018d5a8
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 15 deletions.
12 changes: 12 additions & 0 deletions src/controllers/signal/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function signalEventName(name: string, type: string) :string {
return `signal:${type}:${name}`;
}

export function signalConnectEvent(name: string): string {
return signalEventName(name, 'connect');
}

export function signalValueEvent(name: string): string {
return signalEventName(name, 'value');
}

28 changes: 18 additions & 10 deletions src/controllers/signal/signal_input_controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {BaseController} from "../../utilities/base_controller";
import {EventBus} from "../../utilities/event_bus";
import {useEventListener} from "../../mixins/use_event_listener";
import {isHTMLInputElement} from "../../utilities";
import {getAllRadiosInGroup, isHTMLInputElement} from "../../utilities";
import {signalConnectEvent, signalValueEvent} from "./events";
import {useEventBus} from "../../mixins/use_event_bus";

export interface SignalPayload {
element: HTMLElement;
Expand All @@ -12,20 +14,26 @@ export class SignalInputController extends BaseController {

static values = {
name: String,
debounceInterval: Number,
};

declare debounceIntervalValue: number;
declare readonly hasDebounceIntervalValue: boolean;

get _debounceTimeout(): number | null {
return this.hasDebounceIntervalValue ? this.debounceIntervalValue : null;
}

declare nameValue: string;
declare hasNameValue: boolean;

get _name(): string {
return this.hasNameValue ? this.nameValue : (this.element as HTMLInputElement).name;
}

get _eventName(): string {
return `signal:value:${this._name}`;
}

connect() {
useEventListener(this, this.el, "input", this.emitValue, {debounce: 1000});
useEventBus(this, signalConnectEvent(this._name), () => this.emitValue());
useEventListener(this, this.el, "input", this.emitValue, {debounce: this._debounceTimeout || undefined});
useEventListener(this, this.el, "change", this.emitValue);
requestAnimationFrame(() => this.emitValue());
}
Expand All @@ -35,12 +43,12 @@ export class SignalInputController extends BaseController {

if (isHTMLInputElement(this.el) && this.el.type === "checkbox") {
value = this.el.checked ? "true" : "false";
} else if (isHTMLInputElement(this.el) && this.el.type === "radio") {
let selectedValue = getAllRadiosInGroup(this.el).find(el => el.checked)?.value;
value = selectedValue ? selectedValue : "";
}

EventBus.emit(this._eventName, {
element: this.el,
value,
} as SignalPayload);
EventBus.emit(signalValueEvent(this._name), {element: this.el, value} as SignalPayload);
}

}
9 changes: 4 additions & 5 deletions src/controllers/signal/signal_visibility_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {BaseController} from "../../utilities/base_controller";
import {useEventBus} from "../../mixins/use_event_bus";
import {SignalPayload} from "./signal_input_controller";
import {extractPredicates} from "./expressions";
import {signalConnectEvent, signalValueEvent} from "./events";
import {EventBus} from "../../utilities";

export class SignalVisibilityController extends BaseController {

Expand Down Expand Up @@ -29,12 +31,9 @@ export class SignalVisibilityController extends BaseController {
return ["hide"];
}

get _eventName(): string {
return `signal:value:${this.nameValue}`;
}

connect() {
useEventBus(this, this._eventName, this._onSignal);
EventBus.emit(signalConnectEvent(this.nameValue));
useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
}

_onSignal(payload: SignalPayload) {
Expand Down
5 changes: 5 additions & 0 deletions src/utilities/elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,8 @@ export function insertHiddenInput(name: string, value: string, targetElement: El
export function insertHiddenButton(type: "submit" | "reset", targetElement: Element, insertPosition: InsertPosition): HTMLButtonElement {
return insertElement(targetElement, insertPosition, createHiddenButton(type));
}

export function getAllRadiosInGroup(radio: HTMLInputElement): HTMLInputElement[] {
let parent = radio.form || document;
return Array.from(parent.querySelectorAll(`input[type="radio"][name="${radio.name}"]`));
}

0 comments on commit 018d5a8

Please sign in to comment.