~sirn/fanboi2

ref: 5b482cfc1bfb0bb1e89715cb57c7bac864391768 fanboi2/assets/app/javascripts/components/topic_state_tracker.ts -rw-r--r-- 2.2 KiB
5b482cfcKridsada Thanabulpong 0.30.0 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
68
69
70
71
72
73
74
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);
        });
    }
}