JSFiddle - React, Tailwind, and code Playground

by amarcrypto

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"></script>
<div class="container">
    <div class="row">
        <div class="col-md-6">
            <div class="form-group">
                <label for="initial_deposit">Starting Balance</label>
                <div class="row">
                    <div class="input-group col-md-6 col-sm-8">
                        <div class="input-group-prepend">
                            <button class="btn btn-primary" type="button" data-counter="sub" data-field="initial_deposit">&minus;</button>
                        </div>
                        <input class="form-control text-center" id="initial_deposit" type="text" name="initial_deposit" min="100" max="1000000" step="100" value="$5000" data-value="5000" data-prepend="$">
                        <div class="input-group-append">
                            <button class="btn btn-primary" type="button" data-counter="add" data-field="initial_deposit">&plus;</button>
                        </div>
                    </div>
                </div>
            </div>

            <div class="form-group">
                <label for="contribution_amount">Contributions</label>
                <div class="row">
                    <div class="input-group col-md-6 col-sm-8">
                        <div class="input-group-prepend">
                            <button class="btn btn-primary" type="button" data-counter="sub" data-field="contribution_amount">&minus;</button>
                        </div>
                        <input class="form-control text-center" id="contribution_amount" type="text" name="contribution_amount" min="0" max="10000" step="50" value="$100" data-value="100" data-prepend="$">
                        <div class="input-group-append">
                            <button class="btn btn-primary" type="button"...

JavaScript

(function () {
    var initial_deposit = document.querySelector('#initial_deposit'),
        contribution_amount = document.querySelector('#contribution_amount'),
        investment_timespan = document.querySelector('#investment_timespan'),
        investment_timespan_text = document.querySelector('#investment_timespan_text'),
        estimated_return = document.querySelector('#estimated_return'),
        future_balance = document.querySelector('#future_balance');

    function updateValue(element, action) {
        var min = parseFloat(element.getAttribute('min')),
            max = parseFloat(element.getAttribute('max')),
            step = parseFloat(element.getAttribute('step')) || 1,
            oldValue = element.dataset.value || element.defaultValue || 0,
            newValue = parseFloat(element.value.replace(/\$/, ''));

        if (isNaN(parseFloat(newValue))) {
            newValue = oldValue;
        } else {
            if (action == 'add') {
                newValue += step;
            } else if (action == 'sub') {
                newValue -= step;
            }

            newValue = newValue < min ? min : newValue > max ? max : newValue;
        }

        element.dataset.value = newValue;
        element.value = (element.dataset.prepend || '') + newValue + (element.dataset.append || '');

        updateChart();
    }

    function getChartData() {
        var P = parseFloat(initial_deposit.dataset.value), // Principal
            r = parseFloat(estimated_return.dataset.value / 100), // Annual Interest Rate
            c = parseFloat(contribution_amount.dataset.value), // Contribution Amount
            n = parseInt(document.querySelector('[name="compound_period"]:checked').value), // Compound Period
            n2 = parseInt(document.querySelector('[name="contribution_period"]:checked').value), // Contribution Period
            t = parseInt(investment_timespan.value), // Investment Time Span
            currentYear = (new...