I want to create some UI from Binding.scala. The UI contains a textbox. When the user type text in the textbox, I want to change the background color according to the user input.
import com.thoughtworks.binding._, Binding._
import org.scalajs.dom._
@dom def render = {
val color = Var("")
val styleText: String = s"background-color: ${color.bind}"
// <div> and <input> will be recreated once data changes.
<div style={styleText}>
<input id="myInput" type="text" oninput={ _: Any => color := myInput.value }/>
</div>
}
dom.render(document.body, render)
The example runs on ScalaFiddle.
However, when I enter something in the textbox, the textbox misses focus and still keep empty.
How can I fix it?
Maybe you defined the <input ...>
and .bind
in the same @dom
method and the <input ...>
is after .bind
. Try to refactor the .bind
and <input ...>
into separate @dom
methods or let the .bind
expression nested in another DOM.
For example, if myInput
is written before .bind
, it will not be recreated:
import com.thoughtworks.binding._, Binding._
import org.scalajs.dom._
@dom def render = {
val color = Var("")
val myInput = <input id="myInput" type="text" oninput={ _: Any => color := myInput.value }/>
val styleText: String = s"background-color: ${color.bind}"
// <div> will be recreated once data changes.
// <input> will not be recreated.
<div style={styleText}>
{myInput}
</div>
}
dom.render(document.body, render)
The above example runs on ScalaFiddle.
If the .bind
expression is embedded in a XHTML literal, it will not affect its children:
import com.thoughtworks.binding._, Binding._
import org.scalajs.dom._
@dom def render = {
val color = Var("")
// <div> and <input> will not be recreated when data changes.
// Only the class attribute will be changed.
<div style={s"background-color: ${color.bind}"}>
<input id="myInput" type="text" oninput={ _: Any => color := myInput.value }/>
</div>
}
dom.render(document.body, render)
The above example runs on ScalaFiddle.
Another approach is wrapping .bind
expression in a @dom val
:
import com.thoughtworks.binding._, Binding._
import org.scalajs.dom._
@dom def render = {
val color = Var("")
@dom val styleText: Binding[String] = s"background-color: ${color.bind}"
// <div> and <input> will not be recreated when data changes.
// Only the class attribute will be changed.
<div style={styleText.bind}>
<input id="myInput" type="text" oninput={ _: Any => color := myInput.value }/>
</div>
}
dom.render(document.body, render)
The above example runs on ScalaFiddle.