HTML boolean attributes break dynamic expressions

This issue has been tracked since 2023-01-12.

Boolean attributes such as the checked attribute on a checkbox seem unable to be set by dynamic expressions.

Example:

This renders and behaves as expected when the checked attribute is static:

html`<input type="checkbox"
  ${data.foo ? 'checked' : ''}
  @input="${e => data.foo = e.target.checked}"
/>`

However, if we make the checked attribute dynamic, two things go wrong:

html`<input type="checkbox"
  ${() => data.foo ? 'checked' : ''}
  @input="${e => data.foo = e.target.checked}"
/>`

(1) It renders like this in the browser, with an unchecked checkbox followed by some mangled code as plain text. (The name of the attribute, checked, seems to replace the value of the next attribute, @input.)

☐ @input="checked" />

(2) The @input event doesn't fire when the checkbox is clicked.

Workaround:

Checkboxes can be made to work by making the checked attribute static and then manipulating the checkbox DOM element directly when the value changes, with $on.

Here's a generalized implementation of the workaround that I've only tested with checkboxes:

function booleanHack(data, prop, attr) {
  let hackAttr = `boolean-hack="${prop}"`;
  data.$on(prop, () => {
    document.querySelectorAll(`[${hackAttr}]`).forEach(el => {
      el[attr] = data[prop];
    });
  });
  return hackAttr;
}

html`<input type="checkbox"
  ${booleanHack(data, 'foo', 'checked')}
  ${data.foo ? 'checked' : ''}
  @input="${e => data.foo = e.target.checked}"
/>`
justin-schroeder wrote this answer on 2023-01-13

This is working as expected. In arrow (just like in React or Vue) you cannot use dynamic expressions to create new attributes, but you can effect whether a given attribute is rendered or not by assigning it to a falsey value:

https://codepen.io/justin-schroeder/pen/JjBJXpW

thomasperi wrote this answer on 2023-01-13

Thanks, but that way has a different problem: Once I interact with the checkbox, it breaks. I can turn the checkbox on and off with the button initially, but once I click the checkbox itself, the button can't change it anymore.

justin-schroeder wrote this answer on 2023-02-20

@thomasperi this should all be working now. Checkboxes now set the internal IDL attribute rather than the checked attribute: https://codepen.io/justin-schroeder/pen/JjBJXpW

More Details About Repo
Owner Name justin-schroeder
Repo Name arrow-js
Full Name justin-schroeder/arrow-js
Language TypeScript
Created Date 2022-11-08
Updated Date 2023-03-28
Star Count 1240
Watcher Count 21
Fork Count 22
Issue Count 7

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date