js-only todo

by Soviut

HTML

<ul class="list">
</ul>

<script id="itemTemplate" type="text/template">
    <li>
        <input id="item_{index}" type="checkbox"><label for="item_{index}">Label</label></input>
    </li>
</script>

CSS

.done {
    text-decoration: line-through;
}

JavaScript

var items = [
    {label: 'First',  done: false},
    {label: 'Second', done: false},
    {label: 'Third',  done: true}
];

var list = document.querySelector('ul');
var itemTemplate = document.getElementById('itemTemplate');

function createElementFromHTML(html) {
    // temporary container element
    var container = document.createElement('div');
    container.innerHTML = html;

    // transfer all child nodes to a document fragment so they're not inside a div
    var frag = document.createDocumentFragment();
    while (container.childNodes[0]) {
        frag.appendChild(container.childNodes[0]);
    }

    return frag;
}

function renderList() {
    list.innerHTML = '';
    
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        
        var html = itemTemplate.innerHTML;
        var el = createElementFromHTML(html);
        
        var checkbox = el.querySelector('input');
        checkbox.setAttribute('id', 'item_' + i);
        
        var label = el.querySelector('label');
        label.textContent = item.label;
        label.setAttribute('for', 'item_' + i);

        list.appendChild(el);

        if (item.done) {
            //el.classList.add('done');
            checkbox.setAttribute('checked', '');
        }
    }
    
    console.log(items);
}

renderList();

list.addEventListener('change', function(e) {
    e.preventDefault();
    var index = Array.prototype.indexOf.call(list.children, e.target.parentNode);
    items[index].done = !items[index].done;
    renderList();
});