08: Set Edit Mode
Let's work edit title for each todo. Firstly, change edit mode by double click.
"To save edit results" and "To exit edit mode" are explained in the next section.
Please check below two points.
- Cannot return to a view mode after switching to edit mode.
- After double-clicking, the edit input field does not get focus automatically.
- Add editingTodoIndex with default value as -1 into x-state.
- Add editTodo invocation to controller element by x-invocations directive.
- Add index variable name into x-each directive for editing each todo item.
- Add class binding directive to apply CSS class of editing item design to the todo item.
- Add event listener to call editTodo invocation on double click at todo title.
- Bind value to <input> of editing todo by x-bind:value. This value does not need as reactive. Only receiving value from controller.
<body> <section class="todoapp" x-state="{ todos: [], editingTodoIndex: -1, }" x-invocations="{ addTodo (_, payload, meta) {<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1" > <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/todomvc-app-css@2.1.2/index.css" > <script src="https://x-ninja.org/assets/js/o_o.js"></script> <script src="https://x-ninja.org/assets/js/flux._.js"></script> <title>TODOs @x-ninja</title> </head>}, editTodo (_, payload, meta) { const todo = this.todos[payload.index] if (!todo) { return } this.beforeEditCache = todo.title this.editingTodoIndex = payload.index }, }" ::>const newTodo = payload.newTodo.trim()
if (!newTodo) { return } this.todos.push({ title: newTodo, completed: false })<section class="main"><header class="header">
<h1>todos</h1> <input class="new-todo" autofocus autocomplete="off" placeholder="What needs to be done?" @change="addTodo({newTodo: launcher$.value})" x-callbacks="{ change (_) { _.$.value = '' } }" > </header><ul class="todo-list" x-each="todo, index in todos" > <li class="todo" :class="{ completed: todo.completed, editing: index === editingTodoIndex, }" > <div class="view"><input id="toggle-all" class="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label><label @dblclick="editTodo({index})">{{ todo.title }}</label> <button class="destroy"></button> </div> <input class="edit" :value="todo.title" > </li> </ul> </section><input class="toggle"
type="checkbox" x-model="todo.completed" ></section> </body> </html><footer class="footer">
<span class="todo-count"> <strong>3</strong> items left </span> <ul class="filters"> <li><a href="#/all" class="selected">All</a></li> <li><a href="#/active">Active</a></li> <li><a href="#/completed">Completed</a></li> </ul> <button class="clear-completed"> Clear completed </button> </footer>