4

I'm writing a browser app in Kotlin/JS, and I'm using kotlinx.html's DSL to generate some of the HTML. For (a simple) example:

(window.document.body!! as Node).append {
    p {
        +"Some text"
    }
    p {
        +"Click here"
        onClickFunction = { event ->
            <Do some stuff here...>
        }
    }
}

Now my problem is I want to be able to refer to the elements created by this code. For example, say when the user clicks on the second p element (where there's a click event handler) I want to do something with the first p element (e.g. change its text). Is there an elegant way to do that?

I know I can somehow find that element (e.g. by giving it an ID and then looking for it, or by relying on its position or something), and that I can do it either within the event handler or, if I prefer, in some other code that will be run after the elements are created – but still as part of initialisation – and will save a reference to the element in some variable that the event handler can then use. But doing something like that feels like a workaround when my code defines that element right there, and so I'm looking for a way to get a reference to that element as part of the process building it if that's at all possible.

Tom
  • 4,910
  • 5
  • 33
  • 48

2 Answers2

5

The DSL methods also return the DOM object they create, so you can assign them to a variable and use that later:

(window.document.body!! as Node).append {
    val firstP = p {
        +"Some text"
    }
    p {
        +"Click here"
        onClickFunction = { event ->
            firstP.textContent = "Clicked"
        }
    }
}
deive
  • 862
  • 7
  • 19
  • Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Mark Rotteveel Jun 08 '22 at 12:04
  • Thanks, this works perfectly! In fact, it's so obvious that it's not clear to me why I had not thought of that myself... (I think somehow I was sure I had tried it and it didn't work, but clearly it does!) – Tom Jun 09 '22 at 13:41
  • np, Tom! We all have * those * days! – deive Jun 13 '22 at 18:50
  • I guess it didn't work for me because my scenario was slightly different. As this does work for the scenario in this question this is a valid answer, but I opened a new question for the scenario I'm dealing with for which this doesn't actually work: https://stackoverflow.com/questions/76671297/when-using-kotlinx-htmls-dsl-to-create-html-how-is-it-possible-to-refer-to-n. – Tom Jul 12 '23 at 13:49
0

I had a similar problem, the solution I found was to create an element (and get its reference immediately) :

myElement = document.createElement("canvas") as HTMLCanvasElement
// add some more properties at will
myElement.width = 800
myElement.height = 600

then append the newly created element :

document.body!!.append(myElement) 

you have your reference, and you have your referenced element inserted.

Now you can access all the functions you want (in my case the canvas api provided by HTMLCanvasElement) by simply doing myElement.someAPIFunction()

ker2x
  • 440
  • 3
  • 11
  • 1
    note the question was specifically about creating and adding HTML elements using the DSL; your answer doesn't use the DSL but calls to `document.createElement`. – Tom Sep 06 '22 at 16:15
  • ha ok, I didn't know it was different things. thank you. – ker2x Sep 07 '22 at 08:35