aboutsummaryrefslogtreecommitdiff
path: root/static/input_list.js
blob: b15162d6ea8f9cc42845f53182322d0e125df598 (plain)
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
75
76
77
/*
  TODO document 'input-list'.

  ∀ children('.input-list') => 'unit' ∈ classList(child)

  <div class="input-list">
    <div class="unit"><input/></div>
    <div class="unit final"><input/></div>
  </div>

*/


function transferListeners(old_unit, new_unit) {
    for (let [o, n] of zip([old_unit, ...old_unit.querySelectorAll("*")],
                           [new_unit, ...new_unit.querySelectorAll("*")])) {
        for (const key in o.listeners) {
            if (! o.listeners.hasOwnProperty(key)) continue;
            for (let proc of o.listeners[key]) {
                n.addEventListener(key, proc);
            }
        }
    }
}


function advance_final(input_list) {
    let old_unit = input_list.unit;
    let new_unit = old_unit.cloneNode(true);
    new_unit.classList.add('final');
    transferListeners(old_unit, new_unit);
    input_list.appendChild(new_unit);
}



function update_inline_list () {

    /* can target self */
    let unit = this.closest('.unit');

    let lst = this.closest('.input-list');

    if (unit.classList.contains("final")) {
        if (this.value !== '') {
            unit.classList.remove('final');
            advance_final(lst);
        }
    } else {
        /* TODO all significant fields empty, instead of just current */
        if (this.value === '') {
            let sibling = unit.previousElementSibling || unit.nextElementSibling;
            unit.remove();
            if (sibling.tagName !== 'input')
                sibling = sibling.querySelector('input');
            sibling.focus();
        }
    }
}

/* run this from window.onload (or similar) */
function init_input_list() {

    for (let lst of document.getElementsByClassName('input-list')) {

        for (let el of lst.getElementsByTagName('input')) {
            el.addEventListener('input', update_inline_list);
        }

        let oldUnit = lst.querySelector('.final.unit')
        let unit = oldUnit.cloneNode(true);

        transferListeners(oldUnit, unit);

        lst.unit = unit;
    }
}