Todo list

A list of tasks: add one, tick it off, remove it. The state is the list itself, read back as JSON below it.

It builds on two toolkits. Util gives the short DOM helpers, up and one. Val renders each item from a template with vappend, flips its status with set, and reads the whole list back with varr.


Uses: Util.js, Val.js

<div todo-space>
    <template todo-item-tpl>
        <div todo-item>
            <i val val-fx="Pattr" val-key="status" val-attr="todo-item-status" hidden></i>
            <input type="checkbox" todo-item-checkbox onchange="Todo.Check(this)" />
            <span todo-item-text val val-fx="Text" val-key="text"></span>
            <button onclick="Todo.Remove(this)">remove</button>
        </div>
    </template>
    <div todo-items val-tpl="[todo-item-tpl]"></div>
    <div todo-add val val-fx="Obj">
        <input val val-fx="Input" val-key="text" type="text" />
        <button onclick="Todo.Add(this)">add</button>
    </div>
    <pre todo-output></pre>
</div>
const Todo = (() => {
    const Add = (ctx) => {
        const space = ctx.up('[todo-space]');
        const add = space.one('[todo-add]');
        space.one('[todo-items]').vappend([{ ...add.val(), status: 'todo'}]);
        add.val({ text: '' });
        Output(space);
    };
    const Check = (ctx) => {
        ctx.up('[todo-item]').set(d => ({ ...d, status: d.status === 'done' ? 'todo' : 'done' }));
        Output(ctx.up('[todo-space]'));
    };
    const Remove = (ctx) => {
        const space = ctx.up('[todo-space]');
        ctx.up('[todo-item]').remove();
        Output(space);
    };
    const Output = (space) => {
        space.one('[todo-output]').textContent = JSON.stringify(space.one('[todo-items]').varr(), null, 4);
    }
    return {
        Add,
        Check,
        Remove,
    }
})();

The todo-item-status attribute is a contract. The HTML, the JavaScript, and the CSS all use it. The CSS styles the done item straight from the attribute. There is no active class toggled in JavaScript, so changing the style never means changing the code.

[todo-item][todo-item-status="done"] [todo-item-text] {
  text-decoration: line-through;
}

Next: Produce →