aboutsummaryrefslogtreecommitdiff
path: root/src/View/Form/Autocomplete.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/View/Form/Autocomplete.ml')
-rw-r--r--src/View/Form/Autocomplete.ml62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/View/Form/Autocomplete.ml b/src/View/Form/Autocomplete.ml
new file mode 100644
index 0000000..537316d
--- /dev/null
+++ b/src/View/Form/Autocomplete.ml
@@ -0,0 +1,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
+ |]