Skip to content

Instantly share code, notes, and snippets.

Created July 5, 2017 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/c812eee1b39b6d6f6daec80bd2f2a99f to your computer and use it in GitHub Desktop.
Save anonymous/c812eee1b39b6d6f6daec80bd2f2a99f to your computer and use it in GitHub Desktop.
null created by dtstanley - https://repl.it/HzSS/250
* {
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serif;
}
button, input[type="text"] {
padding: 5px;
}
button:hover {
cursor: pointer;
}
.hidden {
display: none;
}
#shopping-list-item {
width: 250px;
}
.container {
max-width: 600px;
margin: 0 auto;
}
.shopping-list {
list-style: none;
padding-left: 0;
}
.shopping-list > li {
margin-bottom: 20px;
border: 1px solid grey;
padding: 20px;
}
.shopping-item {
display: block;
color: grey;
font-style: italic;
font-size: 20px;
margin-bottom: 15px;
}
.shopping-item__checked {
text-decoration: line-through;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Shopping List</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="container">
<h1>Shopping List</h1>
<form id="js-shopping-list-form">
<label for="shopping-list-entry">Add an item</label>
<input type="text" name="shopping-list-entry" class="js-shopping-list-entry" placeholder="e.g., broccoli">
<button type="submit">Add item</button>
</form>
<ul class="shopping-list js-shopping-list">
</ul>
</div>
</body>
<script src="//code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="index.js"></script>
</html>
const STORE = [
{name: "apples", checked: false},
{name: "oranges", checked: false},
{name: "milk", checked: true},
{name: "bread", checked: false}
];
const NEW_ITEM_FORM_INPUT_CLASS = ".js-shopping-list-entry";
const SHOPPING_LIST_ELEMENT_CLASS = ".js-shopping-list";
const ITEM_CHECKED_TARGET_IDENTIFIER = "js-shopping-item";
const ITEM_CHECKED_CLASS_NAME = "shopping-item__checked";
const ITEM_INDEX_ATTRIBUTE = "data-item-index";
const ITEM_INDEX_ELEMENT_IDENTIFIER = "js-item-index-element";
const NEW_ITEM_FORM_IDENTIFIER = '#js-shopping-list-form';
const ITEM_CHECKED_BUTTON_IDENTIFIER = "js-item-toggle";
function generateItemElement(item, itemIndex) {
return `
<li class="${ITEM_INDEX_ELEMENT_IDENTIFIER}" ${ITEM_INDEX_ATTRIBUTE}="${itemIndex}">
<span class="shopping-item ${ITEM_CHECKED_TARGET_IDENTIFIER} ${item.checked ? ITEM_CHECKED_CLASS_NAME : ''}">${item.name}</span>
<div class="shopping-item-controls">
<button class="shopping-item-toggle ${ITEM_CHECKED_BUTTON_IDENTIFIER}">
<span class="button-label">check</span>
</button>
<button class="shopping-item-delete js-item-delete">
<span class="button-label">delete</span>
</button>
</div>
</li>`;
}
function generateShoppingItemsString(shoppingList) {
console.log("Generating shopping list element");
const items = shoppingList.map((item, index) => generateItemElement(item, index));
return items.join();
}
function renderShoppingList() {
// render the shopping list in the DOM
console.log('`renderShoppingList` ran');
const shoppingListItemsString = generateShoppingItemsString(STORE);
// insert that HTML into the DOM
$(SHOPPING_LIST_ELEMENT_CLASS).html(shoppingListItemsString);
}
function addItemToShoppingList(itemName) {
console.log(`Adding "${itemName}" to shopping list`);
STORE.push({name: itemName, checked: false});
}
function handleNewItemSubmit() {
$(NEW_ITEM_FORM_IDENTIFIER).submit(function(event) {
event.preventDefault();
console.log('`handleNewItemSubmit` ran');
const newItemElement = $(NEW_ITEM_FORM_INPUT_CLASS);
const newItemName = newItemElement.val();
newItemElement.val('');
addItemToShoppingList(newItemName);
renderShoppingList();
});
}
function toggleCheckedForListItem(itemIndex) {
console.log("Toggling checked property for item at index " + itemIndex);
STORE[itemIndex].checked = !STORE[itemIndex].checked;
}
function getItemIndexFromElement(item) {
const itemIndexString = $(item)
.closest(`.${ITEM_INDEX_ELEMENT_IDENTIFIER}`)
.attr(ITEM_INDEX_ATTRIBUTE);
return parseInt(itemIndexString, 10);
}
function handleItemCheckClicked() {
$(SHOPPING_LIST_ELEMENT_CLASS).on('click', `.${ITEM_CHECKED_BUTTON_IDENTIFIER}`, event => {
console.log('`handleItemCheckClicked` ran');
const itemIndex = getItemIndexFromElement(event.currentTarget);
toggleCheckedForListItem(itemIndex);
renderShoppingList();
});
}
function handleDeleteItemClicked() {
// Listen for when users want to delete an item and
// delete it
$(SHOPPING_LIST_ELEMENT_CLASS).on('click', '.shopping-item-delete', '.js-item-delete', function(event){
$(this).closest('li').remove();
});
console.log('`handleDeleteItemClicked` ran');
}
function handleShoppingList() {
renderShoppingList();
handleNewItemSubmit();
handleItemCheckClicked();
handleDeleteItemClicked();
}
$(handleShoppingList);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment