Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

adds form error display

  • Loading branch information...
commit 76c4c3aba0d8cda9c10250222acd619dd9df945d 1 parent a7ae3f7
@slagyr slagyr authored
51 spec/cljs/com/eighthlight/filament/forms_spec.cljs
@@ -14,15 +14,46 @@
(it "collects all the data on a form"
(dom/append! (css/sel "body")
- (h/html [:form#test-form [:input {:type "text" :name "red" :value "red"}]
- [:input {:type "checkbox" :name "orange" :checked true}]
- [:input {:type "checkbox" :name "yellow"}]
- [:input {:type "radio" :name "green" :value "grass"}]
- [:input {:type "radio" :name "green" :value "pea" :checked true}]
- [:select {:name "blue"}
- [:option {:value "sky"}]
- [:option {:value "sea" :selected true}]]
- [:textarea {:name "indigo"} "like blue"]]))
+ (h/html [:form#test-form [:input {:type "text" :name "red" :value "red"}]
+ [:input {:type "checkbox" :name "orange" :checked true}]
+ [:input {:type "checkbox" :name "yellow"}]
+ [:input {:type "radio" :name "green" :value "grass"}]
+ [:input {:type "radio" :name "green" :value "pea" :checked true}]
+ [:select {:name "blue"}
+ [:option {:value "sky"}]
+ [:option {:value "sea" :selected true}]]
+ [:textarea {:name "indigo"} "like blue"]]))
(should= {:red "red", :orange "on", :green "pea", :blue "sea", :indigo "like blue"}
- (forms/form-data (dom/by-id "test-form"))))
+ (forms/form-data (dom/by-id "test-form"))))
+ (context "with a field"
+ (with field (dom/single-node (h/html [:div
+ [:label {:for "one"} "Label"]
+ [:input#one {:type "text" :name "one"}]])))
+ (before (dom/append! (css/sel "body") @field))
+ (it "displays an error on a form field"
+ (forms/display-errors {:errors {:one ["is lonely"]}})
+ (let [errors (dom/nodes (css/sel "p.field-errors"))]
+ (should= 1 (count errors))
+ (should= "one is lonely" (dom/text (first errors))))
+ (should-contain "field-error" (dom/classes (dom/by-id "one"))))
+ (it "displays multuple errors on a form field"
+ (forms/display-errors {:errors {:one ["is lonely" "is solitary"]}})
+ (let [errors (dom/nodes (css/sel "p.field-errors"))]
+ (should= 1 (count errors))
+ (should= "one is lonely, one is solitary" (dom/text (first errors)))))
+ (it "removes errors"
+ (forms/display-errors {:errors {:one ["is lonely" "is solitary"]}})
+ (forms/teardown-errors)
+ (should-not-contain "field-error" (vec (dom/classes (dom/by-id "one"))))
+ (should= 0 (count (dom/nodes (css/sel "p.field-errors")))))
+ )
30 src/cljs/com/eighthlight/filament/forms.cljs
@@ -1,11 +1,14 @@
(ns com.eighthlight.filament.forms
+ (:require-macros [hiccup.core :as h])
(:require [clojure.string :as str]
[domina :as dom]
[domina.css :as css]
-(defn form-data [form]
+(defn form-data
+ "Takes a form node, and returns a map of all the data in the form."
+ [form]
(let [form-map (goog.dom.forms.getFormDataMap (dom/single-node form))]
(fn [result key]
@@ -14,4 +17,27 @@
(assoc result (keyword key) (first value))
(assoc result (keyword key) value))))
- (.getKeys form-map))))
+ (.getKeys form-map))))
+(defn display-errors
+ "Highlights all the errors for a given model and display the error messages next to the field.
+ Assumes:
+ - (:errors model) will return a Metis style map of errors eg. {:field-name [\"first error\" \"second error\"]}
+ - each input node has an id that matches the model's field name.
+ CSS:
+ .field-error - is applied to input nodes that have an error
+ p.field-errors - contains the error messages and is added to the dom before each error input"
+ [model]
+ (doseq [[field errors] (:errors model)]
+ (let [error-message (str/join ", " (map #(str (name field) " " %) errors))
+ input (dom/by-id (name field))]
+ (dom/add-class! input "field-error")
+ (dom/insert-before! input (h/html [:p.field-errors error-message])))))
+(defn teardown-errors
+ "Removed all the error messages and highlighting done by `display-errors`"
+ []
+ (dom/detach! (css/sel "p.field-errors"))
+ (dom/remove-class! (css/sel ".field-error") "field-error"))

0 comments on commit 76c4c3a

Please sign in to comment.
Something went wrong with that request. Please try again.