JSFiddle - React, Tailwind, and code Playground

by joplomacedo

HTML

<label>
    <span>Total monthly visitors</span>
    <span>
        <input class="js-expectedResultsInput js-expectedResultsInput--monthVisitors" type="number" value="1000" min=0 />
    </span>
</label>

<label>
    <span>Subscriber/Lead value ($)</span>
    <span>
        <input class="js-expectedResultsInput js-expectedResultsInput--subVal" type="number" value="1.3" min=0 />
    </span>
</label>



<table class="expectedResultsTable js-expectedResultsTable">
    <thead class="expectedResultsThead">
        <tr class="expectedResultsTheadTr">
            <th class="expectedResultsTh">Expected Conversion Rate</th>
            <th class="expectedResultsTh">Extra monthly subscribers</th>
            <th class="expectedResultsTh">Extra monthly revenue</th>
            <th class="expectedResultsTh">Extra yearly revenue</th>
        </tr>
    </thead>
    <tbody class="expectedResultsTbody">
        <tr data-convrate=1 class="expectedResultsTbodyTr js-expectedResultsTbodyTr">
            <td class="expectedResultsTd">1%</td>
            <td class="expectedResultsTd js-expectedResultsTd js-expectedResultsTd--monthSubs"></td>
            <td class="expectedResultsTd js-expectedResultsTd js-expectedResultsTd--monthRev"></td>
            <td class="expectedResultsTd js-expectedResultsTd js-expectedResultsTd--yearRev"></td>
        </tr>
        <tr data-convrate=2 class="expectedResultsTbodyTr js-expectedResultsTbodyTr">
            <td class="expectedResultsTd">2%</td>
            <td class="expectedResultsTd js-expectedResultsTd js-expectedResultsTd--monthSubs"></td>
            <td class="expectedResultsTd js-expectedResultsTd js-expectedResultsTd--monthRev"></td>
            <td class="expectedResultsTd js-expectedResultsTd js-expectedResultsTd--yearRev"></td>
        </tr>
        <tr data-convrate=3 class="expectedResultsTbodyTr js-expectedResultsTbodyTr">
            <td class="expectedResultsTd">3%</td>
            <td class="expectedResultsTd js-expectedResultsTd...

CSS

* {
    margin: 0;
    padding: 0;
}

label,
label span,
label input {
    display: block;
}

label {
    margin-bottom: 1em;
}

label input {
    width: 100%;
}

body {
    margin: 30px auto;
    max-width: 300px;
}

.inputBlock {
    margin-bottom: 2em;
}

.estimationDefItem {
    margin-bottom: 1em;
}

.estimationDef {
    color: #777;
}

JavaScript

var $trs = $('.js-expectedResultsTbodyTr'),
    
    $inputs = $('.js-expectedResultsInput'),
    
    $visitorsInput = $('.js-expectedResultsInput--monthVisitors'),
    $subscriberValInput = $('.js-expectedResultsInput--subVal');

function onValChange() {
    var month_visitors = $visitorsInput.val(),
        sub_val = $subscriberValInput.val();
        
   updateTable(month_visitors, sub_val);
}

function calculateMonthSubs( month_visitors, cr ) {
    return Math.floor(month_visitors * cr / 100);
}

function updateTable( month_visitors, sub_val ) {
    $trs.each(function () {
        var $tr = $(this),
            cr = $tr.data('convrate'),
            extra_month_subs = calculateMonthSubs(month_visitors, +cr),
            extra_month_rev = extra_month_subs * sub_val,
            extra_year_rev = extra_month_rev * 12;
        

        extra_month_rev = extra_month_rev.toFixed(2) + '$';
        extra_year_rev = extra_year_rev.toFixed(2) + '$';
        
        $tr.find('.js-expectedResultsTd--monthSubs').text(extra_month_subs);
        $tr.find('.js-expectedResultsTd--monthRev').text(extra_month_rev);
        $tr.find('.js-expectedResultsTd--yearRev').text(extra_year_rev);
    });
}


$inputs
    .on({
        'change': onValChange,
        'keyup': onValChange
    })
    .eq(1).trigger('change');




 var str = "Congratulations! Not bad for something that takes minutes to setup.";