3

I want to create a custom tag with Kotlin that contains default content. The linked example works fine, but I didn't manage to add some default content (e.g. input element) to the custom tag.

I've tried different things, but so far only managed to add the input element next to the custom tag in the DOM, but not inside it.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JS Client</title>
</head>
<body>
<script src="webcomponentexampleproject.js"></script>
<div id="root"></div>
</body>
</html>

client.kt

import kotlinx.browser.document
import kotlinx.browser.window
import kotlinx.html.InputType
import kotlinx.html.dom.append
import kotlinx.html.dom.create

fun main() {
    window.onload = {

        document.getElementById("root")!!.append {
            webcomponent {
                text = "added it"
                +"some more text"
            }
        }

    }
}

WebComponent.kt

import kotlinx.html.*
import kotlinx.html.js.onChangeFunction
import org.w3c.dom.HTMLInputElement
import org.w3c.dom.events.Event
import kotlin.properties.Delegates

@JsExport
class WebComponent(consumer: TagConsumer<*>, _text: String = "", _backgroundColor: String = "none") :
    HTMLTag("webcomponent", consumer, emptyMap(), inlineTag = true, emptyTag = false), HtmlInlineTag {

    var text: String by Delegates.observable(_text) { prop, old, new ->
        el.value = text
    }
    var backgroundColor: String by Delegates.observable(_backgroundColor) { prop, old, new ->
        el.style.backgroundColor = backgroundColor
    }

    private val el: HTMLInputElement

    init {
        //TODO: this input element should be INSIDE the tag
        el = consumer.input {
            type = InputType.text
            value = [email protected]
        }.unsafeCast<HTMLInputElement>()
    }
}

// make the new custom tag usable via the kotlinx.html DSL
fun <T> TagConsumer<T>.webcomponent(block: WebComponent.() -> Unit = {}): T {
    return WebComponent(this).visitAndFinalize(this, block)
}

1 Answer 1

1

Try to call onTagContentUnsafe after the element init:

private val el: HTMLInputElement

init {
    el = consumer.input {
        type = InputType.text
        value = [email protected]
    }.unsafeCast<HTMLInputElement>()

    consumer.onTagContentUnsafe {
        +el.outerHTML
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

this results in adding only the input element but without the parent custom tag

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.