<div class="container">
  <div class="todo_list">
    <h1>ToDo list</h1>
    <div class="create_new_todo">
      <input type="text" class="name" placeholder="name">
      <input type="text" class="message" placeholder="message">
      <button class="add">ADD</button>
    </div>
    <div class="wrapper">
      <ul class="todos"></ul>
    </div>
  </div>
</div>
body {
  background-color: #ffd78a;
  font-family: sans-serif;
  -webkit-box-sizing: content-box;
  box-sizing: content-box;
}

.container {
  margin: 0 auto;
  padding-top: 50px;
}

.important {
  font-weight: bold;
  color: #a40e11;
}

.todo_list {
  max-width: 400px;
  display: block;
  margin: 0 auto 40px;
  background-color: #1ba39c;
  padding: 30px;
  border-radius: 10px;
  -webkit-box-shadow: 0 2px 10px 0 #074b83;
  box-shadow: 0 2px 10px 0 #074b83;
}

h1 {
  text-align: center;
  margin-top: 0;
  margin-bottom: 20px;
  color: #fff;
  font-size: 30px;
}

.create_new_todo {
  text-align: center;
}

input[type="text"] {
  width: 376px;
  padding: 10px;
}

button {
  margin-top: 10px;
  width: 400px;
  padding: 10px;
  cursor: pointer;
}

.todos {
  padding-left: 0;
}
.todos li {
  list-style-type: none;
}
.todos li:not(:last-child) {
  border-bottom: 1px solid #000;
}

.todos label {
  margin: 5px 0;
}

.todos fieldset {
  border: none;
  padding: 0;
}

.todos input[type='text'] {
  margin: 10px 0;
  color: white;
  background-color: black;
  border: none;
  border-radius: 5px;
}

.todos input[type='text']:focus {
  background-color: darkslategray;
}
// A template function to create the list item HTML
function createTodoHTML (todo) {
  return `
  <li id="${todo.id}">
    <fieldset disabled>
      <label>Name: 
        <input type="text" name="name" value="${todo.name}">
      </label>
      <label>Message: 
        <input type="text" name="message" value="${todo.message}">
      </label>
    </fieldset>
    <button class="remove" onClick="removeTodo('${todo.id}')">DELETE</button>
    <button class="edit" onClick="editTodo(this)">EDIT</button>
  </li>
  `
}

function uniqueId() {
  return Math.random().toString(16).slice(2);
}

// A factory function to create a new todo object
function createTodo (name, message) {
  return {
    id: uniqueId(),
    name: name,
    message: message,
    checked: false,
    important: false
  };
}

// a function to update the storage
// and update the displayed list
function updateTodoList (todoList) {
  localStorage.setItem('todo-list', JSON.stringify(todoList));
  displayTodos(todoList);
}

// as we have editTodo and removeTodo it makes
// sense to have addTodo
function addTodo (name, message) {
  const newTodo = createTodo(name, message);
  
  todoList.push(newTodo);
  updateTodoList(todoList);
}

function removeTodo (id) {
  todoList = todoList.filter(
    function(todo) {
      return todo.id !== id;
    }
  )
  
  updateTodoList(todoList);
}

function editTodo (editButton) {
  const listItem = editButton.parentElement;
  const fieldset = listItem.querySelector('fieldset');
  const editing = editButton.textContent === 'EDIT';
  
  // fieldsets have an elements array that allow
  // you to access the inputs by input name
  const name = fieldset.elements.name;
  const message = fieldset.elements.message;
  
  if (editing) {
    editButton.textContent = 'SAVE';
    fieldset.disabled = false; // now we can edit the inputs
    name.focus(); // move cursor to name
    return; // exit here
  }
  
  // otherwise the button clicked is 'SAVE'
  editButton.textContent = 'EDIT';
  fieldset.disabled = true;
  
  // Iterate through the todos
  todoList = todoList.map(function(todo) {
    // if the todo id matches the list item id then ammend
    if (todo.id === listItem.id) {
      todo.name = name.value;
      todo.message = message.value;
    }
    
    return todo;
  })
  
  updateTodoList(todoList);
}

function displayTodos (todoList = []) {
  const todos = document.querySelector('.todos');
  const messages = todoList.map(createTodoHTML);

  todos.innerHTML = messages.join('\n');
}

// A generic function to reset fields
// Using the rest operator e.g ...fields 
// to convert all arguments to an array
// e.g. resetFields(name, message) → [name, message]
function resetFields (...fields) {
  fields.forEach(function(field) {
    field.value = "";
  })
}

// Moved addButton here. Saves having to scroll to the top of the code
// to find out what addButton is
const addButton = document.querySelector('.add');

addButton.addEventListener('click', function(event) {
  // event.target is the button, parent is the wrapping div
  const parent = event.target.parentElement;
  // parent can be used as the root to search from
  const message = parent.querySelector('.message');
  const name = parent.querySelector('.name');
  
  if (!name.value || !message.value) return;
  
  addTodo(name.value, message.value);
  resetFields(name, message);
});

let todoList = [];

if (localStorage.getItem('todo-list')) {
   todoList = JSON.parse(localStorage.getItem('todo-list'));
   displayTodos(todoList);
}

// localStorage.removeItem('todo-list')
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.