Search code examples
clojurescriptreagentreagent-forms

reagent-forms bind-fields ignores ':field', missing dependencies or incorrect usage?


I am not able to get reagent-forms to bind to an atom. I have data binding working in reagent elsewhere in the same file. And I can set and display the atom in question as expected.

I have

  • form-doc that returns a [:div] vector with inputs I'd like bound
  • form-test that creates an atom and calls bind-forms
  • secretary route defined for /#/test

It seems like the :field key within the form-doc return value is ignored or not parsed by bind-fields.

In the test example below, the date picker is never displayed and the inputs look no different than [:input ] would.

Am I using reagent-forms incorrect? Missing a js dependency?


Browser rendered HTML of localhost.localdomain:3000/#/test

  <div data-reactid=".5.0.0">
    <input id="foobar" data-reactid=".5.0.0.0">
    <input id="test" data-reactid=".5.0.0.1">
    <input id="nofieldtest" data-reactid=".5.0.0.2">
    <div id="picker" data-reactid=".5.0.0.3"></div>
  </div>

in core.cljs

(ns ...
   ( :require
      ...
      [reagent.core :as reagent :refer [atom]]
      [reagent.session :as session]
      [secretary.core :as secretary :include-macros true]
      [reagent-forms.core :as rf ]
      [json-html.core :refer [edn->hiccup]]

))

(defn form-doc []
  [:div
   [:input {:field :text :id :foobar}]
   [:input {:field :text :id :test}]
   [:div   {:field :datepicker
            :id :picker
            :date-format "yyyy/mm/dd"
            :inline true}]
  ]
)
(defn form-test []
  (let [doc (atom {:test "test"} ) ]
    (fn []
      [:div.new-visit-form
        [rf/bind-fields form-doc doc ]
        [:div (edn->hiccup @doc) ]
 ]))
)
(secretary/defroute "/test" []
  (session/put! :current-page #'form-test))

in ring/compojure handler I have

 (include-js  "//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js")
 (include-js  "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js")
 (include-css "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css")
 (include-css "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css")
 [:style (-> "reagent-forms.css" clojure.java.io/resource slurp) ]

as far as I can tell, all the necessary js and css is loaded by the browser

in project.clj's :dependencies

 [reagent       "0.5.1"]
 [reagent-utils "0.1.5"]
 [reagent-forms "0.5.13"]

Solution

  • The problem is that you have defined form-doc as a function when it should just be a def. This is an easy mistake to make. Have a look at the examples on the reagent-forms github page again and you will see how to do this.

    I'm not sure your definition for a datepicker component is quite right either. I've not used the reagent-forms datepicker, but it doesn't look quite right, so perhapse look at the demo examples of that as well.

    something you might find useful would be to start by using one of the existing template frameworks. this will allow you to focus on what you want to learn/experiment with rather than getting caught up on all the incidental bits. My recommendation would be to look at luminus. You can setup a basic template with

    lein new luminus +cljs
    

    This will take care of setting up a basic ring/compojure backend, a clojurescript, reagent, reagent-forms and secretary scaffolding for the front end and some other useful bits, such as logging and figwheel, which can make the learning process a little easier. Once you have done that, you can run

    lein run
    

    to start the web server and your application and then

    lein figwheel
    

    to compile your coljurescript and start a figwheel repl. This is really useful as figwheel provides a wonderful envirionment for developing clojurescript. Once you have done that, just go to

    http://localhost:3000
    

    to see your app. There is also some good documentation on the luminus site.