Skip to content

Instantly share code, notes, and snippets.

@chrishutchinson
Created November 23, 2017 17:45
Show Gist options
  • Save chrishutchinson/7c29a7a9fc31cde111284dfb351c9d39 to your computer and use it in GitHub Desktop.
Save chrishutchinson/7c29a7a9fc31cde111284dfb351c9d39 to your computer and use it in GitHub Desktop.
Budget Calculator 2017 code review
// HTML Element
<budget-calculator no-headline></budget-calculator>
// Polymer template code
<template is="dom-if" if="{{showHeadline}}">
<h1>This is my headline</h1>
</template>
// Polymer JavaScript code
properties: {
noHeadline: {
type: Boolean,
value: false,
},
showHeadline: {
type: Boolean,
computed: 'computeShowHeadline(noHeadline)'
}
},
computeShowHeadline: function(noHeadline) {
// Return the opposite of `noHeadline`.
// If `noHeadline` is FALSE, then `showHeadline` will be TRUE
// If `noHeadline` is TRUE, then `showHeadline` will be FALSE
return !noHeadline;
}
// Polymer template code
<form on-submit="handleFormSubmit"></form>
// Polymer JavaScript code
handleFormSubmit: function(event) {
// Your form submission behaviour would go here
}
// Polymer template code
<form autocomplete="off" id="form" on-submit="handleFormSubmit">
<input type="text" name="income" placeholder="Enter your annual income (£)" />
<div class="selectWrapper">
<i class="Icon Icon--arrowDown"></i>
<select name="category" id="dropdown">
<option value="" disabled selected>Your status</option>
</select>
</div>
<input type="submit" value="Search" class="Button" />
</form>
<template is="dom-if" if={{error}}>
<div class="error">{{error}}</div>
</template>
// Polymer JavaScript code
const cleanIncome = income => parseInt(income.replace(/([^\d.]+)/g, ''));
handleFormSubmit: function(event) {
event.preventDefault();
// 0. Get input data
const form = event.target;
const income = form.income.value;
const dropdownSelection = form.category.value;
// 1. Reset error state
this.error = null;
// 2. Clean input data
const cleanedIncome = cleanIncome(income);
console.log({ cleanedIncome });
// 3. Validate input data
if (cleanedIncome === '' || !cleanedIncome) {
// 4. Show error
this.error = 'There has been a problem parsing your income.';
return;
}
if (cleanedIncome < 10000) {
// 4. Show error (2)
this.error = 'Please input an income greater than £10,000.';
return;
}
// 5. Show results and send analytics event
this.showData({
income: cleanedIncome,
case: dropdownSelection,
});
ga('send', 'event', 'budget-calculator', 'income', cleanedIncome);
}
// Polymer template code
<!-- A permanently visible (although empty) anchor, so we have somewhere to scroll to -->
<div id="results-anchor"></div>
// Polymer JavaScript code
const scrollToElement = (element, offset = 0) => {
const distanceFromTop = element.getBoundingClientRect().top;
window.scrollBy({
top: distanceFromTop + offset,
left: 0,
behavior: 'smooth',
});
};
// ...
showData: function(data) {
// ...
scrollToElement(this.$$('#results-anchor'), -40);
// ...
}
// Polymer template code
<p>Your closest income band is {{results.income}}. Figures for a {{sheetLabel}}.</p>
<div class="row">
<div class="col">
<div class="label">Income change next year (2018/19)</div>
<div class="big income">{{results.change_2018}}</div>
</div>
</div>
<div class="row borderTop">
<div class="col">
<div class="label">Current net income (2017/18)</div>
<div class="big mid">{{results.total_income_2017}}</div>
<div class="label gill">after a {{results.tax_nic_bill_2017}} tax deduction</div>
</div>
<div class="col">
<div class="label">Net year's net income (2018/19)</div>
<div class="big mid">{{results.total_income_2018}}</div>
<div class="label gill">after a {{results.tax_nic_bill_2018}} tax deduction</div>
</div>
</div>
<div class="row borderBottom">
<div class="col">
<div class="label">Current child benefit (2017/18)</div>
<div class="big mid">{{results.child_benefit_2017}}</div>
</div>
<div class="col">
<div class="label">Next year's child benefit (2018/19)</div>
<div class="big mid">{{results.child_benefit_2018}}</div>
</div>
</div>
// Polymer JavaScript code
const rawIncomeBracketData = {
change_2018: 283,
change_2019: 0,
child_benefit_2017: 0,
child_benefit_2018: 0,
child_benefit_2019: 0,
income: 120000,
student_loan_repayment_2017: 9200,
student_loan_repayment_2018: 9150,
student_loan_repayment_2019: 9150,
tax_nic_bill_2017: 46620,
tax_nic_bill_2018: 46387,
tax_nic_bill_2019: 46387,
total_income_2017: 64180,
total_income_2018: 64463,
total_income_2019: 64463,
universal_credit_2017: 0,
universal_credit_2018: 0,
universal_credit_2019: 0
};
this.results = Object.keys(rawIncomeBracketData)
.reduce((acc, key) => {
const value = rawIncomeBracketData[key];
let prefix = '';
switch(key) {
case 'change_2018':
prefix = value < 0 ? '-' : '+';
break;
}
return Object.assign(acc, {
[key]: `${prefix}£${Math.abs(value).toLocaleString()}`
});
}, {});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment