JSFiddle - React, Tailwind, and code Playground
by mistakster
HTML
<script src="http://pozadi.github.io/kefir/dist/kefir.js"></script>
<table id="table">
<tr>
<td><input class="val"></td>
<td><input class="pct">%</td>
</tr>
<tr>
<td><input class="val"></td>
<td><input class="pct">%</td>
</tr>
<tr>
<td><input class="val"></td>
<td><input class="pct">%</td>
</tr>
<tr>
<td><input class="val"></td>
<td><input class="pct">%</td>
</tr>
<tr>
<td><input class="sum"></td>
<td><input readonly value="100">%</td>
</tr>
</table>
JavaScript
$(function () {
var $table = $('#table');
var streamVal = Kefir.fromBinder(function (emitter) {
function handler() {
var values = $.map($table.find('.val'), function (ele) {
return $(ele).val();
});
emitter.emit(values);
}
$table.on('change', '.val', handler);
return function () {
$table.off('change', '.val', handler);
};
});
var streamPct = Kefir.fromBinder(function (emitter) {
function handler() {
var $input = $(this);
var $row = $input.closest('tr');
var i = $table.find('tr').index($row);
emitter.emit({
pct: $input.val(),
index: i
});
}
$table.on('change', '.pct', handler);
return function () {
$table.off('change', '.pct', handler);
};
});
var streamSum = Kefir.fromBinder(function (emitter) {
function handler() {
emitter.emit($table.find('.sum').val());
}
$table.on('change', '.sum', handler);
return function () {
$table.off('change', '.sum', handler);
};
});
streamSum.onValue(function (sum) {
sum = parseFloat(sum);
if (isNaN(sum)) {
return;
}
// compute values
$table.find('.pct').each(function (i) {
var pct = parseFloat($(this).val());
$table.find('.val').eq(i)
.val(isNaN(pct) ? '' : (sum * pct / 100));
});
});
streamVal.onValue(function (values) {
// compute sum
var sum = values.reduce(function (memo, v) {
v = parseFloat(v);
return memo + (isNaN(v) ? 0 : v)
}, 0);
$table.find('.sum').val(sum);
// compute percentage
values.forEach(function (v, i) {
v = parseFloat(v);
$table.find('.pct').eq(i)
.val(isNaN(v) ? '' : (100 * v / sum));
});
});
streamPct.onValue(function (data) {
var $pct = $table.find('.pct');
var $val = $table.find('.val');
var other = $
.map($pct, function (ele, i) {
return {
pct: $(ele).val(),
index: i
}
})
.filter(function (d) {
return d.index != data.index
});
var otherSum = other.reduce(function (memo, v) {
v =...