17

I am new to Clojurescript. I want to know how to create html elements, and how to change their properties using clojurescript. I cannot seem to find a lot of relevant information online.

akond
  • 15,865
  • 4
  • 35
  • 55
mandy1339
  • 496
  • 3
  • 11

2 Answers2

17

ClojureScript provides good interoperability with JavaScript and the browser. You can call JavaScript globals and functions directly to query and manipulate DOM like so:

(-> js/document
    (.getElementById "app")
    (.-innerHTML)) ; returns contents of element with id 'app'

(-> js/document
    (.getElementById "app")
    (.-innerHTML)
    (set! "Hello Clojure!")) ; Sets new content for element

Checkout ClojureScript cheatsheet for short summary of JavaScript inter-operability in CLJS.

However, modern Web apps are not built with such direct DOM manipulation. @scott-lowe's answer suggests using Reagent, which is a ClojureScript bridge for React, (one of) the most popular JS framework for UIs at the moment. A good choice for getting started with Web apps.

In addition, I would recommend looking at re-frame, which builds on Reagent, and provides state management for your app. Easy way to get started is to install the Leiningen build tool, and simply say lein new re-frame my-app-name. This gives you a good template to start experimenting. Run the app with lein figwheel and you can see your changes to the cljs code instantly in the browser. A good place to start hacking is views.cljs, which contains hiccup-like template for your main app.

Toni Vanhala
  • 1,352
  • 6
  • 16
  • Thank you so much. I never realized the ClojureScript cheatsheet was different from Clojure's cheatsheet. The js/jQuery function seems great for getting started hacking around. Thanks!! – mandy1339 Jul 21 '17 at 18:07
  • Minor detail: My example is not really jQuery, but use of standard Web APIs of the browser, including [getElementById](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById). – Toni Vanhala Jul 21 '17 at 19:24
7

Take a look at the Reagent project, which "provides a minimalistic interface between ClojureScript and React".

The Reagent project website includes this example:

(ns example
  (:require [reagent.core :as r]))

(defn simple-component []
  [:div
   [:p "I am a component!"]
   [:p.someclass
    "I have " [:strong "bold"]
    [:span {:style {:color "red"}} " and red "] "text."]])

(defn render-simple []
  (r/render [simple-component]
    (.-body js/document)))

In the above example, the Reagent component simple-component is rendered into the DOM at the body node of js/document. The Reagent component is just a simple function, but you can compose more complex blocks of HTML by composing these simple functions together.

There are many other ways to generate HTML and interact with the DOM from ClojureScript, but I think it's fair to say that Reagent is one of the most popular libraries in the ClojureScript community right now; it's also mature and well documented.

Scott
  • 17,127
  • 5
  • 53
  • 64
  • Wow Reagent seems really go with Clojurescripts flow. It uses vectors and maps for the elements and properties. I will most definitively be using this library. Thank you so much Scott! – mandy1339 Jul 21 '17 at 18:11
  • I'm glad you like the look of Reagent! I've gotten a lot of fun and enjoyment out of it recently. That said, @toni-vanhala's advice is equally good: There's an awful lot you can achieve with little more than ClojureScript's JS-interop and the standard suite of JS functions built into modern browsers. It doesn't hurt to learn and use both approaches as required :-) – Scott Jul 21 '17 at 21:47