Skip to content

Instantly share code, notes, and snippets.

@callum
Created December 16, 2016 13:11
Show Gist options
  • Select an option

  • Save callum/a8c9b29496598021435dcb785fc5ecb4 to your computer and use it in GitHub Desktop.

Select an option

Save callum/a8c9b29496598021435dcb785fc5ecb4 to your computer and use it in GitHub Desktop.
<!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