adding instructions for addTodo. fixes #28

This commit is contained in:
Micah Godbolt 2019-02-27 19:34:29 -08:00
Родитель fdceb93839
Коммит cc260afce1
1 изменённых файлов: 70 добавлений и 10 удалений

Просмотреть файл

@ -4,9 +4,9 @@ Now that we a UI that looks like a todo app, we need to add functionality to mak
> Keep an eye on how often user actions directly modify the HTML on the page. You'll see this number drop to zero when we start using React.
## Demo
## What we're starting with
This demo starts off with a few elements already in place. Let's walk through what's already here.
This demo starts off with a few functions already in place. Let's walk through what's already here.
- **clearInput()** - This is a generic, reusable function that takes in a `selector` parameter, finds the first matching element, and sets the element's value to an empty string. This direct modification is called a side effect.
- **getTodoText()** - This is a quick helper function that returns the value inside of our textfield. Notice how some functions return values and how you can set that return to a variable.
@ -17,16 +17,76 @@ This demo starts off with a few elements already in place. Let's walk through wh
4. Get all of the todos with [querySelectAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll), and then loop through them.
5. Set the `hidden` property of each todo based on the filter/state combination.
### Writing addTodo Function
## Writing `addTodo` Function
1. `todo` is set to equal the first todo item.
2. `newTodo` is a clone of todo. Passing true means it is a deep clone, so we get the todo's children as well. Cloning does not duplicate the DOM node. We'll need to insert it in step 4.
> Note that this approach is very fragile, as it requires a todo node to always be present on the page.
3. We set the innerText of the `<span class='title'>` to the value returned from getTodoText.
> Note that if we left off the `()` we'd actually be assigning innerText to the 'function' instead of the function return.
4. Insert our new todo into the todo's parent (the `ul`), before our reference todo. [insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore)
We start writing all functions with the `function` keyword and the name of our function. Functions can take parameters, but in this case we don't need to pass any through, so we follow the function name with an empty `()`. Everything we want this function to do will then be placed in a set of brackets `{}`.
### Triggering functions from click events
```js
function addTodo() {}
```
### Creating a Todo Clone
The first thing we need to do in this function is create a `newTodo` wish is a clone of an existing Todo.
```js
function addTodo() {
const todo = document.querySelector('.todo');
const newTodo = todo.cloneNode(true);
}
```
Passing true to our `cloneNode` means it is a deep clone, so we get a copy of the todo's children as well.
> Note that this approach is very fragile, as it requires a todo node to always be present on the page.
### Updating the newTodos's text
With this clone created, we need to update the `innerText` of the node with our todo text, which is returned from `getTodoText()`.
```js
function addTodo() {
const todo = document.querySelector('.todo');
const newTodo = todo.cloneNode(true);
newTodo.querySelector('.title').innerText = getTodoText();
}
```
We can target a child node by calling `querySelector` again and asking for the child with the `.child` class.
> Note that if we left off the `()` we'd actually be assigning innerText to the 'function' instead of the function return.
### Placing the newTodo into the list of todos
Making a clone only stores the clone inside of our variable. If we want to place it back into the DOM, we'll need to insert it manually. For that we can use [insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore).
This function actually needs to target the parent element, which we can get by calling `todo.parentElement` and passing parameters of `(elementToInsert, elementToInsertBefore)`.
```js
function addTodo() {
const todo = document.querySelector('.todo');
const newTodo = todo.cloneNode(true);
newTodo.querySelector('.title').innerText = getTodoText();
todo.parentElement.insertBefore(newTodo, todo);
}
```
### Cleanup
Now that our todo has been inserted into the DOM, we can clear the text input and call `updateRemaining()`.
```js
function addTodo() {
...
clearInput('.textfield');
updateRemaining();
}
```
> Note how often we have to reach into the DOM to find nodes, manipulate content, insert back into the DOM and manually change the values in inputs. This is the error prone manipulation that React helps us avoid.
## Triggering functions from click events
Now that we have a working `addTodo` function, we need a way to trigger it when the user is ready. This can be done in two ways.