Skip to content

Commit ccd4bce

Browse files
authored
Complete challenge 15 readme
1 parent 154517e commit ccd4bce

File tree

1 file changed

+132
-2
lines changed

1 file changed

+132
-2
lines changed

exercises/15 - LocalStorage/README.md

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,138 @@
22
Nitish Dayal, Software & Applications Developer - [Contact](http://nitishdayal.me)
33
Last Commit Date: Dec 19, 2016
44

5-
TODO
5+
The web page simulates a restaurant's menu. The user should be able to
6+
add new dishes to the list using the `form` HTML element without having
7+
to refresh the page. Currently, when the user submits a dish into the form,
8+
the page reloads (as this is the _default action_ of a `submit` event)
9+
and the list remains empty. Write the necessary JavaScript code to bring
10+
functionality to the page.
611

712
## Guide
813

9-
TODO
14+
In the `script` tag, we're provided 3 `const` variables: one referencing
15+
the _`form` element_ (`addItems`), one referencing the _`unordered list`
16+
element_ (`itemsList`), and an empty array (`items`). This one is lengthy,
17+
so let's get started with the necessary steps:
18+
19+
**Steps:**
20+
21+
1. Attach an event handler to the `form` element that will listen for
22+
the 'submit' event and call upon an _event handler_ (to be defined, for
23+
now simply provide the name that you'll give to the function).
24+
25+
```JavaScript
26+
addItems.addEventListener('submit', addItem)
27+
```
28+
29+
2. Define the _event handler_ as a function which accepts an `event` as
30+
a parameter and will prevent the default behavior of that event:
31+
32+
```JavaScript
33+
const addItem = (e) => {
34+
e.preventDefault()
35+
}
36+
```
37+
38+
3. In the function body, declare a `const` and define it as the _value
39+
of the `input` element_ and declare another `const` as an _object_
40+
with the properties 'text' (set to the `input` value) and 'done' (set
41+
to the `boolean` value false):
42+
43+
```JavaScript
44+
/* In function body */
45+
const text = (e.target.querySelector('[name="item"]').value(),
46+
item = {
47+
text,
48+
done: false
49+
}
50+
```
51+
52+
4. Push the newly created _`item` object_ into the `items` array &
53+
store the `items` array in _localStorage_. Values saved in _localStorage_
54+
are associated with a `key` and can only be String values, so we'll convert
55+
the `items` array into a _JSON string_. Reset the form:
56+
57+
```JavaScript
58+
/* In function body */
59+
items.push(item)
60+
localStorage.setItem('dishes', JSON.stringify(items))
61+
e.target.reset()
62+
```
63+
- **NOTE:** Submit some values into the form.In your browser's dev tools,
64+
navigate to the `Application` tab and open up 'Local Storage > file://'.
65+
You should see these items stored under the key 'dishes' as a string
66+
representation of the `items` array.
67+
68+
5. Declare a _function_ that will be responsible for generating the necessary
69+
HTML to display each item in the `items` array as a list item with a clickable
70+
checkbox.
71+
72+
```JavaScript
73+
const populateList = (items, itemsList) => {
74+
// If the parameter `items` isn't an array, go no further
75+
if (!(items instanceof Array)) return false
76+
77+
// Update the 'itemsList' HTML to contain each item stored in the `items` array
78+
itemsList.innerHTML = items.map((item, i) => {
79+
return `
80+
<li>
81+
<input type="checkbox" data-index=${i} id="item${i}" ${item.done ? 'checked' : ''} />
82+
<label for="item${i}">${item.text}</label>
83+
</li>
84+
`
85+
}).join('')
86+
}
87+
```
88+
89+
6. Go back to the _event handler_ function body and call the newly defined function **after**
90+
we've pushed an _item object_ into the `items` array:
91+
92+
```JavaScript
93+
/* Right after 'items.push(item)' */
94+
populateList(items, itemsList)
95+
```
96+
97+
7. At the very top of your JavaScript code, change `const items` so that it is **either**
98+
an array generated from parsing through the items currently in localStorage, or if there is
99+
nothing in localStorage, an empty array.
100+
101+
```JavaScript
102+
const addItems = document.querySelector('.add-items'),
103+
itemsList = document.querySelector('.plates'),
104+
items = JSON.parse(localStorage.getItem('dishes')) || []; // This is the line we're changing
105+
```
106+
107+
8. We need to call the `populateList` method as soon as the document loads
108+
so that we can generate the menu items if there is something in the localStorage:
109+
110+
```JavaScript
111+
document.onload = populateList(items, itemsList)
112+
```
113+
114+
9. Currently, the 'done' property of each _item_ element is never updated, so the status
115+
of the checkbox does not carry across page reloads. Attach an event handler to the `itemsList`
116+
that will call an _event handler_ function on each 'click' event.
117+
118+
```JavaScript
119+
itemsList.addEventListener('click', toggleDone)
120+
```
121+
122+
10. Define this _event handler_ function so that it accepts an _event_ as a parameter and,
123+
if the target of the event contains the text 'input' anywhere, we'll toggle
124+
the `done` value of correct object in the `items` array and update the localStorage
125+
to reflect that change:
126+
127+
```JavaScript
128+
const toggleDone = (e) => {
129+
if (!e.target.matches('input')) return;
130+
131+
const element = e.target,
132+
idx = element.dataset.index;
133+
134+
items[idx].done = !items[idx].done
135+
localStorage.setItem('dishes', JSON.stringify(items))
136+
}
137+
```
138+
139+
Guess what, friends? We're already **HALF WAY THEREEEEEEEE!!!!**

0 commit comments

Comments
 (0)