Hi all,

I am banging my head against the wall - I think it is obvious but I have 
started too long:

The use-case is that I want a form which takes a set of children. The form 
also takes in some form-wide state, like the form-wide validation, the 
values for each item etc. I want the macro, for each child, to decorate 
that child by extracting the validation errors and value from the form-wide 
state.

So, assuming:
 - validation looks like {:name "Duplicate name" :age "You must be at least 
0"}
 - form-values looks like {:name "a-duplicate-user" :age -1}

then my form might look like:

(form {:editing? true :values form-values :validation validation-report 
:on-change handle-form-change}
  [form/text {:id :name}]
  [form/number {:id :age}])

After the macro I want the following code:

[:div.form.horizontal
  {:class "editing"}
  [form/text {:id :name :value "a-duplicate-user" :errors "Duplicate name" 
:on-click (fn [e] (handle-form-change :name (-> e .target .value])]
  [form/number {:id :age :value "-1" :errors "You must be at least 0" 
:on-click (fn [e] (handle-form-change :age (-> e .target .value))]]

However, ideally the macro would _not_ emit the contents of the input as 
literals but would emit code that inspects the provided parameters at 
run-time (i.e. rather than :value "a-duplicate-user" I would much prefer 
:value (-> state values :name) as that will allow me to pass in an atom for 
example.

I have tried so many variations and evaluating the state (e.g. (:editing? 
state)) works fine as the emitted code has the destructured values, but 
that doesn't work for an atom.

Here is my attempt at trying to emit code that interrogates the provided 
parameter.

(defmacro form [state & elements]
  (let [state# state]
    `[:div.form.horizontal
      {:class (if (:editing? state#) "editing" "editable")}
      ~@(map (fn [[_ {:keys [id]} :as child]]
               (update child 1 assoc
                       :editing? (:editing? state#)
                       :value `(-> (:values state#) 'deref (get ~id))
                       :on-change `(fn [e#]
                                     (js/console.log "E: " 
(cljs.core/clj->js e#))
                                     ((:on-change state#) ~id (-> e# 
.-target .-value)))))
             elements)]))

The error I am getting is that there is such var as the gen-sym's state# in 
the namespace.

The generic thing I am trying to do is remove the boilerplate from each of 
the items in the form.

Any and all suggestions are welcome. 

Thanks!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to