4

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.

Lekkkim
  • 43
  • 3

3 Answers3

0

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() }
Alex Humphrey
  • 6,099
  • 4
  • 26
  • 41
0

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.

Pointer Null
  • 39,597
  • 13
  • 90
  • 111
-1

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

Alexey Sviridov
  • 3,360
  • 28
  • 33
  • Thanks for the quick answer! I am desperately searching for a platform for my app, so I kind of rushed into using it. Thanks for enlightening me. I will try to move towards Kotlin + JS/React. I am currently working with React at other projects and I should provide what I need. – Lekkkim May 13 '21 at 08:16
  • Excellent choice, Kotlin for backend, JS/React for frontend is a wise decision – Alexey Sviridov May 13 '21 at 08:21