Binding.scala
Binding.scala copied to clipboard
Inconsistent empty attribute behaviour
If node attribute is set by binding to empty string on construction - it is omitted from resulting DOM, however if it is set to empty string after DOM is constructed - it results in value-less attribute.
@dom def header: Binding[Node] = {
val selected = Var(-1)
def select(index: Int): Event => Unit = { _ => selected.value = index}
<ul>
<li class={ isSelected(0, selected).bind }><a onclick={ select(0) }>Link 1</a></li>
<li class={ isSelected(1, selected).bind }><a onclick={ select(1) }>Link 2</a></li>
<li class={ isSelected(2, selected).bind }><a onclick={ select(2) }>Link 3</a></li>
</ul>
}
def isSelected(index: Int, value: Binding[Int]): Binding[String] = Binding {
if(value.bind == index) "active"
else ""
}
Example above will be initially rendered as
<ul>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
but after pressing buttons it will came to look like this:
<ul>
<li class="active">...</li>
<li class>...</li>
<li class>...</li>
</ul>
What's your expected behavior?
It seems that value-less attribute is how JS reacts to field being set to empty string, so expected behaviour would be above fragment being initially rendered as
<ul>
<li class>...</li>
<li class>...</li>
<li class>...</li>
</ul>
instead of
<ul>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
Interesting because we did not give any special treatment between empty and non-empty string attributes.
https://scalafiddle.io/sf/YVOjunl/0
Fortunately this inconsistency is not found on boolean attributes: https://scalafiddle.io/sf/YVOjunl/2