DOM Basics

Table of Contents

Creating DOM Elements and Fragments

Let's create a <button> as a child of the <body> element and set its text:

fun main() {
    Kweb(port = 16097) {
        doc.body {
            button().text("Click Me!")
        }
    }
}

The Kweb DSL can be used to create nested elements:

Kweb(port = 16097) {
    doc.body {
        table {
            tr {
                th().text("Name")
                th().text("Age")
            }
            tr {
                td().text("Alice")
                td().text("21")
            }
            tr {
                td().text("Bob")
                td().text("22")
            }
        }
    }
}

Element Attributes

If you assign the button element to a val then you can also set its attributes:

val button = button()
button.text("Click Me!")
button.classes("bigbutton")
button["autofocus"] = true

Or delete it:

button.delete()

Adding children to an existing element

The DSL syntax makes it very easy to create elements and their children together:

ul {
    li().text("One")
    li().text("Two")
}

The created Element is passed to the {block} as a parameter, which can be used to set attributes on the element, add listeners, or set the element's text or innerHtml:

button { btnEl ->
    with(btnEl) {
        classes("bigbutton")
        this["autofocus"] = true
        text("Click Me!")
    }
}

We can also use the new {} function to add children to a pre-existing Element:

val unorderedList : ULElement = ul()
unorderedList.new {
    li().text("One")
    li().text("Two")
}

Reading from the DOM

Kweb can also read from the DOM, in this case the value of an <input> element:

val input: InputElement = input(type = InputType.text)
// A KVar is a mutable value to which you can add listeners
val inputKVar = input.value
inputKVar.addListener { old, new ->
    println("Input changed from $old to $new")
}

Events can evaluate a JavaScript expression and send the result to the server, in this case we give it an expression that will retrieve the value of an InputElement, conveniently provided by valueJsExpression.

Note: See the Observer Pattern & State section for another way to read input element values.

Supported HTML tags

Kweb supports a significant subset of HTML tags like button(), p(), a(), table(), and so on. You can find a more complete list in prelude.kt (scroll down to the Functions section). This provides a nice statically-typed HTML DSL, fully integrated with the Kotlin language.

If a tag doesn't have explicit support in Kweb that's not a problem. For example, here is how you might use the infamous and now-obsolete <blink> tag:

element("blink") {
    span().text("Blinking Text")
}

Further Reading

The Element class provides many other useful ways to interact with DOM elements.