Search code examples
clojurescriptreagent-forms

Antizer form submit data handling


I would like to use ant design components in reagent through antizer but I can't figure out how to extract fields values from the form after submitting. I can't find anything in the documentation.

Someone more expert than me has resolved this problem?


Solution

  • If you supply a callback to the ant/validate-fields function, it will receive two arguments: errors and values.

    If the input is valid, errors will be null.

    The second argument will always contain the current form data.

    ;; Receive the output of `ant/validate-fields`, and react accordingly
    (defn submit-form-if-valid
      [errors values]
      (if (nil? errors)
        (println "Form is valid."     values)
        (println "Validation failed." errors)))
    
    (defn sample-form
      (fn [props]
        (let [my-form         (ant/create-form)
              submit-handler #(ant/validate-fields my-form submit-form-if-valid)]
          [:div
           [ant/form {:on-submit #(do
                                    (.preventDefault %)
                                    (submit-handler))}
             [ant/form-item ...]
             [ant/form-item ...]
             [ant/form-item ...]
             [ant/form-item
               [ant/button {:type "primary"
                            :html-type "submit"}
                "Submit"]]]])))
    

    Note: Personally, I only use this function to check for errors. My form data is continually recorded in the app-db every time the user changes a field. So my submit handler looks more like this:

    (defn submit-form-if-valid
      [errors _]
      (when (nil? errors)
        (dispatch [:sample-form/submit!])))
    

    My re-frame events look something like this. One event to update the form data in DB (using the key/value pair provided by a form input), and another to actually submit the form:

    (reg-event-db
     :sample-form/update-value
     [(path db/path)]
     (fn [db [_ k v]]
       (assoc-in db [:sample-form-data k] v)))
    
    (reg-event-fx
     :sample-form/submit!
     [(path db/path)]
     (fn [{:keys [db]} _]
       (let [form-data (:sample-form-data db)])
         ;; ... send data to back-end, handle the response, etc.
      ))
    

    And each of my form inputs invoke that event like this:

    [ant/form-item 
      (ant/decorate-field my-form "Thing #1" {:rules [{:required true}]}
        [ant/input {:on-change #(dispatch [:sample-form/update-value :thing1 (-> % .-target .-value)])}])]
    

    Hope this helps!