Permalink
Browse files

adds flash

  • Loading branch information...
1 parent 0bbeba7 commit 8abfde4154f53bfadf8f7f60d3d3e5f6b67a8e18 @slagyr slagyr committed Jan 15, 2014
Showing with 161 additions and 1 deletion.
  1. +10 −0 CHANGES.md
  2. +1 −1 project.clj
  3. +75 −0 spec/cljs/com/eighthlight/filament/flash_spec.cljs
  4. +75 −0 src/cljs/com/eighthlight/filament/flash.cljs
View
@@ -1,3 +1,13 @@
+# 1.2.0
+
+* adds flash
+
+# 1.1.4
+
+* adds display-errors, remove-errors to forms
+* adds docstrings to forms
+* adds forms example
+
# 1.1.3
* switched hiccups library to com.8thlight/hiccup 1.1.1
View
@@ -1,4 +1,4 @@
-(defproject com.8thlight/filament "1.1.4"
+(defproject com.8thlight/filament "1.2.0"
:description "Rich client utilities"
:url "http://github.com/8thlight/filament"
:license {:name "Eclipse Public License"
@@ -0,0 +1,75 @@
+(ns com.eighthlight.filament.flash-spec
+ (:require-macros [hiccup.core :as h]
+ [specljs.core :refer [describe context it should= should-not= with before around should-contain should-not-contain]])
+ (:require [com.eighthlight.filament.flash :as flash]
+ [com.eighthlight.filament.spec-helper :as helper]
+ [domina :as dom]
+ [domina.css :as css]
+ [hiccup.core]
+ [specljs.core]))
+
+(describe "Flash"
+
+ (helper/with-clean-dom)
+
+ (it "adds a notice flash"
+ (flash/flash-notice! "first notice")
+ (let [container (dom/single-node (css/sel "body #flash-container"))]
+ (should-not= nil container)
+ (let [notices (dom/single-node (css/sel container "#flash-notices"))]
+ (should-not= nil notices)
+ (should= 2 (count (dom/children notices)))
+ (should= "X" (dom/text (first (dom/children notices))))
+ (should= "first notice" (dom/text (second (dom/children notices)))))))
+
+ (it "adds an error flash"
+ (flash/flash-error! "first error")
+ (let [errors (flash/errors-node)]
+ (should= (flash/flash-container-node) (.-parentElement errors))
+ (should= "flash-errors" (dom/attr errors "id"))
+ (should= 2 (count (dom/children errors)))
+ (should= "X" (dom/text (first (dom/children errors))))
+ (should= "first error" (dom/text (second (dom/children errors))))))
+
+ (it "adds an success flash"
+ (flash/flash-success! "first success")
+ (let [successes (flash/successes-node)]
+ (should= (flash/flash-container-node) (.-parentElement successes))
+ (should= "flash-successes" (dom/attr successes "id"))
+ (should= 2 (count (dom/children successes)))
+ (should= "X" (dom/text (first (dom/children successes))))
+ (should= "first success" (dom/text (second (dom/children successes))))))
+
+ (it "closes errors"
+ (flash/flash-error! "an error")
+ (helper/click! (first (dom/children (flash/errors-node))))
+ (should= nil (dom/by-id "flash-errors")))
+
+ (it "closes notices"
+ (flash/flash-error! "a notice")
+ (helper/click! (first (dom/children (flash/notices-node))))
+ (should= nil (dom/by-id "flash-notices")))
+
+ (it "closes successes"
+ (flash/flash-error! "a success")
+ (helper/click! (first (dom/children (flash/successes-node))))
+ (should= nil (dom/by-id "flash-successes")))
+
+ (it "adds multiple notices"
+ (flash/flash-notice! "first notice")
+ (flash/flash-notice! "second notice")
+ (should= 3 (count (dom/children (flash/notices-node))))
+ (should= ["X" "first notice" "second notice"] (map dom/text (dom/children (flash/notices-node)))))
+
+ (it "clears all flash"
+ (flash/flash-error! "error")
+ (flash/flash-notice! "notice")
+ (flash/flash-success! "success")
+
+ (flash/clear-flash!)
+
+ (should= nil (dom/by-id "flash-container"))
+ (should= nil (dom/by-id "flash-errors"))
+ (should= nil (dom/by-id "flash-notices"))
+ (should= nil (dom/by-id "flash-successes")))
+ )
@@ -0,0 +1,75 @@
+(ns com.eighthlight.filament.flash
+ (:require-macros [hiccup.core :as h])
+ (:require [clojure.string :as str]
+ [com.eighthlight.filament.util :as util]
+ [domina :as dom]
+ [domina.css :as css]))
+
+(defn flash-container-node
+ "Returns the flash container node. The node is added to the DOM if it isn't already attached."
+ []
+ (or
+ (dom/by-id "flash-container")
+ (let [container (dom/single-node (h/html [:div#flash-container]))]
+ (dom/append! (.-body js/document) container)
+ container)))
+
+(defn- flash-section [section]
+ (let [name (str "flash-" section)]
+ (or
+ (dom/by-id name)
+ (let [section-node (dom/single-node (h/html [:div {:id name} [:a.flash-close "X"]]))]
+ (util/override-click! (first (dom/children section-node)) #(dom/destroy! section-node))
+ (dom/append! (flash-container-node) section-node)
+ section-node))))
+
+(defn errors-node
+ "Returns the errors container node. The node is added to the DOM if it isn't already attached."
+ [] (flash-section "errors"))
+
+(defn notices-node
+ "Returns the notices container node. The node is added to the DOM if it isn't already attached."
+ [] (flash-section "notices"))
+
+(defn successes-node
+ "Returns the successes container node. The node is added to the DOM if it isn't already attached."
+ [] (flash-section "successes"))
+
+(defn flash-error!
+ "Adds an error flash to the DOM.
+
+ CSS:
+ #flash-container - a div added to the body element so consider using absolute/fixed positioning
+ #flash-errors - a div inside the flash-container that will hold all the error flashes
+ a.flash-close - the first node in a flash section. Contains the text \"X\". Clicking it will close the section.
+ p.flash-error - one is added to the flash-errors div for each message"
+ [message]
+ (dom/append! (errors-node) (h/html [:p.flash-error message])))
+
+(defn flash-notice!
+ "Adds an notice flash to the DOM.
+
+ CSS:
+ #flash-container - a div added to the body element so consider using absolute/fixed positioning
+ #flash-notices - a div inside the flash-container that will hold all the notice flashes
+ a.flash-close - the first node in a flash section. Contains the text \"X\". Clicking it will close the section.
+ p.flash-notice - one is added to the flash-notices div for each message"
+ [message]
+ (dom/append! (notices-node) (h/html [:p.flash-notice message])))
+
+(defn flash-success!
+ "Adds an success flash to the DOM.
+
+ CSS:
+ #flash-container - a div added to the body element so consider using absolute/fixed positioning
+ #flash-successes - a div inside the flash-container that will hold all the success flashes
+ a.flash-close - the first node in a flash section. Contains the text \"X\". Clicking it will close the section.
+ p.flash-success - one is added to the flash-successes div for each message"
+ [message]
+ (dom/append! (successes-node) (h/html [:p.flash-success message])))
+
+(defn clear-flash!
+ "Removes all flash nodes from the DOM."
+ []
+ (when-let [container (dom/by-id "flash-container")]
+ (dom/destroy! container)))

0 comments on commit 8abfde4

Please sign in to comment.