Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for checkbox and radio form elements. #26

Merged
merged 1 commit into from Feb 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 22 additions & 6 deletions src/cljs/free_form/core.cljs
Expand Up @@ -20,16 +20,32 @@
(contains? (second node) :free-form/input)))

(defn- js-event-value [event]
(.-value (.-target event)))
(let [target (.-target event)]
(case (.-type target)
"checkbox" (.-checked target)
(.-value target))))

(defn- extract-event-value [event]
(if (string? event)
event ; React-toolbox generates events that already contain a stracted string of the value as the first paramenter
(js-event-value event))) ; for all other cases, we extract it ourselves.

(defn- bind-input [values on-change node]
(if (not (input? node))
node
(let [[attributes _ keys] (extract-attributes node :free-form/input)]
(assoc node attributes-index (assoc attributes :value (or (get-in values keys) "")
:on-change #(on-change keys (if (string? %1)
%1 ; React-toolbox generates events that already contain a stracted string of the value as the first paramenter
(js-event-value %1)))))))) ; for all other cases, we extract it ourselves.
(let [[attributes _ keys] (extract-attributes node :free-form/input)
on-change-fn #(on-change keys (extract-event-value %1))]

(case (:type attributes)
:checkbox
(assoc node attributes-index (assoc attributes :defaultChecked (= true (get-in values keys))
:on-change on-change-fn))
:radio
(assoc node attributes-index (assoc attributes :defaultChecked (= (:value attributes) (get-in values keys))
:on-change on-change-fn))

(assoc node attributes-index (assoc attributes :value (or (get-in values keys) "")
:on-change on-change-fn))))))

(defn- error-class?
"Tests whether the node should be marked with an error class should the field have an associated error."
Expand Down
116 changes: 115 additions & 1 deletion test/cljs/free_form/core_test.cljs
Expand Up @@ -82,6 +82,42 @@
:id :text-with-extra-validation-errors
:placeholder "This will be marked as a validation error also when Text and General have validation errors."}]
[:div.errors {:free-form/error-message {:key :text-with-extra-validation-errors}} [:p.error]]]

; === Checkboxes
[:div.field {:free-form/error-class {:key :checkbox-true :error "validation-errors"}}
[:label {:for :checkbox-true} "Checkbox (default checked)"]
[:input.form-control {:free-form/input {:key :checkbox-true}
:type :checkbox
:id :checkbox-true}]
[:div.errors {:free-form/error-message {:key :checkbox-false}} [:p.error]]]

[:div.field {:free-form/error-class {:key :checkbox-false :error "validation-errors"}}
[:label {:for :checkbox-false} "Checkbox (default not checked)"]
[:input.form-control {:free-form/input {:key :checkbox-false}
:type :checkbox
:id :checkbox-false}]
[:div.errors {:free-form/error-message {:key :checkbox-false}} [:p.error]]]

; === Radio Buttons
[:div.field {:free-form/error-class {:key :radio :error "validation-errors"}}
[:label {:for :radio-option-1} "Radio Option 1"
[:input.form-control {:free-form/input {:key :radio}
:type :radio
:id :radio-option-1
:value "radio-option-1"}]]
[:label {:for :radio-option-2} "Radio Option 2"
[:input.form-control {:free-form/input {:key :radio}
:type :radio
:id :radio-option-2
:value "radio-option-2"}]]
[:label {:for :radio-option-3} "Radio Option 3"
[:input.form-control {:free-form/input {:key :radio}
:type :radio
:id :radio-option-3
:value "radio-option-3"}]]
[:div.errors {:free-form/error-message {:key :radio}} [:p.error]]]


[:button "Button"]]]

(testing "simple generation"
Expand Down Expand Up @@ -166,6 +202,45 @@
:value ""
:on-change :was-function}]
nil]

[:div.field {}
[:label {:for :checkbox-true} "Checkbox (default checked)"]
[:input.form-control {:type :checkbox
:id :checkbox-true
:defaultChecked false
:on-change :was-function}]
nil]

[:div.field {}
[:label {:for :checkbox-false} "Checkbox (default not checked)"]
[:input.form-control {:type :checkbox
:id :checkbox-false
:defaultChecked false
:on-change :was-function}]
nil]

[:div.field {}
[:label {:for :radio-option-1} "Radio Option 1"
[:input.form-control {:type :radio
:id :radio-option-1
:value "radio-option-1"
:defaultChecked false
:on-change :was-function}]]
[:label {:for :radio-option-2} "Radio Option 2"
[:input.form-control {:type :radio
:id :radio-option-2
:value "radio-option-2"
:defaultChecked false
:on-change :was-function}]]
[:label {:for :radio-option-3} "Radio Option 3"
[:input.form-control {:type :radio
:id :radio-option-3
:value "radio-option-3"
:defaultChecked false
:on-change :was-function}]]
nil]


[:button "Button"]]))))

(testing "generation with initial data"
Expand All @@ -177,6 +252,9 @@
;:select-with-group "two" ; TODO: enable this and fix generation, as it's broken right now.
:textarea "Textarea value"
:t {:e {:x {:t "Text with deep keys value"}}}
:checkbox-true true
:checkbox-false false
:radio "radio-option-2"
} {} (fn [_keys _value])
plain-reagent-form-template))]
(is (= generated-input
Expand Down Expand Up @@ -256,6 +334,42 @@
:value ""
:on-change :was-function}]
nil]
[:button "Button"]]))))))

[:div.field {}
[:label {:for :checkbox-true} "Checkbox (default checked)"]
[:input.form-control {:type :checkbox
:id :checkbox-true
:defaultChecked true
:on-change :was-function}]
nil]

[:div.field {}
[:label {:for :checkbox-false} "Checkbox (default not checked)"]
[:input.form-control {:type :checkbox
:id :checkbox-false
:defaultChecked false
:on-change :was-function}]
nil]

[:div.field {}
[:label {:for :radio-option-1} "Radio Option 1"
[:input.form-control {:type :radio
:id :radio-option-1
:value "radio-option-1"
:defaultChecked false
:on-change :was-function}]]
[:label {:for :radio-option-2} "Radio Option 2"
[:input.form-control {:type :radio
:id :radio-option-2
:value "radio-option-2"
:defaultChecked true
:on-change :was-function}]]
[:label {:for :radio-option-3} "Radio Option 3"
[:input.form-control {:type :radio
:id :radio-option-3
:value "radio-option-3"
:defaultChecked false
:on-change :was-function}]]
nil]

[:button "Button"]]))))))