Skip to content

Commit 46da1fc

Browse files
author
vanntile
committed
Day 15
1 parent e6b6d94 commit 46da1fc

8 files changed

Lines changed: 182 additions & 117 deletions

File tree

15 - LocalStorage/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Local Storage
2+
3+
This tutorial shows how to use local storage to keep user data refresh-safe. This could be the first step for an `offline web application` syncing.
4+
5+
![Local Storage](../assets/img/15%20-%20LocalStorage.png?raw=true "Presentation Image")
6+
7+
## My contribution
8+
9+
As Wes challenged us, I have added buttons for clearing the list, checking and unchecking all the items.
10+
11+
## Learning notes
12+
13+
Some concepts taught:
14+
15+
- `Window.localStorage` property from the `Web Storage API`
16+
- ternary operators in `ES6 template literals`
17+
- parent-children `event delegation`
18+
- `JSON.stringify()`
19+
- `submit` event for forms
20+
21+
```javascript
22+
// generating the HTML list elemnts
23+
// we use a ternary operation for having the checked attribute checked
24+
const populateList = function (plates = [], platesList) {
25+
platesList.innerHTML = plates.map((plate, idx) => {
26+
return `
27+
<li>
28+
<input type="checkbox" data-index=${idx} id="item${idx}" ${plate.done ? 'checked' : ''}/>
29+
<label for="item${idx}">${plate.text}</label>
30+
</li>
31+
`
32+
})
33+
.join('')
34+
}
35+
36+
// saving data as 'items' to the localStorage map
37+
localStorage.setItem('items', JSON.stringify(items))
38+
39+
// clearing a const array
40+
items.splice(0, items.length)
41+
```

15 - LocalStorage/index-FINISHED.html

Lines changed: 0 additions & 77 deletions
This file was deleted.

15 - LocalStorage/index-START.html

Lines changed: 0 additions & 38 deletions
This file was deleted.

15 - LocalStorage/index.html

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>LocalStorage</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
10+
<body>
11+
<!--
12+
Fish SVG Cred:
13+
https://thenounproject.com/search/?q=fish&i=589236
14+
-->
15+
16+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
17+
<g>
18+
<path d="M495.9,425.3H16.1c-5.2,0-10.1,2.9-12.5,7.6c-2.4,4.7-2.1,10.3,0.9,14.6l39,56.4c2.6,3.8,7,6.1,11.6,6.1h401.7 c4.6,0,9-2.3,11.6-6.1l39-56.4c3-4.3,3.3-9.9,0.9-14.6C506,428.2,501.1,425.3,495.9,425.3z M449.4,481.8H62.6L43,453.6H469 L449.4,481.8z" />
19+
<path d="M158.3,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1c-7.8,0-14.1,6.3-14.1,14.1v64.5 C144.2,115.7,150.5,122,158.3,122z" />
20+
<path d="M245.1,94.7c7.8,0,14.1-6.3,14.1-14.1V16.1c0-7.8-6.3-14.1-14.1-14.1C237.3,2,231,8.3,231,16.1v64.5 C231,88.4,237.3,94.7,245.1,94.7z" />
21+
<path d="M331.9,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1s-14.1,6.3-14.1,14.1v64.5 C317.8,115.7,324.1,122,331.9,122z" />
22+
<path d="M9.6,385.2c5.3,2.8,11.8,1.9,16.2-2.2l50.6-47.7c56.7,46.5,126.6,71.9,198.3,71.9c0,0,0,0,0,0 c87.5,0,169.7-36.6,231.4-103.2c5-5.4,5-13.8,0-19.2c-61.8-66.5-144-103.2-231.4-103.2c-72,0-142.2,25.6-199,72.5l-50-47.1 c-4.4-4.1-10.9-5-16.2-2.2c-5.3,2.8-8.3,8.7-7.4,14.6l11.6,75L2.2,370.6C1.3,376.5,4.2,382.4,9.6,385.2z M380.9,230.8 c34.9,14.3,67.2,35.7,95.3,63.6c-10.1,10-20.8,19.2-31.9,27.5c-22.4-3.3-29.6-8.8-30.7-9.7c-4-5.7-11.8-7.7-18.1-4.4 c-6.9,3.6-9.5,12.2-5.9,19.1c1.9,3.5,7.3,10.3,22.4,16c-10.1,5.7-20.5,10.7-31.1,15.1C352.4,320.2,352.4,268.6,380.9,230.8z M36.3,255.6l29.4,27.7c5.3,5,13.6,5.1,19.1,0.3c53.2-47.6,120.7-73.7,190-73.7c26.9,0,53.2,3.9,78.5,11.3 c-29.3,44.6-29.3,102,0,146.6c-25.3,7.4-51.6,11.3-78.5,11.3c-69,0-136.3-26-189.4-73.2c-2.7-2.4-13.4-6.3-19.1,0.3l-30.1,28.3 l5.7-40C42.2,293,36.3,255.6,36.3,255.6z" />
23+
<circle cx="398.8" cy="273.8" r="14.1" />
24+
</g>
25+
</svg>
26+
27+
<div class="wrapper">
28+
<h2>LOCAL TAPAS</h2>
29+
<p></p>
30+
<ul class="plates">
31+
<li>Loading Tapas...</li>
32+
</ul>
33+
<form class="add-items">
34+
<input type="text" name="item" placeholder="Item Name" required>
35+
<input type="submit" value="+ Add Item">
36+
<div class="buttons">
37+
<span class="btn clear-items">Clear items</span>
38+
<span class="btn clear-selection">Clear selection</span>
39+
<span class="btn select-all">Select all</span>
40+
</div>
41+
</form>
42+
</div>
43+
44+
<script src="script.js"></script>
45+
46+
</body>
47+
48+
</html>

