How do I create the onClick function for a button with Kotlinx.html?

1.6k views Asked by At

I am using Kotlin's html library kotlinx.html for dynamic html building.

I want to create a button which triggers a function when clicked. This is my current code:

class TempStackOverflow(): Template<FlowContent> {
    var counter: Int = 1

    override fun FlowContent.apply() {
        div {
            button(type = ButtonType.button) {
                onClick = "${clicked()}"
            }
        }
    }

    fun clicked() {
        counter++
    }
}

This results in the following source code:

<button type="button" onclick="kotlin.Unit">testkotlin.Unit</button>

Which gives this error when clicked (from Chrome developer console):

Uncaught ReferenceError: kotlin is not defined at HTMLButtonElement.onclick

I have tried several approves, and search for a solution - but could not find the proper documentation.

3

There are 3 answers

2
Alexey Sviridov On BEST ANSWER

Unfortunately, you're completely missing the point of the kotlinx.html library. It can only render HTML for you, it's not supposed to be dynamic kotlin->js bridge, like Vaadin or GWT. So, you just set result of clicked function converted to String to onClick button's property, which is effective kotlin.Unit, because kotlin.Unit is default return value of a function if you not specify another type directly.

    fun clicked() {
        counter++
    }

is the same as

    fun clicked():Unit {
        counter++
    }

and same as

    fun clicked():Kotlin.Unit {
        counter++
    }

So, when you set "${clicked()}" to some property it actually exec function (your counter is incremented here) and return Koltin.Unit value, which is becomes "Kotlin.Unit" string when it rendered inside "${}" template

0
Pointer Null On

If you really need a bit on Javascript here, you can type this:

   unsafe {
      +"<button onClick = console.log('!')>Test</button>"
   }

Good for debugging and tests, but not very nice for production code.

0
Alex Humphrey On

I am not a Kotlin expert, but it's perfectly possible to write event handlers using kotlinx. Rather than:

onClick = "${clicked()}"

have you tried using this?

onClickFunction = { clicked() }