diff --git a/JS/helpers/calculator.js b/JS/helpers/calculator.js
new file mode 100644
index 0000000..f984584
--- /dev/null
+++ b/JS/helpers/calculator.js
@@ -0,0 +1,43 @@
+/*global console, Rent */
+
+function Calculator(home) {
+ 'use strict';
+ this.home = home;
+ this.calculateRents();
+
+ console.log(this.home.rooms);
+}
+
+Calculator.prototype.calculateRents = function () {
+ 'use strict';
+ var room_id;
+ for (room_id in this.home.rooms) {
+ if (this.home.rooms.hasOwnProperty(room_id)) {
+ this.calculateRent(room_id);
+ }
+ }
+};
+
+Calculator.prototype.calculateRent = function (room_id) {
+ 'use strict';
+ var room = this.home.rooms[room_id],
+ occupants = room.occupiedBy.length,
+ baseCost = this.home.commonShareCost * occupants,
+ roomCost = room.sqft * this.home.privateCostPerSqft * room.percentUsable,
+ price = baseCost + roomCost;
+
+ room.rent = new Rent(price, room_id, this.home);
+
+ this.applyFeesAndDiscounts(room);
+ if (this.home.roundDollar) {
+ room.rent.price += parseInt(room.rent.price, 10);
+ }
+};
+
+Calculator.prototype.applyFeesAndDiscounts = function (room) {
+ 'use strict';
+ room.rent = (
+ room.hasWindow ?
+ parseFloat(this.home.goodLightingFee) : parseFloat(this.home.badLightingDeduction)
+ );
+};
\ No newline at end of file
diff --git a/JS/helpers/defaultRooms.js b/JS/helpers/defaultRooms.js
new file mode 100644
index 0000000..82c22fe
--- /dev/null
+++ b/JS/helpers/defaultRooms.js
@@ -0,0 +1,62 @@
+var defaultRooms = {
+ "B-R1": {
+ "sqft": 169,
+ "hasWindow": true,
+ "percentUsable": 100,
+ "occupiedBy": ["Conrad"]
+ },
+ "B-R2": {
+ "sqft": 165,
+ "hasWindow": false,
+ "percentUsable": 100,
+ "occupiedBy": ["A. Kern", "Potluck"]
+ },
+ "B-R3": {
+ "sqft": 151,
+ "hasWindow": false,
+ "percentUsable": 80,
+ "occupiedBy": ["Renee"]
+ },
+ "B-R4": {
+ "sqft": 146,
+ "hasWindow": true,
+ "percentUsable": 100,
+ "occupiedBy": ["Hallie"]
+ },
+ "B-R5": {
+ "sqft": 146,
+ "hasWindow": true,
+ "percentUsable": 100,
+ "occupiedBy": ["Jack"]
+ },
+ "C-R1": {
+ "sqft": 191,
+ "hasWindow": true,
+ "percentUsable": 100,
+ "occupiedBy": ["Marco", "Alex C."]
+ },
+ "C-R2": {
+ "sqft": 191,
+ "hasWindow": true,
+ "percentUsable": 100,
+ "occupiedBy": ["Ashley", "Robin"]
+ },
+ "C-R3": {
+ "sqft": 178,
+ "hasWindow": false,
+ "percentUsable": 100,
+ "occupiedBy": ["Ari"]
+ },
+ "C-R4": {
+ "sqft": 166,
+ "hasWindow": true,
+ "percentUsable": 100,
+ "occupiedBy": ["Nick"]
+ },
+ "C-R5": {
+ "sqft": 167,
+ "hasWindow": true,
+ "percentUsable": 100,
+ "occupiedBy": ["Fouad"]
+ }
+};
\ No newline at end of file
diff --git a/JS/helpers/home.js b/JS/helpers/home.js
index f1a6dbb..338ed26 100644
--- a/JS/helpers/home.js
+++ b/JS/helpers/home.js
@@ -1,4 +1,4 @@
-/*global rooms, console, moneyRound */
+/*global rooms, console, defaultRooms, dataType, getPropertyName, getDisplayName, moneyRound, convertItem */
var defaults = {
attributeTableId: 'house-attribute-table',
@@ -16,9 +16,15 @@ var defaults = {
commonWeight: 0.60,
houseSize: 6200,
rentSum: 18000,
+ rooms: defaultRooms,
roundDollar: true
};
+var EDITABLE_FIELDS = [
+ 'calculateAsSingles', 'cheapestRoomMustBeSingle', 'commonWeight',
+ 'rentSum', 'roundDollar'
+];
+
function Home(options) {
'use strict';
this.rooms = {};
@@ -31,6 +37,7 @@ function Home(options) {
this.commonWeight = options.commonWeight || defaults.commonWeight;
this.houseSize = options.houseSize || defaults.houseSize;
this.rentSum = options.rentSum || defaults.rentSum;
+ this.rooms = options.rooms || defaults.rooms;
this.roundDollar = options.roundDollar || defaults.roundDollar;
this.feesAndDeducts = options.feesAndDeducts || defaults.feesAndDeducts;
@@ -51,10 +58,8 @@ function Home(options) {
}
}
- this.populateAttributeTable(this.attributeTableId, this);
- this.populateAttributeTable('fees-attribute-table', this.feesAndDeducts);
-
- console.log(this);
+ this.populateAttributeTable(this);
+ this.populateAttributeTable(this.feesAndDeducts);
}
Home.prototype.setCheapestRoom = function (room) {
@@ -146,8 +151,8 @@ Home.prototype.setOpposingFeeOrDeduction = function (name, feeDuct) {
Home.prototype.fillHouse = function () {
'use strict';
/* TODO: check/grab rooms from structured screen before falling back on defaults */
- if (rooms !== undefined) {
- this.rooms = rooms;
+ if (this.rooms !== undefined) {
+ this.rooms = defaultRooms;
}
};
@@ -174,33 +179,77 @@ Home.prototype.calculateRoomSqftCosts = function () {
this.privateCostPerSqft = moneyRound(this.privateCostPerSqft);
};
-Home.prototype.populateAttributeTable = function (tableId, attributes) {
+Home.prototype.populateAttributeTable = function (attributes) {
'use strict';
- var attributeTable = document.getElementById(tableId),
+ var attributeTable = document.getElementById(this.attributeTableId),
+ dontPrint = ['attributeTableId'],
row,
cell,
attribute,
subAttribute,
rowIndex = attributeTable.rows.length,
cellIndex;
- function insertCell(row, index, item) {
- cell = row.insertCell(index);
- cell.innerHTML = item;
+ function createValInput(item) {
+ var input = document.createElement('INPUT');
+ input.setAttribute('type', 'text');
+ input.setAttribute('value', item);
+ return input;
}
- function insertRow(table, index, cells) {
- row = table.insertRow(index);
- for (cellIndex = 0; cellIndex < cells.length; cellIndex += 1) {
- insertCell(row, cellIndex, cells[cellIndex]);
+ function createValCheckbox(item) {
+ var input = document.createElement('INPUT');
+ input.setAttribute('type', 'checkbox');
+ input.checked = (item === 'true');
+ return input;
+ }
+ function createValCell(row, attrName, attrValue) {
+ var propertyName = attrName;
+ attrName = getDisplayName(attrName);
+ cell = row.insertCell(0);
+ cell.innerHTML = attrName;
+ cell = row.insertCell(1);
+
+ attrValue = convertItem(propertyName, attrValue);
+ if (EDITABLE_FIELDS.includes(propertyName)) {
+ if (dataType[propertyName].type === 'bool') {
+ attrValue = createValCheckbox(attrValue);
+ } else {
+ attrValue = createValInput(attrValue);
+ }
+ cell.appendChild(attrValue);
+ } else {
+ cell.innerHTML = attrValue;
}
}
- console.log(tableId);
+ function insertRow(table, index, attrName, attrValue) {
+ row = table.insertRow(index);
+ createValCell(row, attrName, attrValue);
+ }
+
for (attribute in attributes) {
if (attributes.hasOwnProperty(attribute)) {
- if (typeof attributes[attribute] !== 'object') {
- console.log(attributeTable, tableId, attribute);
- insertRow(attributeTable, rowIndex, [attribute, attributes[attribute]]);
+ if (!dontPrint.includes(attribute) && (typeof attributes[attribute] !== 'object')) {
+ insertRow(attributeTable, rowIndex, attribute, attributes[attribute]);
rowIndex += 1;
}
}
}
-};
\ No newline at end of file
+};
+
+Home.prototype.getAttributesFromTable = function () {
+ 'use strict';
+ var attributeTable = document.getElementById(this.attributeTableId),
+ table,
+ tr,
+ tdName,
+ tdContent;
+ console.log(attributeTable);
+ for (tr = 1; tr < attributeTable.rows.length; tr += 1) {
+ if (attributeTable.rows.hasOwnProperty(tr)) {
+ tdName = getPropertyName(attributeTable.rows[tr].children[0].textContent);
+ tdContent = getText(attributeTable.rows[tr].children[1]);
+ tdContent = parseItem(tdName, tdContent);
+ this[tdName] = tdContent;
+ }
+ }
+ console.log(this);
+};
diff --git a/JS/helpers/rent.js b/JS/helpers/rent.js
new file mode 100644
index 0000000..6ba8e2e
--- /dev/null
+++ b/JS/helpers/rent.js
@@ -0,0 +1,11 @@
+function Rent(price, room_id, home) {
+ 'use strict';
+ this.price = price;
+ this.room_id = room_id;
+ this.home = home;
+}
+
+Rent.prototype.getRoomDeets = function () {
+ 'use strict';
+ return this.home.rooms[this.room_id];
+};
\ No newline at end of file
diff --git a/JS/helpers/rooms.js b/JS/helpers/rooms.js
index c80d9c3..cbbc2c8 100644
--- a/JS/helpers/rooms.js
+++ b/JS/helpers/rooms.js
@@ -1,62 +1,32 @@
-var rooms = {
- "B-R1": {
- "sqft": 169,
- "hasWindow": true,
- "percentUsable": 1,
- "occupiedBy": ["Conrad"]
- },
- "B-R2": {
- "sqft": 165,
- "hasWindow": false,
- "percentUsable": 1,
- "occupiedBy": ["A. Kern", "Potluck"]
- },
- "B-R3": {
- "sqft": 151,
- "hasWindow": false,
- "percentUsable": 0.8,
- "occupiedBy": ["Renee"]
- },
- "B-R4": {
- "sqft": 146,
- "hasWindow": true,
- "percentUsable": 1,
- "occupiedBy": ["Hallie"]
- },
- "B-R5": {
- "sqft": 146,
- "hasWindow": true,
- "percentUsable": 1,
- "occupiedBy": ["Jack"]
- },
- "C-R1": {
- "sqft": 191,
- "hasWindow": true,
- "percentUsable": 1,
- "occupiedBy": ["Marco", "Alex C."]
- },
- "C-R2": {
- "sqft": 191,
- "hasWindow": true,
- "percentUsable": 1,
- "occupiedBy": ["Ashley", "Robin"]
- },
- "C-R3": {
- "sqft": 178,
- "hasWindow": false,
- "percentUsable": 1,
- "occupiedBy": ["Ari"]
- },
- "C-R4": {
- "sqft": 166,
- "hasWindow": true,
- "percentUsable": 1,
- "occupiedBy": ["Nick"]
- },
- "C-R5": {
- "sqft": 167,
- "hasWindow": true,
- "percentUsable": 1,
- "occupiedBy": ["Fouad"]
+/*global console, getPropertyName, getText, parseItem */
+
+function createRoomsFromDefaults() {
+ 'use strict';
+}
+
+function getRoomsFromTables() {
+ 'use strict';
+ var tables = document.getElementsByClassName('room'),
+ table,
+ tr,
+ tdName,
+ tdContent,
+ rooms = {},
+ roomId;
+ for (table in tables) {
+ if (tables.hasOwnProperty(table)) {
+ roomId = tables[table].rows[0].textContent;
+ rooms[roomId] = {};
+ for (tr = 1; tr < tables[table].rows.length; tr += 1) {
+ if (tables[table].rows.hasOwnProperty(tr)) {
+ tdName = getPropertyName(tables[table].rows[tr].children[0].textContent);
+ tdContent = getText(tables[table].rows[tr].children[1]);
+ tdContent = parseItem(tdName, tdContent);
+ rooms[roomId][tdName] = tdContent;
+ }
+ }
+ }
}
-};
\ No newline at end of file
+ console.log(rooms);
+ return rooms;
+}
\ No newline at end of file
diff --git a/JS/helpers/utils.js b/JS/helpers/utils.js
index 90a2a74..c441070 100644
--- a/JS/helpers/utils.js
+++ b/JS/helpers/utils.js
@@ -1,4 +1,219 @@
function moneyRound(number) {
'use strict';
- return parseFloat(number.toFixed(2));
-}
\ No newline at end of file
+ return parseFloat(number).toFixed(2);
+}
+
+function stripNumber(numString) {
+ 'use strict';
+ return numString.replace(/[^0-9\.]+/g, "");
+}
+
+function invertDict(dict) {
+ 'use strict';
+ var newDict = {},
+ newKey,
+ newVal;
+ for (newVal in dict) {
+ if (dict.hasOwnProperty(newVal)) {
+ newKey = dict[newVal];
+ newDict[newKey] = newVal;
+ }
+ }
+ return newDict;
+}
+
+var displayNames = {
+ // House Attributes
+ calculateAsSingles: 'Calculated as Singles',
+ cheapestRoomMustBeSingle: 'Cheapest Room is Single',
+ commonWeight: 'Common Weight',
+ houseSize: 'House Size',
+ rentSum: 'Rent Sum',
+ roundDollar: 'Rounded to Dollar',
+ peepsCount: '# Housemates',
+ commonSpace: 'Common Area',
+ commonCostPerSqft: 'Common Cost per SqFt',
+ commonShareCost: 'Base share cost',
+ privateCostPerSqft: 'Room Cost per SqFt',
+ // Room attributes
+ sqft: 'Area',
+ hasWindow: 'Has Window',
+ percentUsable: 'Usable Space',
+ occupiedBy: 'Occupied By'
+};
+
+var propertyNames = invertDict(displayNames);
+propertyNames.feeOrDeduct = 'feeOrDeduct';
+
+var dataType = {
+ // House attributes
+ calculateAsSingles: {
+ type: 'bool',
+ displayName: displayNames.calculateAsSingles
+ },
+ cheapestRoomMustBeSingle: {
+ type: 'bool',
+ displayName: displayNames.cheapestRoomMustBeSingle
+ },
+ commonWeight: {
+ type: 'percent',
+ displayName: displayNames.commonWeight
+ },
+ houseSize: {
+ type: 'sqft',
+ displayName: displayNames.houseSize
+ },
+ rentSum: {
+ type: 'dollar',
+ displayName: displayNames.rentSum
+ },
+ roundDollar: {
+ type: 'bool',
+ displayName: displayNames.roundDollar
+ },
+ peepsCount: {
+ type: 'number',
+ displayName: displayNames.peepsCount
+ },
+ commonSpace: {
+ type: 'sqft',
+ displayName: displayNames.commonSpace
+ },
+ commonCostPerSqft: {
+ type: 'dollar',
+ displayName: displayNames.commonCostPerSqft
+ },
+ commonShareCost: {
+ type: 'dollar',
+ displayName: displayNames.commonShareCost
+ },
+ privateCostPerSqft: {
+ type: 'dollar',
+ displayName: displayNames.privateCostPerSqft
+ },
+ feeOrDeduct: {
+ type: 'dollar'
+ },
+ // Room attributes
+ sqft: {
+ type: 'sqft',
+ displayName: displayNames.sqft
+ },
+ hasWindow: {
+ type: 'bool',
+ displayName: displayNames.hasWindow
+ },
+ percentUsable: {
+ type: 'percent',
+ displayName: displayNames.percentUsable
+ },
+ occupiedBy: {
+ type: 'list',
+ displayName: displayNames.occupiedBy
+ }
+};
+
+var toDataType = {
+ bool: function (item) {
+ 'use strict';
+ return item.toString();
+ },
+ percent: function (item) {
+ 'use strict';
+ return (item * 100).toString() + '%';
+ },
+ sqft: function (item) {
+ 'use strict';
+ return item.toLocaleString();
+ },
+ dollar: function (item) {
+ 'use strict';
+ return '$' + moneyRound(item).toLocaleString();
+ },
+ number: function (item) {
+ 'use strict';
+ return item.toLocaleString();
+ },
+ list: function (item) {
+ 'use strict';
+ return item.join(',');
+ }
+};
+
+var fromDataType = {
+ bool: function (item) {
+ 'use strict';
+ return (item === 'true');
+ },
+ percent: function (item) {
+ 'use strict';
+ return parseFloat(stripNumber(item)) / 100;
+ },
+ sqft: function (item) {
+ 'use strict';
+ return parseInt(stripNumber(item), 10);
+ },
+ dollar: function (item) {
+ 'use strict';
+ return moneyRound(stripNumber(item));
+ },
+ number: function (item) {
+ 'use strict';
+ return parseInt(stripNumber(item), 10);
+ },
+ list: function (item) {
+ 'use strict';
+ return item.split(',');
+ }
+};
+
+function isFeeOrDeduct(name) {
+ 'use strict';
+ return (name.includes('Deduction') || name.includes('Fee'));
+}
+
+function parseItem(name, item) {
+ 'use strict';
+ name = isFeeOrDeduct(name) ? propertyNames.feeOrDeduct : name;
+ var type = dataType[name].type;
+ return fromDataType[type](item);
+}
+
+function convertItem(name, item) {
+ 'use strict';
+ name = isFeeOrDeduct(name) ? propertyNames.feeOrDeduct : name;
+ var type = dataType[name].type;
+ return toDataType[type](item);
+}
+
+function getText(item) {
+ 'use strict';
+ if (item.firstChild.localName === 'input') {
+ if (item.firstChild.type === 'checkbox') {
+ return item.firstChild.checked.toString();
+ }
+ return item.firstChild.value;
+ }
+ return item.textContent;
+}
+
+function getDisplayName(name) {
+ 'use strict';
+ if (displayNames.hasOwnProperty(name)) {
+ return displayNames[name];
+ }
+ name = name.split(/(?=[A-Z])/).join(' ');
+ name = name.charAt(0).toUpperCase() + name.slice(1);
+ return name;
+}
+
+function getPropertyName(name) {
+ 'use strict';
+ if (propertyNames.hasOwnProperty(name)) {
+ return propertyNames[name];
+ }
+ name = name.split(' ').join('');
+ name = name.charAt(0).toLowerCase() + name.slice(1);
+ return name;
+}
+
diff --git a/JS/index.html b/JS/index.html
index 4c5f521..b39b710 100644
--- a/JS/index.html
+++ b/JS/index.html
@@ -1,18 +1,126 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
diff --git a/JS/main.css b/JS/main.css
new file mode 100644
index 0000000..78ca4e9
--- /dev/null
+++ b/JS/main.css
@@ -0,0 +1,38 @@
+html, body {
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+}
+
+table {
+ float: left;
+ border: 1px solid black;
+}
+
+td {
+ border: 1px solid black;
+ width: 200px;
+}
+
+input {
+ width: 100%;
+}
+
+#attributes {
+ display: inline-block;
+}
+
+#rooms {
+ display: inline-block;
+}
+
+.room {}
+
+.room td {
+ width: 110px;
+}
+
+#house-attribute-table {}
+
+#fees-attribute-table {}
\ No newline at end of file
diff --git a/JS/main.js b/JS/main.js
index 3440580..84452bb 100644
--- a/JS/main.js
+++ b/JS/main.js
@@ -1,3 +1,13 @@
-/*global Home */
+/*global Calculator, Home, getRoomsFromTables */
-var homes = new Home();
\ No newline at end of file
+function buildHome() {
+ 'use strict';
+ var rooms = getRoomsFromTables(),
+ home = new Home({
+ rooms: rooms
+ });
+ //calculator = new Calculator(homes);
+ home.getAttributesFromTable();
+}
+
+document.addEventListener('DOMContentLoaded', buildHome, false);
\ No newline at end of file