Non-Framework plain ToDo App

by flek

HTML

<input placeholder="what needs to be done?">

<div>
  <div class='left'>
    <h2>todo</h2>
    <ol id="todos"></ol>
  </div>

  <div class='right'>
    <h2>done</h2>
    <ol id="dones"></ol>
    <button id="clear" style="display: none">clear</button>
  </div>
</div>

JavaScript

//////////////////////////////////////////////////
// Template helpers
function createHtmlFromTemplate(template) {
  const dummyEl = document.createElement('div');
  dummyEl.insertAdjacentHTML('beforeend', template);
  return dummyEl.firstChild;
};

function removeAllChildren(el) {
  while (el.firstChild) {
    el.removeChild(el.firstChild);
  }
};

function forEach(creator, parentEl) {
  return function(list) {
    removeAllChildren(parentEl);
    list.forEach(item => {
      const el = creator(item);
      parentEl.appendChild(el);
    })
  }
}

//////////////////////////////////////////////////
// Template creators
function createTodo(text) {
  const el = createHtmlFromTemplate(
    `<li><label><input type=checkbox class="check" />${text}<button class="remove">remove</button></label></li>`
  );

  el.querySelector('.check')
    .addEventListener('change', () => check(text), { once: true });

  el.querySelector('.remove')
    .addEventListener('click', () => remove(text), { once: true });

  return el;
}

function createDone(text) {
  return createHtmlFromTemplate(`<li>${text}</li>`);
}

//////////////////////////////////////////////////
// HTML-JS Bindings
const input = document.body.querySelector('input');
function keyDownHandler(e) {
  if (e.key === 'Enter') enter(e.target);
}
input.addEventListener('keydown', keyDownHandler);

const todosList = document.body.querySelector('#todos');
const syncTodos = forEach(createTodo, todosList);

const donesList = document.body.querySelector('#dones');
const syncDones = forEach(createDone, donesList);

const clearBtn = document.body.querySelector('#clear');
clearBtn.addEventListener('click', clear);

//////////////////////////////////////////////////
// App
let todos = [];
let dones = [];

function enter(input) {
  add(input.value);
  input.value = '';
}
function add(todo) {
  todos = [todo, ...todos];
  sync();
}
function remove(todo) {
  todos.splice(todos.indexOf(todo));
  todos = [...todos];
  sync();
}
function...