Reba calculator
Simple demo to show an element with with Alpine.js
by lmeurs
HTML
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<h1 class="header">
REBA calculator
<img src="https://justiceandpeace.nl/wp-content/uploads/2022/06/Partner-AMIF-300x300-1.jpg" />
</h1>
<form
x-cloak
x-data="alpineToDemoBridge"
@submit.prevent="demo.nextStep()"
@reset.prevent="demo.reset()"
>
<fieldset
id="step-amv"
@step-activation="if (input.isAmv === undefined) submitButtonDisabled = true"
>
<legend>Wat is jouw leeftijd?</legend>
<label>
<input type="radio" value="false" x-model="input.isAmv">
Ik ben 18 jaar of ouder
</label>
<label>
<input type="radio" value="true" x-model="input.isAmv">
Ik ben 17 jaar of jonger (amv)
</label>
</fieldset>
<fieldset
id="step-composition"
@step-activation="if (input.isAmv == 'true') setStep('++')"
x-show="stepEqualsOrHigher('composition') && input.isAmv === 'false' "
x-transition:enter.opacity.duration.500ms
>
<legend>Hoe is jouw gezin samengesteld?</legend>
<label>
<select x-model="input.amountOfAdults">
<template x-for="option in [1,2,3,4,5]" :key="option">
<option :value="option" :selected="option == input.amountOfAdults" x-text="option"></option>
</template>
</select>
<span x-show="input.amountOfAdults == 1">volwassene (18 jaar of ouder)</span>
<span x-show="input.amountOfAdults != 1">volwassenen (18 jaar of ouder)</span>
</label>
<label>
<select x-model="input.amountOfChildren">
<template x-for="option in [0,1,2,3,4,5]" :key="option">
<option :value="option" :selected="option == input.amountOfChildren" x-text="option"></option>
</template>
</select>
<span x-show="input.amountOfChildren == 1">kind (17 jaar of jonger)</span>
<span x-show="input.amountOfChildren != 1">kinderen (17 jaar of jonger)</span>
</label>
<label x-show="input.amountOfChildren>0"...
SCSS
[x-cloak] { display: none !important; }
body {
font: 12px/1.2 sans-serif;
}
fieldset {
margin: 2em 0;
padding: 1em;
border: 1px solid #ccc;
}
label {
display: block;
line-height: 2;
}
input {
&.error {
border-color: red;
outline-color: red;
}
&[type=checkbox] {
vertical-align: middle;
}
&.indent {
www-margin-left: 1.75em;
}
}
.result {
font-weight: bold;
font-size: 18px;
}
button {
border-radius: 0;
border: 0;
color: white;
font-size: 15px;
padding: .5em 1em;
background: green;
cursor: pointer;
&.reset { background: orange; }
&:disabled { opacity: .25; }
}
.header {
img {
display: block;
width: 100px;
margin: 1em 0;
}
}
.version-info {
color: #888;
font-style: italic;
}
JavaScript
// Reba: main object
let reba = {};
// Reba data object
// NB: amounts are per week and automatically converted to per month (multiplied by 4.33).
reba.data = {
// "Zakgeld"
pocketMoney: 14.47,
// "Eetgeld"
foodMoney: [],
// "Wooncomponent"
livingComponent: [],
// "Logeerregeling"
lodgingAllowance: [],
};
// Define food money per week, keyed by amount of persons.
reba.data.foodMoney[1] = { perAdult: 58.24, perChild: 48.51 };
reba.data.foodMoney[2] = { perAdult: 58.24, perChild: 48.51 };
reba.data.foodMoney[3] = { perAdult: 49.49, perChild: 41.23 };
reba.data.foodMoney[4] = { perAdult: 43.68, perChild: 36.40 };
// Define living component per week, keyed by amount of persons.
reba.data.livingComponent[1] = 50;
reba.data.livingComponent[2] = 25;
reba.data.livingComponent[3] = 12.5;
reba.data.livingComponent[4] = 12.5;
// Define lodging allowance per week, keyed by amount of persons.
reba.data.lodgingAllowance[1] = 75;
reba.data.lodgingAllowance[2] = 25;
reba.data.lodgingAllowance[3] = 12.5;
reba.data.lodgingAllowance[4] = 12.5;
/**
* Calculate: main function
*/
reba.calculate = function(values) {
// Parse weekly amounts to monthly.
this.parseWeeklyToMonthly();
// Calculate amount of persons.
this.calculateAmountOfPersons(values);
// Calculate week money.
this.calculateWeekMoney(values);
// Calculate exemption ("Vrijstelling"): 25% of the income with a maximum of 264.
values.exemption = Math.min(264, values.monthlyIncome * .25);
// Calculate maximum own contribution ("maximale eigen bijdrage").
this.calculateMaxOwnContribution(values);
// Calculate own contribution ("eigen bijdrage"): income minus exemption, or maximum.
values.ownContribution = Math.min(values.monthlyIncome - values.exemption, values.maxOwnContribution);
};
/**
* Parse data: from weekly to monthly amounts
*/
reba.parseWeeklyToMonthly = function(dataObject) {
// Only execute once (exit if no data object provided and set flag).
if (!dataObject &&...