JSFiddle - React, Tailwind, and code Playground
by lchau
HTML
<div>
<label for="subtotal">Subtotal</label>
<input type="number" id="subtotal" value="0" readonly="readonly" disabled="disabled">
</div>
<div>
<label for="total">Sales Tax</label>
<input type="number" id="salesTax" value="8.5" min="1.0">%
</div>
<div>
<label for="total">SF Employer Mandate</label>
<input type="number" id="mandatoryTax" value=4 min="0">%
</div>
<div>
<label for="total">Total</label>
<input type="number" id="total" value="40" min="0">
</div>
<div>
<label for="total">Split</label>
<input type="number" id="splitCount" value="2" min="1">
</div>
<button id="calculate">calculate</button>
<div id="output"></div>
CSS
#output {
font-family: monospace;
}
table {
margin-top: 10px;
border: 1px solid silver;
border-collapse: collapse;
}
table td,
table th {
border: 1px solid #AAAAAA;
padding: 2px 15px;
}
table td {
text-align: right;
}
label {
width: 150px;
display: inline-block;
text-align: right;
padding-right: 5px;
}
input {
width: 75px;
text-align: right;
}
body,
input {
font-family: monospace;
}
JavaScript
function getValue(id, defaultValue = 0) {
const $element = document.getElementById(id);
const value = Number($element.value) || defaultValue;
return value >= 0 ? value : defaultValue;
}
const toFixed = (value, precision = 2) => Number(Number(value).toFixed(precision));
function calculate() {
const total = getValue('total', 0);
const salesTax = 1 + (getValue('salesTax', 1) / 100);
const mandatoryTax = 1 + (getValue('mandatoryTax', 1) / 100);
const splitCount = getValue('splitCount', 1);
const subtotal = toFixed(total / salesTax / mandatoryTax);
document.getElementById('subtotal').value = subtotal;
return [1.15, 1.18, 1.20].map(v => {
const tip = toFixed((subtotal * v) - subtotal);
return {
'%': Math.round((v - 1) * 100),
tip,
get adjusted_tip() {
//Â return +(+Math.trunc(this.tip) + +(Math.ceil(this.total) - this.total)).toFixed(2);
return toFixed((Math.ceil(total) - total) + Math.ceil(this.tip));
},
get adjusted_tip_person() {
return toFixed(this.adjusted_tip / splitCount);
},
get round() {
return toFixed(this.adjusted_tip + total);
},
get split() {
return toFixed(this.round / splitCount);
}
};
});
}
function render() {
const rows = calculate().map(data => {
return `
<tr>
<td>${data['%']}%</td>
<td>$${data.tip}</td>
<td>$${data.adjusted_tip}</td>
<td>$${data.round}</td>
<td>$${data.adjusted_tip_person}</td>
<td>$${data.split}</td>
</tr>
`;
});
document.getElementById('output').innerHTML = `
<table>
<tr>
<th>%</th>
<th>Tip</th>
<th>Adjusted Tip</th>
<th>Rounded Total</th>
<th>Tip/Person</th>
<th>Total/Person</th>
</tr>
${rows.join('')}
</table>
`
}
document.getElementById('calculate').addEventListener('click', render);
document.addEventListener('keyup', render);
render();