Nitish Dayal, Software & Applications Developer - Contact
Last Commit Date: May 12, 2017
The web page simulates a restaurant's menu. The user should be able to
add new dishes to the list using the form HTML element without having
to refresh the page. Currently, when the user submits a dish into the form,
the page reloads (as this is the default action of a submit event)
and the list remains empty. Write the necessary JavaScript code to bring
functionality to the page.
In the script tag, we're provided 3 const variables: one referencing
the form element (addItems), one referencing the unordered list
element (itemsList), and an empty array (items). This one is lengthy,
so let's get started with the necessary steps:
Steps:
-
Attach an event handler to the
formelement that will listen for the 'submit' event and call upon an event handler (to be defined, for now simply provide the name that you'll give to the function).addItems.addEventListener('submit', addItem)
-
Define the event handler as a function which accepts an
eventas a parameter and will prevent the default behavior of that event:
const addItem = (e) => {
e.preventDefault()
}- In the function body, declare a
constand define it as the value of theinputelement and declare anotherconstas an object with the properties 'text' (set to theinputvalue) and 'done' (set to thebooleanvalue false):
/* In function body */
const text = (e.target.querySelector('[name="item"]').value(),
item = {
text,
done: false
}- Push the newly created
itemobject into theitemsarray & store theitemsarray in localStorage. Values saved in localStorage are associated with akeyand can only be String values, so we'll convert theitemsarray into a JSON string. Reset the form:
/* In function body */
items.push(item)
localStorage.setItem('dishes', JSON.stringify(items))
e.target.reset()- NOTE: Submit some values into the form.In your browser's dev tools,
navigate to the
Applicationtab and open up 'Local Storage > file://'. You should see these items stored under the key 'dishes' as a string representation of theitemsarray.
- Declare a function that will be responsible for generating the necessary
HTML to display each item in the
itemsarray as a list item with a clickable checkbox.
const populateList = (items, itemsList) => {
// If the parameter `items` isn't an array, go no further
if (!(items instanceof Array)) return false
// Update the 'itemsList' HTML to contain each item stored in the `items` array
itemsList.innerHTML = items.map((item, i) => {
return `
<li>
<input type="checkbox" data-index=${i} id="item${i}" ${item.done ? 'checked' : ''} />
<label for="item${i}">${item.text}</label>
</li>
`
}).join('')
}- Go back to the event handler function body and call the newly defined function after
we've pushed an item object into the
itemsarray:
/* Right after 'items.push(item)' */
populateList(items, itemsList)- At the very top of your JavaScript code, change
const itemsso that it is either an array generated from parsing through the items currently in localStorage, or if there is nothing in localStorage, an empty array.
const addItems = document.querySelector('.add-items'),
itemsList = document.querySelector('.plates'),
items = JSON.parse(localStorage.getItem('dishes')) || []; // This is the line we're changing- We need to call the
populateListmethod as soon as the document loads so that we can generate the menu items if there is something in the localStorage:
document.onload = populateList(items, itemsList)- Currently, the 'done' property of each item element is never updated, so the status
of the checkbox does not carry across page reloads. Attach an event handler to the
itemsListthat will call an event handler function on each 'click' event.
itemsList.addEventListener('click', toggleDone)- Define this event handler function so that it accepts an event as a parameter and,
if the target of the event contains the text 'input' anywhere, we'll toggle
the
donevalue of correct object in theitemsarray and update the localStorage to reflect that change:
const toggleDone = (e) => {
if (!e.target.matches('input')) return;
const element = e.target,
idx = element.dataset.index;
items[idx].done = !items[idx].done
localStorage.setItem('dishes', JSON.stringify(items))
}Guess what, friends? We're already HALF WAY THEREEEEEEEE!!!!