Binding.scala icon indicating copy to clipboard operation
Binding.scala copied to clipboard

Inconsistent empty attribute behaviour

Open NekoiNemo opened this issue 6 years ago • 4 comments

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>

NekoiNemo avatar Mar 21 '19 08:03 NekoiNemo

What's your expected behavior?

Atry avatar Mar 21 '19 10:03 Atry

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>

NekoiNemo avatar Mar 21 '19 11:03 NekoiNemo

Interesting because we did not give any special treatment between empty and non-empty string attributes.

https://scalafiddle.io/sf/YVOjunl/0

Atry avatar Mar 28 '19 09:03 Atry

Fortunately this inconsistency is not found on boolean attributes: https://scalafiddle.io/sf/YVOjunl/2

Atry avatar Mar 28 '19 09:03 Atry