Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
(ns myapp.typeahead
(:require [reagent.core :as r]
[goog.functions :as gf]
[myapp.api :as api]))
(defn input-control [props]
(let [value (r/atom (:default-value props ""))
local-change #(reset! value (.. % -target -value))]
(fn [{:keys [on-change] :as props}]
[:input (assoc props
:value @value
:on-change (comp #(when (fn? on-change) (on-change %))
local-change))])))
(defn create-typeahead-fetch [opts state]
;; or however you want to build your fetch handler
(gf/debounce
(partial api/fetch (:remote opts))
(:debounce-ms opts 150)))
(defn typeahead [opts]
(let [state (r/atom {:open? false
:loading? false
:results nil
:error nil})
fetch (create-typeahead-fetch state opts)
toggle #(swap! state update :open? not)]
(fn [opts]
[:div
(if (:open? @state)
[input-control
{:default-value (:default-value opts "")
:on-change fetch}]
[button
{:on-click toggle}
"Show search"])
(if (:loading? @state)
[:div "Loading"]
[:div (str (count (:results @state)) " results")])])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment