18

I'm trying to set the initial focus on an input element

(defn initial-focus-wrapper [element]
  (with-meta element
    {:component-did-mount #(.focus (reagent/dom-node %))}))

(defn chat-input []
  (fn []
    [initial-focus-wrapper
      [:input {:type "text"}]]))

This doesn't work for me though. What am I doing wrong?

Brendanator
  • 833
  • 1
  • 8
  • 15
  • 1
    Not a direct answer, but if you provide the `autoFocus` prop with the value `true`, that should work. – Brigand Dec 23 '14 at 12:28

3 Answers3

14

As sbensu says with-meta only seems to work in reagent on a function. This means it can be used with identity to produce a reusable wrapper as hoped

(def initial-focus-wrapper 
  (with-meta identity
    {:component-did-mount #(.focus (reagent/dom-node %))}))

(defn chat-input []
  (fn []
    [initial-focus-wrapper
      [:input {:type "text"}]]))
Brendanator
  • 833
  • 1
  • 8
  • 15
  • For those struggling you need to use (reagent/as-element [chat-input]) to render it properly. – Vans S Oct 11 '16 at 23:04
5

I think with-meta should take a function as an argument. From the docs:

(def my-html (atom ""))

(defn plain-component []
  [:p "My html is " @my-html])

(def component-with-callback
  (with-meta plain-component
    {:component-did-mount
     (fn [this]
       (reset! my-html (.-innerHTML (reagent/dom-node this))))}))

So your code should be:

(defn initial-focus-wrapper [element]
  (with-meta element
    {:component-did-mount #(.focus (reagent/dom-node %))}))

(defn chat-input []
  [initial-focus-wrapper
    (fn []
      [:input {:type "text"}]]))
sbensu
  • 1,491
  • 10
  • 9
  • You're right. Reagent only seems to work when with-meta is applied to a function. Unfortunately it doesn't seem to work with an anonymous function either – Brendanator Dec 24 '14 at 12:18
1

Another way to set the focus on a given component is to use the ":auto-focus true" attribute:

(defn chat-input []
  [:input {:type "text" :auto-focus true}]])
Rozar Fabien
  • 352
  • 2
  • 9