15 - LocalStorage/script.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const addItems = document.querySelector('.add-items')
2+
const itemsList = document.querySelector('.plates')
3+
const items = JSON.parse(localStorage.getItem('items')) || []
4+
const clearItemsBtn = document.querySelector('.clear-items')
5+
const clearSelectionBtn = document.querySelector('.clear-selection')
6+
const selectAllBtn = document.querySelector('.select-all')
7+
8+
/*
9+
* We want a reusable function
10+
*/
11+
const populateList = function (plates = [], platesList) {
12+
platesList.innerHTML = plates.map((plate, idx) => {
13+
return `
14+
<li>
15+
<input type="checkbox" data-index=${idx} id="item${idx}" ${plate.done ? 'checked' : ''}/>
16+
<label for="item${idx}">${plate.text}</label>
17+
</li>
18+
`
19+
})
20+
.join('')
21+
}
22+
23+
const addItem = function (e) {
24+
e.preventDefault()
25+
26+
const text = (this.querySelector('[name=item]'))
27+
.value
28+
const item = {
29+
text,
30+
done: false
31+
}
32+
33+
items.push(item)
34+
populateList(items, itemsList)
35+
localStorage.setItem('items', JSON.stringify(items))
36+
37+
this.reset()
38+
}
39+
40+
const toggleDone = function (e) {
41+
if (!e.target.matches('input')) return
42+
43+
const idx = e.target.dataset.index
44+
items[idx].done = !items[idx].done
45+
46+
localStorage.setItem('items', JSON.stringify(items))
47+
populateList(items, itemsList)
48+
}
49+
50+
addItems.addEventListener('submit', addItem)
51+
52+
// Get previous items
53+
populateList(items, itemsList)
54+
55+
itemsList.addEventListener('click', toggleDone)
56+
57+
clearItemsBtn.addEventListener('click', () => {
58+
items.splice(0, items.length)
59+
populateList(items, itemsList)
60+
localStorage.setItem('items', JSON.stringify(items))
61+
})
62+
63+
clearSelectionBtn.addEventListener('click', () => {
64+
items.forEach(i => i.done = false)
65+
populateList(items, itemsList)
66+
localStorage.setItem('items', JSON.stringify(items))
67+
})
68+
69+
selectAllBtn.addEventListener('click', () => {
70+
items.forEach(i => i.done = true)
71+
populateList(items, itemsList)
72+
localStorage.setItem('items', JSON.stringify(items))
73+
})

15 - LocalStorage/style.css

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ html {
1111
}
1212

1313
*, *:before, *:after {
14-
box-sizing: inherit;
14+
box-sizing: inherit;
1515
}
1616

1717
svg {
@@ -76,4 +76,21 @@ h2 {
7676
padding: 10px;
7777
outline: 0;
7878
border: 1px solid rgba(0,0,0,0.1);
79+
max-width: 200px;
80+
}
81+
82+
.buttons {
83+
margin: 12px 0;
84+
}
85+
86+
.btn {
87+
display: inline-block;
88+
padding: 6px;
89+
border: 1px solid rgba(0,0,0,0.1);
90+
font-size: 15px;
91+
}
92+
93+
.btn:hover {
94+
cursor: pointer;
95+
background: rgba(0,0,0,0.25)
7996
}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ Check the course at [https://JavaScript30.com](https://JavaScript30.com)
3030
12. [x] [Key Sequence Detection](https://vanntile.github.io/JavaScript30/12%20-%20Key%20Sequence%20Detection)
3131
13. [x] [Slide in on Scroll](https://vanntile.github.io/JavaScript30/13%20-%20Slide%20in%20on%20Scroll)
3232
14. [x] [JavaScript References vs. Copying](https://vanntile.github.io/JavaScript30/14%20-%20JavaScript%20References%20VS%20Copying)
33-
15. [ ] LocalStorage
33+
15. [x] [LocalStorage](https://vanntile.github.io/JavaScript30/15%20-%20LocalStorage) and my
34+
[notes](./15%20-%20LocalStorage)
3435
16. [ ] Mouse Move Shadow
3536
17. [ ] Sort Without Articles
3637
18. [ ] Adding Up Times with Reduce

assets/img/15 - LocalStorage.png

2.46 MB
Loading

0 commit comments

Comments
 (0)