Attribute value is not yet defined for tag input
renatoathaydes opened this issue · 4 comments
Got the following error trying to get the value
of an input
:
message: "Attribute value is not yet defined for tag input"
Code:
import kotlinx.browser.document
import kotlinx.html.div
import kotlinx.html.dom.append
import kotlinx.html.h2
import kotlinx.html.id
import kotlinx.html.input
import kotlinx.html.js.onKeyUpFunction
import kotlinx.html.style
import kotlinx.html.unsafe
import org.w3c.dom.HTMLElement
object HtmlIds {
const val base58Result = "base58-result"
}
/**
* Test application for the base58 library.
*
* It helps test that the code works on a browser.
*/
fun main() {
byId("root").append {
h2 {
+"Enter some text:"
}
input {
placeholder = "Text to encode to base58"
onKeyUpFunction = { _ ->
byId(HtmlIds.base58Result).textContent = value
}
}
div {
id = HtmlIds.base58Result
style {
unsafe { raw("padding: 10px; background: green; color: white") }
}
}
}
}
private fun byId(id: String): HTMLElement {
return (document.getElementById(id) as HTMLElement?)!!
}
A workaround for this is to define the onKeyUp()
function after the declaration of the input
tag, e.g.
val input = input {
placeholder = "Text to encode to base58"
}
input.onkeyup = { _ ->
byId(base58Result).textContent = input.value
asDynamic()
}
@e5l some input on this would be worthwhile, because I'm not sure how to reconcile the fact that the input
object within the builder block isn't the actual input
object within the DOM - and thus, you're not getting the actual value
field within the DOM object when you invoke value
within the builder block - without some considerable refactoring.
@severn-everett, yep we can't make it without refactoring. Could you tell me if you have an idea on how to do that?
As workaround we can try introducing some property (like input { domItem.value }
) which will be resolved to actual dom item when it called. It also can cause error if the element is not initialized yet, so we need to check
It might be worth updating the onEvent
callback signature in this codebase so that the actual DOM object gets passed in as well, so the user could then do something like:
input {
placeholder = "Text to encode to base58"
onKeyUpFunction = { inputDOM, _ ->
byId(HtmlIds.base58Result).textContent = inputDOM.value
}
}
Not the prettiest, but at least it'd minimize the amount of code that would need to get shuffled around behind the scenes.