Search code examples
clojureclojurescriptom

Clojurescript OM targeting element on different html


So I'm starting to learn clojurescript and I'm checking out different tutorials on it. One thing I wasn't able to find out is to target an element id on a certain html file to put my markups.

Let's say I have two html files, index.html and about.html. I want to target my code below to the element id "app" on about.html when the url is pointing to http://localhost:3449/about

code :

(om/root
  (fn [data owner]
    (reify
      om/IRender
      (render [_]
        (dom/p nil (:text data)))))
  app-state
  {:target (. js/document (getElementById "app"))}) 

What would be the best approach to do this? Or maybe a reference so I can look at it. Or maybe I'm missing some point here and maybe someone can enlighten me.

Also I have tried using this https://github.com/gf3/secretary but I'm not sure if it's a better approach since urls must have a hashkey(http://localhost:3449/#/about) to trigger.

Update:

So I have used the answer below and it did work but I faced some problem before making it to work. In any case somebody run into this post and have used the answer below but got an undefined issue check my final code.

:cljsbuild section of your project.clj

:cljsbuild {:builds [{ :id "dev" :source-paths ["src/clj" "src/cljs"] :compiler {:output-to "resources/public/js/main.js" :output-dir "resources/public/js/out/" :optimizations :none :pretty-print true}}]}

included js files on about.html

<script src="js/out/goog/base.js" type="text/javascript"></script> <script src="js/main.js" type="text/javascript"></script> <script type="text/javascript">goog.require("om_async.about");</script> <script type="text/javascript">om_async.about.init();</script>


Solution

  • You need to add your javascript file to the html file that you want to use it on. So if you have two different html files index and about you will need two different cljs files.

    Both of them will contain a method to initialize the js like this

    (defn ^:export init []
      (om/root
        (fn [data owner]
          (reify
            om/IRender
            (render [_]
              (dom/p nil (:text data)))))
        app-state
        {:target (. js/document (getElementById "app"))}))
    

    And in your about.html file you will call the js like this:

    <script type="text/javascript">your.namespace.about.init();</script>
    

    And in the index.html:

    <script type="text/javascript">your.namespace.index.init();</script>
    

    At least that's how I did it. I'd be curious to know if there are more elegant ways to do it.

    Update: Please have a look here at the bottom for the export function: https://github.com/sveri/siwf/blob/master/src/cljs/de/sveri/siwf/groups.cljs and here for the html template where the function is used: https://github.com/sveri/siwf/blob/master/resources/templates/groups.html

    It is hard to tell what is going wrong at your place, most probably it is a namespace issue.
    Also make sure to add your compiled js file before you call:

    <script src="/js/app.js"></script>
    <script type="text/javascript">your.namespace.index.init();</script>