At the core to understanding enfocus is the at form. It comes in two basic flavors listed below:
Single Transform
(at a-node (transform arg1 ...)) ;or implied js/document as main node (at "selector" (transfrom arg1 ...))
Multiple Transforms
(at a-node "selector1" (transform1 arg1 ...) "selector2" (transform2 arg1 ...)) ;or implied js/document as main node (at "selector1" (transform1 arg1 ...) "selector2" (transform2 arg1 ...))
In the first case, at is passed a node/node set or a selector, and a transform and calls the transform on each element in the node set. If a selector is passed the root node is defaulted to js/document.
A transform is nothing more than a function that takes a set of arguments and returns a function that takes a node.
In the second case, we see at is optionally passed a node or node set followed by selector/transform pairs. The selectors are scoped by the node or node set, if provided or js/document otherwise, and the results of each selector is passed on to its partner transformation.
Enfocus supports four types of selectors:
(ef/at "#my-id" (ef/content "hello world"))
(ef/at [:#my-id] (ef/content "hello world"))
(ef/at (ef/xpath "//div[@id='my-id']") (ef/content "hello world"))
Custom Selectors - these are functions that take a root node and return a node or node-list.
(ef/at node #(.children %) (ef/content "hello world"))
The content transform replaces the content nodes returned by the selector with elements in its body. The body can be made up of strings, nodes and/or node sets.
(content “xyz” a-node “abc”)
Example:
The following action is triggered when we click the button.
(em/defaction content-demo [] "#button1" (ef/content "I have been clicked"))
The html-content transform converts the html string to a document fragments and replaces the content of the nodes returned by the selector with the fragment.
(html-content "<tag>content<tag>")
Example: I will be replaced
The following action is triggered when we click the button
(em/defaction html-content-demo [] "#html-content-demo" (ef/html-content "<span style='color: #ff3333'>I replaced the text</span>"))
The set-attr transform will set the value of an attribute on the nodes returned by a selector.
(set-attr :attr1 "test" :attr2 "test2" ...)
Example:
The following action is triggered when we click the button.
(em/defaction set-attr-demo [] "#button3" (ef/set-attr :foo "bar"))
CSS: button[foo=bar] { background-color: #33ff33; }
The remove-attr transform will remove a set of attributes from the nodes returned by a selector.
(remove-attr :attr1 :attr2 ...)
Example:
The following action is triggered when we click the button.
(em/defaction set-attr-demo [] "#button4" (ef/remove-attr :foo))
CSS: button[foo=bar] { background-color: #33ff33; }
The add-class transform will add a list of classes to the nodes returned by a selector.
(add-class "class1" "class2" ...)
Example:
The following action is triggered when we click the button.
(em/defaction add-class-demo [] "#button5" (ef/add-class "highlight"))
CSS: .highlight { border: 2px solid #ff3333; }
The remove-class Transform will remove a set of classes from the nodes returned by a selector.
(remove-class "class1" "class2" ...)
Example:
The following action is triggered when we click the button.
(em/defaction remove-class-demo [] "#button6" (ef/remove-class "highlight"))
CSS: .highlight { border: 2px solid #ff3333; }
The do transform will execute a series of transforms on the nodes returned by a selector.
Note: Effects will be executed asynchronously, if you want synchronization use chain.
(do-> transformation1 transformation2 ...)
Example:
The following action is triggered when we click the button.
(em/defaction do-demo [] "#button7" (ef/do-> (ef/add-attr :foo "bar") (ef/add-class "highlight")))
CSS: button[foo=bar] { background-color: #33ff33; } .highlight { border: 2px solid #ff3333; }
The append transform will append the content to the existing content of the nodes returned by a selector.
(append "text" a-node "text" ...)
Example:
The following action is triggered when we click the button.
(em/defaction append-demo [] "#button8" (ef/append ":append"))
The prepend transform will prepend the content to the existing content of the nodes returned by a selector.
(append "text" a-node "text" ...)
Example:
The following action is triggered when we click the button.
(em/defaction prepend-demo [] "#button9" (ef/prepend "prepend:"))
The after transform will insert the content after the node returned by a selector.
(after "text" a-node "text" ...)
Example:
The following action is triggered when we click the button.
(em/defaction after-demo [] "#button10" (ef/after ":after"))
The before transform will insert the content after the node returned by a selector.
(before "text" a-node "text" ...)
Example:
The following action is triggered when we click the button.
(em/defaction before-demo [] "#button11" (ef/before "before:"))
The substitute transform replaces the node returned by a selector with the content in the body.
(substitute "text" a-node "text" ...)
Example:
The following action is triggered when we click the button.
(em/defaction sub-demo [] "#button12" (ef/substitute "I replaced the button"))
The remove-node transform removes the node returned by a selector from the dom.
(remove-node)
Example: -button will disappear when you click it.
The following action is triggered when we click the button.
(em/defaction remove-node-demo [] "#button22" (ef/remove-node))
The clone-for transform has a similar syntax and function as the clojure for. It will sequence through a collection of items and clone the node returned from the selector with each iteration. This node will be passed to an implicit at form where additional selectors and transformation will modify the cloned node. Once through the entire collection, it will substitute the clone node set for the original node.
(clone-for [item items] transformation) ;or (clone-for [item items] selector1 transformation1 selector2 transformation2)
Example:
fruit | quantity |
---|---|
replace | me |
The following action is triggered when we click the button.
(defn clone-for-demo [] (let [fruit-data {"apple" 5, "pear" 6}] (ef/at "#clone-for-demo tbody > tr:first-child" (em/clone-for [fr (vec fruit-data)] "*:first-child" (ef/content (first fr)) "*:last-child" (ef/content (str (second fr)))))))
The wrap transform will replace the selected node with newly created node that contains the old node as a child.
(wrap :div {:attr1 "test" :attr2 "test2" ...)
Example:
The following action is triggered when we click the button.
(em/defaction wrap-demo [] "#button14" (ef/wrap :span {:class "highlight"}))
CSS: .highlight { border: 2px solid #ff3333; }
The unwrap transform replaces the node returned by a selector with its children.
(unwrap)
Example:
The following action is triggered when we click the button.
(em/defaction unwrap-demo [] "#button15" (ef/unwrap))
CSS: .highlight { border: 2px solid #ff3333; }
The set-style transform sets a style property on selected nodes style object.
(set-style :background-color "#ff3333" :border "1px solid #000"...)
Example:
The following action is triggered when we click the button.
(em/defaction set-style-demo [] "#button16" (ef/set-style :border "2px solid blue"))
The remove-style transform removes a style property on selected nodes style object.
(remove-style :background-color :border)
Example:
The following action is triggered when we click the button.
(em/defaction remove-style-demo [] "#button17" (ef/remove-style :border))
CSS: .highlight { border: 2px solid #ff3333; }
The filter applies a test function to each node returned by the selector and only if the test function returns true is the node passed to the transform.
(filter test-func transform)
Example:
The following action is triggered when we click the button.
(em/defaction filter-demo [] "#email-field" (ef/filter #(> 0 (. (.-value %) (indexOf "@"))) (ef/set-style :background-color "red")) "#email-field" (ef/filter #(<= 0 (. (.-value %) (indexOf "@"))) (ef/set-style :background-color "green")))
The focus & blur transforms set the browser focus to or away from the selected node.
(focus) & (blur)
Example:
The following action is triggered when we click the buttons.
(em/defaction focus-demo [] "#focus-field" (ef/focus)) (em/defaction blur-demo [] "#focus-field" (ef/blur))
The replace-vars transform will replace any ${var} in text and attributes by the value found in the map.
(replace-vars {:key1 "value" :key2 "value"})
Example: ${name} is running ${location}.
The following action is triggered when we click the buttons.
(em/defaction replace-vars-demo [] "#rvar-example" (ef/replace-vars {:name "Kurt" :location "home"}))
The set-data transform will add a piece of data to an immutable map attached to the dom node or nodes. You retrieve the data through the extractor get-data.
(set-data :key "value")