tbranyen/diffhtml

innerHTML() function do not applying checkbox checked state

jmas opened this issue · 6 comments

jmas commented

Hello. I trying to reinvent ToDo app. But have issue with <input type="checkbox" /> element.

export function createTask (task, index) {
  return html`
    <li>
      <label>
        <input type="checkbox" onclick="${onTaskChange}" value=${index} ${task.done ? 'checked': ''} />
        ${task.name} (${task.done ? 'Done': 'Not Done'})
      </label>
    </li>
  `;
}

Here is link where you can see full code listing: https://github.com/jmas/htmldiff-todo/blob/master/src/ui.js#L23

This line is working correctly:
${task.name} (${task.done ? 'Done': 'Not Done'}).

But there is a problem:
<input type="checkbox" onclick="${onTaskChange}" value=${index} ${task.done ? 'checked': ''} />

Problem
Checkbox wan't change checked state, even task.done is true.

Update: If I change input to following structure:

<input type="checkbox" onclick="${onTaskChange}" value=${index} k="${task.done ? 'checked': ''}" />

I can see that k attribute is changing it state from (empty) to checked.

Hrm, @jmas what about this: https://github.com/tbranyen/todomvc/blob/gh-pages/lib/components/todo-list.js#L13

This appears to work fine, I wonder why you were hitting an issue. I noticed your PR, and I'll try and write a unit test to complement it when I get into the office.

jmas commented

@tbranyen You are right. This pice of code do not work for me. Or work partly/buggly.
You can checkout my todo app: https://github.com/jmas/htmldiff-todo and find similar place in file src/ui.js. And it do not working with actual diffhtml.
It should remove checked attribute, but get newAttr={"": ""} and condition !newAttr is not pass and checked attribute still in DOM tree.
Thanks for response!

Well I've tried quite a few tests to try and make this break and I've yet to see why we need this patch. I'll open a PR and maybe you can try and break them?

#102 << check out the two it.only tests here

Edit: nicer view: https://github.com/tbranyen/diffhtml/pull/102/files

jmas commented

@tbranyen I found where was a problem.

It all about how browser process events on buttons checkbox, radio.
When I click checkbox I do event.preventDefault() and this instruct browser to do not check input in current processing loop.
I click checkbox > I prevent default browser behavior > Pass changed value to store > And I though that checkbox should be checked by value from store, but in doesn't do it (browser ignore it).

So my solution is: to modify render process:

store.subscribe(() => window.requestAnimationFrame(render));

Now each render will be in next event loop, so checkbox, radio now is working as it working in React+Flux.

Thanks for watching us. I close the issue.

Awesome, glad you were able to figure it out!