From 7dd2465032dc7cc014da7774b1f1c9872961ab87 Mon Sep 17 00:00:00 2001 From: Ian Adam Naval Date: Thu, 22 May 2014 04:37:30 -0700 Subject: [PATCH] Initial commit --- css/style.css | 54 ++++++++++ index.html | 22 +++++ js/index.js | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 css/style.css create mode 100644 index.html create mode 100644 js/index.js diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..be2567f --- /dev/null +++ b/css/style.css @@ -0,0 +1,54 @@ +html, body { + margin: 0; + padding: 0; +} + +body { + background-color: #333; +} + +#container { + width: 666px; /* muahaha */ + height: 100%; + margin: 0 auto; + padding: 32px; + background-color: #555; + + color: #eee; + font-family: "Ubuntu", serif; +} + +input[type="text"] { + color: #fff; + font-family: "Ubuntu", serif; + background-color: #777; + border: 0; + padding: 4px; +} + +.item input, .item span, .item label { + margin: 0 4px; +} + +#items { + list-style: none; + margin: 0; + padding: 0; +} + +.item { + padding: 8px; +} + +.item-focused { + background-color: #888; +} + +#add { + display: block; + margin: 8px 0 16px 12px; +} + +#tax, .price { + width: 48px; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..f191e4d --- /dev/null +++ b/index.html @@ -0,0 +1,22 @@ + + + + + Grocery Splitter + + + +
+

Grocery Splitter

+ + + Tax: % +
+

The bill's total was $0.00.

+
    +
+
+
+ + + diff --git a/js/index.js b/js/index.js new file mode 100644 index 0000000..668dc82 --- /dev/null +++ b/js/index.js @@ -0,0 +1,267 @@ +var shopperNames = ['Cal', 'Ian', 'Olivia']; +var KEYCODE_ENTER = 13; +var KEYCODE_DELETE = 8; +var KEYCODE_LEFT= 37; +var KEYCODE_UP= 38; +var KEYCODE_RIGHT = 39; +var KEYCODE_DOWN = 40; + +function addItem() { + var item = document.createElement("li"); + item.className = "item"; + + var name = document.createElement("input"); + name.setAttribute("type", "text"); + name.setAttribute("placeholder", "Item Name"); + name.className = "name;"; + item.appendChild(name); + + var dollarSign = document.createElement("span"); + dollarSign.innerText = "$"; + item.appendChild(dollarSign); + + var price = document.createElement("input"); + price.setAttribute("type", "text"); + price.setAttribute("placeholder", "Price"); + price.className = "price"; + item.appendChild(price); + + for (var i in shopperNames) { + var shopperName = shopperNames[i]; + var checkbox = createCheckbox(item, shopperName); + } + + var remove = document.createElement("input"); + remove.setAttribute("type", "button"); + remove.setAttribute("value", "Remove"); + remove.style.float = "right"; + remove.tabIndex = "-1"; + remove.addEventListener("click", function() { removeItem(item); }, false); + item.appendChild(remove); + hide(remove); + + item.onkeydown = itemKeyListener; + + item.addEventListener("click", function() { focusItem(item); }, false); + name.addEventListener("focus", function() { focusItem(item); }, false); + price.addEventListener("focus", function() { focusItem(item); }, false); + price.addEventListener("blur", function() { + price.value = parseFloat(price.value).toFixed(2); + if (price.value == "NaN") { + price.value = ""; + } + }, false); + item.addEventListener("mouseover", function() { show(remove); }, false); + item.addEventListener("mouseout", function() { hide(remove); }, false); + + var items = document.getElementById("items"); + items.appendChild(item); + item.childNodes[0].focus(); +} + +function removeItem(item) { + var items = document.getElementById("items"); + //console.log(items.childNodes.length); + if (items.childNodes.length > 1) items.removeChild(item); +} + +function itemKeyListener(event) { + //console.log(event.keyCode); + var items = document.getElementById("items"); + if (event.keyCode == KEYCODE_ENTER) { + addItem(); + } else if (event.keyCode == KEYCODE_DELETE) { + if (document.activeElement.className == "price" && + !document.activeElement.value) { + document.activeElement.parentNode.childNodes[0].focus(); + } else if ((!document.activeElement.parentNode.childNodes[0].value) && + (!document.activeElement.parentNode.childNodes[2].value)) { + var i = getFocusedItemIndex() - 1; + removeItem(document.activeElement.parentNode); + items.childNodes[i].childNodes[0].focus(); + } + } else if (event.keyCode == KEYCODE_UP) { + var j = getFocusedItemIndex() - 1; + if (j >= 0 && j < items.childNodes.length) { + if (document.activeElement.className == "name") { + items.childNodes[j].childNodes[0].focus(); + } else { + items.childNodes[j].childNodes[2].focus(); + } + } + } else if (event.keyCode == KEYCODE_DOWN) { + var k = getFocusedItemIndex() + 1; + if (k > 0 && k < items.childNodes.length) { + if (document.activeElement.className == "name") { + items.childNodes[k].childNodes[0].focus(); + } else { + items.childNodes[k].childNodes[2].focus(); + } + } else if (k >= items.childNodes.length) { + addItem().childNodes[0].focus(); + } + } else if (event.keyCode == KEYCODE_LEFT) { + if (document.activeElement.className == "price" && + document.activeElement.selectionStart === 0) { + document.activeElement.parentNode.childNodes[0].focus(); + } + } else if (event.keyCode == KEYCODE_RIGHT) { + if (document.activeElement.className == "name" && + document.activeElement.selectionStart == document.activeElement.value.length) { + document.activeElement.parentNode.childNodes[2].focus(); + } + } +} + +function getFocusedItemIndex() { + var items = document.getElementById("items"); + var i = 0; + while (items.childNodes[i] != document.activeElement.parentNode) i++; + return i; +} + +function focusItem(item) { + var items = document.getElementById("items"); + for (var i in items.childNodes) { + items.childNodes[i].className = "item"; + } + item.className += " item-focused"; +} + +function hide(item) { + item.style.display = "none"; +} + +function show(item) { + item.style.display = null; +} + +function moneyBoxKeyListener(event) { + return !(event.keyCode > 31 && (event.keyCode < 48 || event.keyCode > 57)) || (event.keyCode == 190); +} + +function createCheckbox(item, name) { + var label = document.createElement("label"); + var checkbox = document.createElement("input"); + checkbox.setAttribute("type", "checkbox"); + checkbox.setAttribute("checked", "checked"); + checkbox.tabIndex = "-1"; + checkbox.className = name; + checkbox.addEventListener("focus", function() { item.className += " item-focused"; }, false); + checkbox.addEventListener("blur", function() { item.className = "item"; }, false); + label.appendChild(checkbox); + label.innerHTML += name; + item.appendChild(label); + return checkbox; +} + +function createDebtList() { + for (var i in shopperNames) { + var li = document.createElement("li"); + li.className = shopperNames[i]; + li.innerHTML = shopperNames[i] + ' needs to pay $0.00.'; + debts.appendChild(li); + } +} + +function addTax(price, taxRate) { + return price * (1 + taxRate / 100.0); +} + +function getAllItems() { + return document.getElementById("items").childNodes; +} + +function getTotal() { + var total = 0.0; + var items = getAllItems(); + for (var i in items) { + total += getPrice(items[i]); + } + total = addTax(total, getTaxFromInput()); + document.getElementById("total").innerHTML = total.toFixed(2); +} + +function getPrice(item) { + try { + var price = parseFloat(item.childNodes[2].value); + return isNaN(price) ? 0 : price; + } catch (ex) { + return 0; + } +} + +function getTaxFromInput() { + return document.getElementById("tax").value; +} + +function getNumberOfShoppers(item) { + var count = 0; + for (var i in item.childNodes) { + if (item.childNodes[i].tagName == "LABEL") { + var label = item.childNodes[i]; + for (var j in label.childNodes) { + if (label.childNodes[j].checked) { + count++; + } + } + } + } + return count; +} + +function getDebt(name) { + var items = document.getElementById("items"); + var debt = 0; + for (var i in items.childNodes) { + var item = items.childNodes[i]; + if (hasToPayForItem(name, item)) { + var subDebt = getPrice(item) / getNumberOfShoppers(item); + debt += addTax(subDebt, getTaxFromInput()); + console.log(item + getNumberOfShoppers(item)); + } + } + console.log(name + ": " + debt); + return debt; +} + +function hasToPayForItem(name, item) { + for (var i in item.childNodes) { + if (item.childNodes[i].tagName == "LABEL") { + var label = item.childNodes[i]; + for (var j in label.childNodes) { + if (label.childNodes[j].className == name) { + return label.childNodes[j].checked; + } + } + } + } + return false; +} + +function getDebts() { + var debts = document.getElementById("debts"); + for (var i in shopperNames) { + var name = shopperNames[i]; + for (var j in debts.childNodes) { + if (debts.childNodes[j].className == name) { + debts.childNodes[j].childNodes[1].innerText = getDebt(name).toFixed(2); + } + } + } +} + +function updateCalculations() { + getTotal(); + getDebts(); +} + +function setEventListeners() { + document.getElementById("add").addEventListener("click", addItem, false); + document.body.addEventListener("keyup", updateCalculations, false); + document.body.addEventListener("click", updateCalculations, false); +} + +createDebtList(); +setEventListeners(); +addItem();