Skip to content

Instantly share code, notes, and snippets.

@Deraen
Last active May 1, 2018 17:37
Show Gist options
  • Save Deraen/8fbc90721c801e487332 to your computer and use it in GitHub Desktop.
Save Deraen/8fbc90721c801e487332 to your computer and use it in GitHub Desktop.
(ns foobar.search
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.core.async :refer [<! chan put!] :as a]
[reagent.core :as reagent]
[reagent.ratom :refer [atom]]))
; Source: https://gist.github.com/Deraen/946ac9e6c6211c83f1e9
(defn debounce [in ms]
"Creates a channel which will change put a new value to the output channel
after timeout has passed. Each value change resets the timeout. If value
changes more frequently only the latest value is put out.
When input channel closes, the output channel is closed."
(let [out (a/chan)]
(a/go-loop [last-val nil]
(let [val (if (nil? last-val) (a/<! in) last-val)
timer (a/timeout ms)]
(a/alt!
in ([v] (if v
(recur v)
(a/close! out)))
timer ([_] (do (a/>! out val) (recur nil))))))
out))
(defn search-field [& {:keys [class]}]
(let [value (atom "")
search (chan)
search-delayed (debounce search 500)
search! (fn [x] (if (seq x) (r/update-uri! :search {:q x})))]
(go
(loop []
(let [x (<! search-delayed)]
(when x
(search! x)
(recur)))))
(reagent/create-class
{:component-will-unmount
(fn [] (async/close! search))
:reagent-render
(fn []
[:input.form-control
{:type "text"
:placeholder "Search"
:class (str class)
:ref "input"
:value @value
:on-change #(do
(reset! value (.. % -target -value))
(put! search @value))
:on-key-up #(case (.-key %)
"Enter" (search! @value)
nil)}])})))
@kidpollo
Copy link

kidpollo commented Jul 9, 2015

Thanks for this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment