Skip to content

ideal-knee/dommy

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A ClojureScript DOM manipulation, templating and event library.

Usage

Add the following dependency to your project.clj:

[prismatic/dommy "0.1.1"]

Selection

DOM nodes are selected using macros, which expand to the correct native dom calls. Because selectors don't wrap returned nodes, there is a distinction between single and multiple selections. A selector can be a keyword, string or vector.

(ns …
  (:require 
    [dommy.utils :as utils]
    [dommy.core :as dommy])
  (:use-macros
    [dommy.macros :only [node sel sel1]]))

(sel1 :body) ; => document.body
(sel1 :#header) ; => document.getElementById("header")
(sel1 ".todo") ; => document.getElementsByClassName("todo")[0]

(sel [:#todos :li]) ; => document.querySelectorAll("#todos li")

DOM Manipulation

Inspired by jQuery, but adapted to be functional in order to better fit with ClojureScript core.

(dommy/append! (sel1 :#todos) [:.todo "Eat some cake"])

(doseq [todo (sel :.todo)]
  (dommy/add-class! todo :complete))

(map dommy/text (sel :.todo))

Functions that modify take the target dom node as their first argument, and return the same modified node, allowing the use of threading macros to accomplish jQuery-like chaining.

(-> (sel1 :#my-button)
	(dommy/remove-attr! :disabled)
	(dommy/add-class! :active)
	(dommy/set-text! "Click me!"))

(->> (sel :.image)
	 (filter #(> (dommy/px % :width) 500))
	 (map #(dommy/add-class! % :big-image)))

Dom manipulation is defined in dommy.core and dommy.attrs.

Templating

Templating syntax is based on Hiccup, a great HTML library for Clojure. Instead of returning a string of html, dommy's node macro returns a DOM node.

(ns …
  (:require [dommy.core])
  (:use-macros
    [dommy.macros :only [node]]))

(node
  [:div#id.class1
    (for [r (range 2)]
      [:span.text (str "word" r)])]) ;; => [object HTMLElement]

;; Styles can be inlined as a map
(node
  [:span
    {:style
      {:color "#aaa"
       :text-decoration "line-through"}}])

The deftemplate macro is useful syntactic sugar for defining a function that returns a DOM node.

(ns …
  (:require [dommy.core])
  (:use-macros
    [dommy.macros :only [node deftemplate]]))

(defn simple-template [cat]
  (node [:img {:src cat}]))

(deftemplate simple-template [cat]
  [:img {:src cat}])

Thanks to @ibdknox, you can define view logic for custom types by implementing the PElement protocol:

(defrecord MyModel [data]
   dommy.template/PElement
   (-elem [this] (node [:p (str "My data " data)])))

(dommy/append! (sel1 :body) (MyModel. "is big"))

Type-Hinting Template Macros

One caveat of using the compile-macro is that if you have a compound element (a vector element) and want to have a non-literal map as the attributes (the second element of the vector), then you need to use ^:attrs meta-data so the compiler knows to process this symbol as a map of attributes in the runtime system. Here's an example:

(node [:a ^:attrs (merge m1 m2)])

Testing

Dommy comes with reasonably extensive tests. To run them first build the test cljsbuild target, as follows:

$ lein clean
$ lein cljsbuild auto test

Next, open up the HTML file under resources/dommy-tests.html which will give you a visual representation of all tests. For all pull requests, please ensure your tests pass (or add test cases) before submitting.

License

Copyright (C) 2013 Prismatic

Distributed under the Eclipse Public License, the same as Clojure.

About

Dommy is a no-nonsense ClojureScript templating and DOM manipulation library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Clojure 100.0%