Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to create new elements in ClojureScript and it doesn't appear to be working. I'll start up by showing an example that I found here.

(let [dom6238 (.createElement js/document "a")]
    (.setAttribute dom6238 "href" "http://somelink")
    (set! (.-innerText dom6238) "Text")
    dom6238)

Which they say converts to:

var dom54535 = document.createElement("a");
    dom54535.setAttribute("href", "http://somelink.com");
    dom54535.innerText = "Hello there";
return dom54535

If I'm not mistaken, this should produce an HTML snippet that looks like:

[:a.anchor.silly {:href "http://somelink.com"} "Text"]

I have this in my .cljs file:

(defn create-button []
  (let [a (.createElement js/document "a")]
    (.setAttribute a "href" "http://somelink")
    (set! (.-innerText a) "Text")
    a))

(defn init []
  (let [a (.getElementById js/document "write-action")
        b (.getElementById js/document "button-field")]
    (set! (.-innerHTML a)
          "field a")
    (set! (.-innerHTML b)
          (create-button))))

Which just produces (button-field is above write-action in the HTML):

http://somelink/
field a

So there is no anchor tags, only text.


What I am attempting to do is create a button, so I have this code:

(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")
    (set! (.-innerHTML new-button)
          "I'm a button")
    new-button))

Which generates this output:

[object HTMLInputElement]
field a

So, I play around a bit and remove the return value:

(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")
    (set! (.-innerHTML new-button)
          "I'm a button")))

Which creates:

I'm a button
field a

Once again, I have only text.


And I have to be complete:

(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")))

Which only returns the text:

button
field a

And this:

(defn create-button []
  (let [new-button (.createElement js/document "input")]
    (set! (.-type new-button)
          "button")
    new-button))

Produces this:

[object HTMLInputElement]
field a

I'm completely lost here and I've searched high and low for any solution and there doesn't appear to be anything out there that answers this question. I've tried wrapping the new set attributes in (do) as well as as trying out versions without (set!) but nothing is creating the desired result.

Q: How do I create a button that can be clicked using ClojureScript?

Bonus Q if anyone knows: Why does the example from the site only return the result of the first item and not innerText while my examples only return the text results of the second (set!) functions?

share|improve this question
    
Could you please accept Ankur's answer if it works for you? –  deterb Apr 20 '13 at 17:38
1  
@deterb Sure, but is that really good form? I mean, it's like me asking you to upvote my question if it was helpful to you. The reason I didn't want to accept it right off is because I've seen answers simply hinted at but never elaborated on because another answer was already chosen. I prefer to wait a few days before choosing an answer because of this. If you look at my history, every topic I've posted has a chosen answer. –  dizzystar Apr 20 '13 at 19:43
    
Interesting perspective, I like where you are coming from. I see enough cases where people comment on an answer and then don't select it that I put up a reminder comment as I come across them. I'll give the next pairing more time then. –  deterb Apr 22 '13 at 3:07
add comment

1 Answer

up vote 3 down vote accepted

You are assigning a DOM element object to innerHTML property of another element which is obviously not going to work. You need to use appendChild method on the DOM element to insert a child element into it.

(let [div (.createElement js/document "DIV")]
    (.appendChild div (create-button)))
share|improve this answer
    
Ah, I see now. I was using (.appendChild) before but was messing up the syntax a bit by wrapping it in (set!). Turns out I can just append to the div that already exists. Perfect answer. –  dizzystar Apr 20 '13 at 16:01
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.