In lit-html 1.0.0-rc.2, I have the following template, which does not work correctly. So, I suppose I'm doing something wrong. Or is this just a bug in lit-html?
import { html } from './node_modules/lit-html/lit-html.js';
import css from './css.js';
export default function template(c) {
console.log('props', c.text, c.selected, c.checkbox, c.radioButton);
const changeText = c.changeText.bind(c);
return html`
${css()}
<form>
<div>input cannot be updated programatically</div>
<input type="text" value="${c.text}" @input="${changeText}"/>
<div>select cannot be set/changed programatically</div>
<select @change="${ev => {c.selected = ev.currentTarget.value; console.log('value set to', ev.currentTarget.value)}}">
<option value="" ?selected="${c.selcted === ''}">Select</option>
<option value="1" ?selected="${c.selcted === '1'}">1</option>
<option value="2" ?selected="${c.selcted === '2'}">2</option>
<option value="3" ?selected="${c.selcted === '3'}">3</option>
<option value="4" ?selected="${c.selcted === '4'}">4</option>
</select>
<div>checkbox cannot be updated programatically</div>
<input
type="checkbox"
@change="${(ev) => {c.checkbox = ev.currentTarget.value; console.log('checkbox value:', ev.currentTarget.value)}}"
?checked="${c.checkbox === 'on'}"
/>
<div>radio buttons cannot be updated programatically</div>
<input
name="radio"
type="radio"
value="1"
@change="${ev => {c.radioButton = '1'; console.log('radio button value: ', ev.currentTarget.value)}}"
?checked="${c.radioButton === '1'}"/>
<label>1</label>
<input
name="radio"
type="radio"
value="2"
@change="${ev => {c.radioButton = '2'; console.log('radio button value: ', ev.currentTarget.value)}}"
?checked="${c.radioButton === '2'}"/>
<label>2</label>
<input
name="radio"
type="radio"
value="3"
@change="${ev => {c.radioButton = '3'; console.log('radio button value: ', ev.currentTarget.value)}}"
?checked="${c.radioButton === '3'}"/>
<label>3</label>
</form>
`;
}
It is populated/controlled by the following web component:
import { render } from './node_modules/lit-html/lit-html.js';
import template from './template.js';
class MyForm extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.text = 'foo';
this.selected = '2';
this.checkbox = 'on';
this.radioButton = '1';
}
attributeChangedCallback(name, oVal, nVal) {
}
connectedCallback() {
this.render();
setInterval(() => {
this.text = 'foobar';
this.selected = '3';
this.checkbox = 'off';
this.radioButton = '2';
this.render();
}, 2000);
}
disconnectedCallback() {
}
changeText(ev) {
const { value } = ev.currentTarget;
this.text = value;
this.render();
}
render() {
render(template(this), this.shadowRoot);
}
static get observedAttributes() {
return ['']
}
}
customElements.get('my-form') || customElements.define('my-form', MyForm);
export { MyForm }
Note the web component attempts to set the value of various inputs on first render. Thereafter, it attempts to set them again using setInterval. setInterval is used solely to show how the web component is attempting to update the template.
In the case of the select, an option cannot be set programatically. And in the case of each of the other input elements, once selected in the UI cannot be updated programatically.
I don't think it's a bug in Lit, though you're using it in quite a unique way.
In the case of your
<select>
the problem is that you're settingc.selected
but then checkingc.selcted
in each<option>
.