Template:Interactive calculator

 "use strict";

var twr = { fields: [ {id: 'l1tw',  label: 'L1TW:',  init: 3.9,  valid:/^[\d\.]+%?$/, format: '{}%'}, {id: 'l2tw',  label: 'L2TW:',  init: 30,   valid:/^[\d\.]+%?$/, format: '{}%'}, {id: 'yield', label: 'Yield:', init: 2,    valid:/^[\d\.]+%?$/, format: '{}%'}, {id: 'ter',   label: 'TER:',   init: 0.08, valid:/^[\d\.]+%?$/, format: '{}%'}, {id: 'result', label: 'TWR =', format: '{}%'} ], compute: function(v) { if (v.yield * (1 - v.l1tw/100) >= v.ter) v.result = (v.yield * v.l1tw/100) + ((v.yield * (1 - v.l1tw/100) - v.ter) * v.l2tw/100); else v.result = NaN; v.result = v.result.toFixed(4); } };

var calc_v1 = { name: 'calc_v1',

generate: function(handler, schema, prefix) { var styles = { field: 'border-style: solid; border-width: 1px; background-color: #ffffff', button: 'border-style: solid; border-width: 1px; background-color: #dcdcdc; padding: 4px; cursor: pointer' };   var invoke = handler.name + ".calculate('" + prefix + "')"; var fields = schema.fields;

var table = '[table id="' + prefix + 'table" class="wikitable"][tbody]' + '[tr]'; for (var field of fields) { if ('init' in field) { var init = field.format.replace('{}', field.init); table += '[td]' + field.label + ' ' + '[input type="text" style="' + styles.field + '" size="6" id="' + prefix + field.id + '"' + ' value="' + init + '" onchange="' + invoke + '" /]' + '[/td]'; }   }    field = fields[fields.length - 1]; table += '[/tr][tr]' + '[td][button style="' + styles.button + '" onclick="' + invoke + '"]Calculate[/button][/td]' + '[td]' + field.label + ' ' + '[input type="text" style="' + styles.field + '" size="6" id="' + prefix + field.id + '" readonly]' + '[/td]' + '[/tr]' + '[/tbody][/table]'; table = table.replace(/\[/g, '<').replace(/\]/g, '>'); if ('log' in calc_v1) console.log(table); return table; },

calculate: function(prefix) { var schema = window.calc_global[prefix]; var fields = schema.fields;

var get_values = function { var values = {}; for (var field of fields) { var value = document.getElementById(prefix + field.id).value; if (value.trim.match(field.valid)) values[field.id] = parseFloat(value); else values[field.id] = NaN; }     return values; };

var set_values = function(values) { var formats = {}; for (var field of fields) formats[field.id] = field.format; for (var id in values) { var value = values[id]; if (!isNaN(value)) value = formats[id].replace('{}', value); else value = 'Error!'; document.getElementById(prefix + id).value = value; }   };

var values = get_values; schema.compute(values); if ('log' in calc_v1) console.table(values); set_values(values); } };

var registrar = { register: function (handler, schema) { var write = function(string) { var scripts = document.getElementsByTagName('script'); var self = scripts[scripts.length - 1]; self.insertAdjacentHTML('beforebegin', string); }

if (!('calc_global' in window)) window.calc_global = {counter: 1};

var prefix = handler.name + '-' + window.calc_global.counter++ + '-'; window.calc_global[prefix] = schema;

write(handler.generate(handler, schema, prefix)); } };

registrar.register(calc_v1, twr);