aboutsummaryrefslogtreecommitdiff
path: root/src/View/Form/Autocomplete.ml
blob: 537316d2b9aa70b61c9ab9c146ee0c4db2f5842a (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
let search s xs =
  if s == "" then
    [| |]
  else
    let results = Js.Array.filter (Js.String.includes s) xs in
    if Js.Array.length results == 1 && results.(0) == s then [| |] else results

let render_completion on_select entries =
  H.div
    [| HA.class_ "g-Autocomplete__Completion" |]
    (entries
      |> Js.Array.map (fun c ->
          H.button
            [| HA.class_ "g-Autocomplete__Entry"
            ;  HA.type_ "button"
            ;  HE.on_click (fun _ -> on_select c)
            |]
            [| H.text c |]))

let create id label values on_input attrs =

  let completion =
    H.div [| |] [| |]
  in

  let update_completion target value =
    let entries = search value values in
    Element.mount_on completion (render_completion
      (fun selected ->
        let () = Element.set_value target selected in
        let () = Element.remove_children completion in
        on_input selected)
      entries)
  in

  H.div
    [| HA.class_ "g-Autocomplete" |]
    [| H.div
        [| HA.class_ "g-Form__Label" |]
        [| H.label
          [| HA.for_ id |]
          [| H.text label |]
        |]
    ; H.input
      (Js.Array.concat
        [| HA.id id
        ; HA.class_ "g-Autocomplete__Input"
        ; HA.autocomplete "off"
        ;  HE.on_click (fun e ->
            let target = Event.target e in
            let value = Element.value target in
            update_completion target value)
        ;  HE.on_input (fun e ->
            let target = Event.target e in
            let value = Element.value target in
            let () = update_completion target value in
            on_input value)
        |]
        attrs)
      [| |]
    ;  completion
    |]