Skip to content

Commit

Permalink
Added notes and solution for Project 15 - Local Storage and Event Del…
Browse files Browse the repository at this point in the history
…egation
  • Loading branch information
lisaychuang committed May 9, 2018
1 parent fe01ccb commit cbdc6d7
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 3 deletions.
99 changes: 97 additions & 2 deletions 15 - LocalStorage/index-projectnotes.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,115 @@ <h2>LOCAL TAPAS</h2>
<ul class="plates">
<li>Loading Tapas...</li>
</ul>

<!--Form to add items -->
<form class="add-items">
<input type="text" name="item" placeholder="Item Name" required>
<input type="submit" value="+ Add Item">

<!-- STRETCH GOAL: add buttons for: Clear all, check all, uncheck all -->
<input type="button" name='resetBtn' value="Reset Form">
<input type="button" name='checkAllBtn' value="Check All Items">
<input type="button" name='uncheckAllBtn' value="Uncheck All Items">
</form>
</div>

<script>
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const items = [];

</script>
// on page load, either get cached items list or display empty form
const items = JSON.parse(localStorage.getItem('items')) || [];

// addItem will create item obj, display on form, and add to localStorage
function addItem(e){
e.preventDefault(); // prevent page from reloading
const inputText = (this.querySelector('[name=item]')).value; // get user input

const item = {
text: inputText,
done: false
}

items.push(item); // add item to items array
populateList(items, itemsList); // display current items in form

// add items to localStorage to cache data
localStorage.setItem('items', JSON.stringify(items));

this.reset(); // clear form upon submit
};

// populateList will display list on page
function populateList(plates = [], platesList){
platesList.innerHTML = plates.map((plate, index) => {
return `
<li>
<input type="checkbox" data-index=${index} id="item${index}"
${plate.done ? 'checked' : ''} />
<label for="item${index}">${plate.text}</label>
</li>
`;
}).join(''); // converts array into a string
}

// event delegation, attaching listener to high level element
// persist state of toggled items
function toggleDone(e){
if (!e.target.matches('input')) return; // skip this unless target = input
const element = e.target;
const index = element.dataset.index;

items[index].done = !items[index].done; // toggle done = true || false

// store state of checkbox in local storage
localStorage.setItem('items', JSON.stringify(items));
// update visilibity on page
populateList(items, itemsList);
};

// add event listener to the submit button
addItems.addEventListener('submit', addItem);

// delegate event to itemsList instead of individual item checkbox
itemsList.addEventListener('click', toggleDone);

// display list of current items
populateList(items, itemsList);


// STRETCH GOAL: Reset form
const resetBtn = document.querySelector('.add-items [name=resetBtn]');

resetBtn.addEventListener('click', () => {
items.length = 0;
localStorage.clear();
populateList(items, itemsList);
});

// STRETCH GOAL: Check all items
const checkAllBtn = document.querySelector('.add-items [name=checkAllBtn]');

checkAllBtn.addEventListener('click', () => {
items.map(item => {
item.done = true;
});
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);
});

// STRETCH GOAL: Uncheck all items
const uncheckAllBtn = document.querySelector('.add-items [name=uncheckAllBtn]');

uncheckAllBtn.addEventListener('click', () => {
items.map(item => {
item.done = false;
});
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);
});

</script>
</body>

</html>
2 changes: 1 addition & 1 deletion 15 - LocalStorage/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
}

.plates input:checked + label:before {
content: '🌮';
content: '🍛';
}

.add-items {
Expand Down
31 changes: 31 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,3 +802,34 @@ Wes showed us that we can create a `deep clone` with:

This is also the suggested solution on [MDN guides](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign), and a great [StackOverflow thread](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) discussed performance for various methods.

## Project 15: LocalStorage & Event Delegation

### [Storage](https://developer.mozilla.org/en-US/docs/Web/API/Storage)
The `Storage` interface of the Web Storage API provides access to the `sessionStorage` or `localStorage` for a particular domain, allowing you to for example add, modify or delete stored data items.

[`LocalStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage) allows you to access a `Storage` object for the current origin, the stored data is saved across browser sessions with no expiration set.

#### [`Storage.getItem()`](https://developer.mozilla.org/en-US/docs/Web/API/Storage/getItem)
Syntax: `storage.getItem(keyName);`

When passed a key name, the `getItem()` method will return that key's value.

#### [`Storage.setItem()`](https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem)
Syntax: `storage.setItem(keyName, keyValue);`

when passed a key name and value, the `setItem()` method will add that key to the storage, or update that key's value if it already exists.

#### [`Storage.clear()`](https://developer.mozilla.org/en-US/docs/Web/API/Storage/clear)
When invoked, the `clear()` method will empty all keys out of the storage.

### [Event.preventDefault()](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
The `Event` interface's `preventDefault()` method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be. The event continues to propagate as usual, unless one of its event listeners calls `stopPropagation()` or `stopImmediatePropagation()`, either of which terminates propagation at once.

In this project, we used this method to stop the page from refreshing upon clicking the form `submit` button.

### [Event delegation](https://davidwalsh.name/event-delegate)

`Event delegation` allows us to avoid adding event listeners to specific nodes (e.g. `<li>` items once created).

Instead, the event listener is added to one parent (e.g. `ul`). That event listener analyzes bubbled events to find a match on child elements.

0 comments on commit cbdc6d7

Please sign in to comment.