Elements and custom elements are regular functions. The function below, loud , accepts any number of children. It constructs and returns a div containing the uppercased children .

;; start 3 more timers, each with different starting values

;; our first timer will start at 0 and count up

In this example, the timer function initializes a Javelin input cell and schedules it for periodic update using window.setInterval . The text of the returned div is attached reactively to seconds through a formula cell created using cell= .

An application

In this final example, todo-list is a function that returns an instance of a simple todo list application. The application responds to user input by updating input cell values when DOM events occur.

The :change event on the text input is attached to a function that updates the new-item input cell as keystrokes occur.

The :click event on the button is attached to a function that appends the value of new-item to the end of todo-items inside a dosync . dosync is a transactional construct that suspends the propagation of new values through the cell graph while updating multiple cells.

todo-items are rendered as li elements using the loop-tpl macro. loop-tpl efficiently maps dynamically-sized collections to DOM nodes.

( defelem todo-list [{ :keys [ title ]} _ ] ( let [ todo-items ( cell []) new-item ( cell "" )] ( div ( h3 ( or title "TODO" )) ( ul ( loop-tpl :bindings [ todo todo-items ] ( li todo ))) ( input :type "text" :value new-item :change # ( reset! new-item @ % )) ( button :click # ( dosync ( swap! todo-items conj @ new-item ) ( reset! new-item "" )) ( text "Add #~{(inc (count todo-items))}" ))))) ( todo-list :title "TODO List" )