Created
December 16, 2016 13:11
-
-
Save callum/a8c9b29496598021435dcb785fc5ecb4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width"> | |
| <title>Household costs calculator</title> | |
| <style> | |
| * { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| margin: 1rem; | |
| font-family: Helvetica; | |
| } | |
| label, input { | |
| display: block; | |
| } | |
| label { | |
| margin-bottom: .2rem; | |
| } | |
| input { | |
| width: 100%; | |
| font-size: large; | |
| } | |
| input[type=number] { | |
| padding: .4rem; | |
| } | |
| main { | |
| max-width: 480px; | |
| } | |
| header, form { | |
| margin-bottom: 2rem; | |
| } | |
| .field { | |
| margin-bottom: 1rem; | |
| } | |
| .note { | |
| margin-top: .4rem; | |
| font-style: italic; | |
| font-size: small; | |
| } | |
| .total { | |
| display: block; | |
| margin-bottom: .4rem; | |
| font-size: x-large; | |
| } | |
| @media (min-width: 480px) { | |
| body { | |
| margin: 2rem; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <main> | |
| <header> | |
| <h1>Household costs calculator</h1> | |
| <p>Calculate monthly costs for shared property</p> | |
| </header> | |
| <form id="form" method="get"> | |
| <div class="field"> | |
| <label for="div">Divisor</label> | |
| <input id="div" name="div" type="range" min="1" max="6" value="2"> | |
| <div id="people" class="note"></div> | |
| </div> | |
| <div class="field"> | |
| <label for="rent">Rent</label> | |
| <input id="rent" name="rent" type="number" step="10" value="1750"> | |
| <div id="rentpw" class="note"></div> | |
| </div> | |
| <div class="field"> | |
| <label for="ctax">Council tax</label> | |
| <input id="ctax" name="ctax" type="number" step="5" value="100"> | |
| </div> | |
| <div class="field"> | |
| <label for="gas">Gas</label> | |
| <input id="gas" name="gas" type="number" step="5" value="20"> | |
| </div> | |
| <div class="field"> | |
| <label for="elec">Electric</label> | |
| <input id="elec" name="elec" type="number" step="5" value="30"> | |
| </div> | |
| <div class="field"> | |
| <label for="water">Water</label> | |
| <input id="water" name="water" type="number" step="5" value="20"> | |
| </div> | |
| <div class="field"> | |
| <label for="tvlic">TV licence</label> | |
| <input id="tvlic" name="tvlic" type="number" step="5" value="12"> | |
| </div> | |
| <div class="field"> | |
| <label for="net">Internet</label> | |
| <input id="net" name="net" type="number" step="5" value="30"> | |
| </div> | |
| <div class="field"> | |
| <label for="tv">Television</label> | |
| <input id="tv" name="tv" type="number" step="5" value="0"> | |
| </div> | |
| <div class="field"> | |
| <label for="phone">Landline</label> | |
| <input id="phone" name="phone" type="number" step="5" value="0"> | |
| </div> | |
| <div class="field"> | |
| <label for="cleaner">Cleaner</label> | |
| <input id="cleaner" name="cleaner" type="number" step="5" value="0"> | |
| </div> | |
| </form> | |
| <div id="totalpm" class="total"></div> | |
| <span id="totalpw"></span> / <span id="totalpy"></span> | |
| </main> | |
| <script> | |
| var blacklist = ['div'] | |
| var form = document.querySelector('#form') | |
| var rentPw = document.querySelector('#rentpw') | |
| var people = document.querySelector('#people') | |
| var totalPw = document.querySelector('#totalpw') | |
| var totalPm = document.querySelector('#totalpm') | |
| var totalPy = document.querySelector('#totalpy') | |
| form.addEventListener('submit', function (event) { | |
| event.preventDefault() | |
| }) | |
| form.addEventListener('change', function (event) { | |
| event.preventDefault() | |
| window.history.replaceState({}, {}, '?' + serializeValues(form)) | |
| update(form) | |
| }) | |
| restoreValues(form) | |
| update(form) | |
| function restoreValues (form) { | |
| var value | |
| for (var i = 0; i < form.elements.length; i++) { | |
| value = getQueryParam(form.elements[i].name) | |
| if (typeof value !== 'undefined') form.elements[i].value = value | |
| } | |
| } | |
| function serializeValues (form) { | |
| var query = '' | |
| for (var i = 0; i < form.elements.length; i++) { | |
| if (form.elements[i].name) { | |
| query += '&' + encodeURIComponent(form.elements[i].name) | |
| + '=' + encodeURIComponent(form.elements[i].value) | |
| } | |
| } | |
| return query.slice(1) | |
| } | |
| function update (form) { | |
| var monthlyTotal = calculateMonthlyTotal(form) | |
| totalPw.textContent = | |
| '£' + formatNumber(calculateWeeklyValue(monthlyTotal).toFixed(2)) + ' per week' | |
| totalPm.textContent = | |
| 'Total of £' + formatNumber(monthlyTotal.toFixed(2)) | |
| totalPy.textContent = | |
| '£' + formatNumber(calculateYearlyValue(monthlyTotal).toFixed(2)) + ' per year' | |
| rentPw.textContent = | |
| 'Roughly £' + formatNumber(Math.round(calculateWeeklyValue(form.elements.rent.value)).toFixed(2)) + ' per week' | |
| var divisor = form.elements.div.value | |
| if (divisor > 1) { | |
| people.textContent = 'Costs are split between ' + divisor + ' people' | |
| } else { | |
| people.textContent = 'Costs aren’t split' | |
| } | |
| } | |
| function calculateMonthlyTotal (form) { | |
| var total = 0, el | |
| for (var i = 0; i < form.elements.length; i++) { | |
| el = form.elements[i] | |
| if (!el.name || blacklist.indexOf(el.name) !== -1) continue | |
| total += parseInt(el.value, 10) | |
| } | |
| total /= parseInt(form.elements.div.value, 10) | |
| return total | |
| } | |
| function calculateWeeklyValue (monthlyValue) { | |
| return calculateYearlyValue(monthlyValue) / 52 | |
| } | |
| function calculateYearlyValue (monthlyValue) { | |
| return parseInt(monthlyValue, 10) * 12 | |
| } | |
| function formatNumber (value) { | |
| return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') | |
| } | |
| function getQueryParam (param) { | |
| var params = window.location.search.slice(1).split('&') | |
| for (var i = 0; i < params.length; i++) { | |
| var pair = params[i].split('=') | |
| if (decodeURIComponent(pair[0]) === param) { | |
| return decodeURIComponent(pair[1]) | |
| } | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment