How can I trigger the onchange event of a controlled input in a Reagent application?
[:input {:on-change (fn [e] ...) :id :my-input}]
Reagent implements React and the input components are Controlled React inputs so as I found out the input eventually doesn't have the on-change function. It has some kind of React property that contains the passed on-change function and the default on-change fn is nil in the input element object.
So therefore this doesn't working:
(let [input (.get-element-by-id js/document "my-input")]
(.onchange input))
The purpose is that I have input fields and I want to make a field value validator that could be called anytime (e.g. clicking on a submit button). So I put the validator in the on-change function and it works well but now I need to call the on-change function if I want validate the fields when Im clicking on the submit button.
I tried this but nothing happened:
(defn input
[]
(letfn [(f [] (let [e (js/Event. "change")
el (.getElementById js/document "my-input")]
(.dispatchEvent el e)))]
[:<> [:input {:id :my-input :on-change (fn [_] (println "Changed"))}]
[:button {:on-click f} "Trigger on-change"]]))
What you are trying to do is a bad idea, since the browser treats events triggered by the user differently than those triggered by code. So, you might find stuff work on the actual :on-change
but not otherwise. Instead, just write a function to do what you want.
(defn stuff-i-want-to-happen [maybe with args] ...)
(defn input []
[:<> [:input {:on-change (fn [_] (println "Changed") (stuff-i-want-to-happen 1 2 3)}]
[:button {:on-click #(stuff-i-want-to-happen 4 5 6)} "Trigger on-change"]])
If you need to track additional state, you can just move that to the appropriate place.