~sirn/fanboi2

ref: a68873a108d20a6a49a1b6caf374bfb2cf6a94fe fanboi2/assets/app/javascripts/components/topic_state_tracker.ts -rw-r--r-- 2.2 KiB
a68873a1Kridsada Thanabulpong Coding style cleanups and setup pre-commit hooks (#42) 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { CollectionComponent } from "./base";
import { dispatchCustomEvent } from "../utils/elements";

export class TopicStateTracker extends CollectionComponent {
    public targetSelector = "[data-topic-state-tracker]";

    protected bindOne($target: Element): void {
        let trackerName = $target.getAttribute("data-topic-state-tracker");

        if (!trackerName) {
            throw new Error("State tracker name is empty when it should not.");
        }

        if ($target instanceof HTMLInputElement) {
            switch ($target.type) {
                case "checkbox":
                    this.bindCheckbox(trackerName, $target);
                    break;
            }
        } else if ($target instanceof HTMLTextAreaElement) {
            this.bindTextarea(trackerName, $target);
        }
    }

    private bindCheckbox(trackerName: string, $target: HTMLInputElement): void {
        dispatchCustomEvent($target, "readState", {
            name: trackerName,
            callback: (name: string, value?: boolean) => {
                if (value != undefined) {
                    $target.checked = value;
                    $target.defaultChecked = $target.checked;
                }
            },
        });

        $target.addEventListener("change", (e: Event): void => {
            $target.defaultChecked = $target.checked;
            dispatchCustomEvent($target, "updateState", {
                name: trackerName,
                value: $target.checked,
            });
        });
    }

    private bindTextarea(trackerName: string, $target: HTMLTextAreaElement): void {
        let throttleTimer: number;

        dispatchCustomEvent($target, "readState", {
            name: trackerName,
            callback: (name: string, value?: string) => {
                if (value != undefined) {
                    $target.value = value;
                }
            },
        });

        $target.addEventListener("change", (e: Event): void => {
            clearTimeout(throttleTimer);
            throttleTimer = setTimeout(() => {
                dispatchCustomEvent($target, "updateState", {
                    name: trackerName,
                    value: $target.value,
                });
            }, 500);
        });
    }
}