Any suggestions on how to implement a lookahead field in re-frame? I see that the reagent-forms library has one, but support for re-frame is new and I am having trouble following the existing documentation. For some reason I can’t get the field to render, and since there is so much going on with reagent-forms I’m unsure where my problem lies.
Is there a more straightforward means of implementing this that others have used?
Thanks…
To be honest, I just implement one when I need it in a project. You can do it without re-frame, which I like to do for something this simple:
- Two components, one for the input control, one as a wrapper
- Local state atom for the input control, with the usual
on-change
swap for value
- Local state atom for the typeahead, storing loading status, data and flags for what’s visible
- Typeahead passes a debounced on-change for the input, which the input wraps to facilitate the direct render from its local state. The debounced on-change is created via goog.functions/debounce and triggers the fetch logic for the typeahead
- Result rendering is done in the typeahead, optionally in a third component
You can also pass in fetch configuration and/or render functions to the typeahead, just pass them as props. Makes for a nice re-usable component.
If you’re bent on using re-frame for this, I’d still recommend using an atom for the input control, and some sort of ID for each typeahead instance to track its state via re-frame. I like to use a globally defined goog.ui.IdGenerator and a helper function to get one (think it’s cheaper than (random-uuid)
or sth):
(ns myapp.ui
(:require [goog.ui :as ui]))
(defonce id-gen
(ui/IdGenerator.))
(defn next-id []
(.getNextUniqueId id-gen))
When a typahead is created, it creates an ID for itself and “scopes” respective re-frame events by it. You can use this to keep results for each instance apart, and/or pass in a fixed ID via props to sync/share/persist the typeahead state.
Don’t know if it’ll help much, but this is sort what I’m talking about (although I wrote it in one go and didn’t run anything from it ): https://gist.github.com/madbonkey/baf1417be520b27cf94a1fb14637ecbe
I’d go with react-select or some other React component.
+1 It’s a well tested library. We are using it with Rum as a base select component and building more sophisticated ones on top of it.