Fri, 14 Jun 2019 20:28:26 +0200
Version 0.4.3 Major rework on priming sugars.
/***************************************************************************** * Copyright (C) 2018-2019 * * Michiel Broek <mbroek at mbse dot eu> * * This file is part of BMS * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * BrewCloud is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ThermFerm; see the file COPYING. If not, write to the Free * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ function createDelElements() { $('#eventWindow').jqxWindow({ theme: theme, position: { x: 490, y: 210 }, width: 300, height: 175, resizable: false, isModal: true, modalOpacity: 0.4, okButton: $('#delOk'), cancelButton: $('#delCancel'), initContent: function () { $('#delOk').jqxButton({ template: "danger", width: '65px', theme: theme }); $('#delCancel').jqxButton({ template: "success", width: '65px', theme: theme }); $('#delCancel').focus(); } }); $('#eventWindow').jqxWindow('hide'); } $(document).ready(function () { var to_100 = false; // Fermentables adjust to 100% var preboil_sg = 0; var psugar = 0; // Percentage real sugars var pcara = 0; // Percentage cara/crystal malts var svg = 77; // Default attenuation var mashkg = 0; // Malt in mash weight var hop_flavour = 0; var hop_aroma = 0; var mash_infuse = 0; var last_base = ''; var last_acid = ''; var MMCa = 40.048; var MMMg = 24.305; var MMNa = 22.98976928; var MMCl = 35.453; var MMSO4 = 96.0626; var MMCO3 = 60.01684; var MMHCO3 = 61.01684; var MMCaSO4 = 172.171; var MMCaCl2 = 147.015; var MMCaCO3 = 100.087; var MMMgSO4 = 246.475; var MMNaHCO3 = 84.007; var MMNa2CO3 = 105.996; var MMNaCl = 58.443; var MMCaOH2 = 74.06268; var fermentableRow = 0; var fermentableData = {}; var hopRow = 0; var hopData = {}; var miscRow = 0; var miscData = {}; var yeastRow = 0; var yeastData = {}; var mashRow = 0; var mashData = {}; /* * Remove the top menu so that we MUST use the buttons to leave the editor. */ $('#jqxMenu').jqxMenu('destroy'); console.log("record:" + my_record + " return:" + my_return + " theme:" + theme); $("#jqxLoader").jqxLoader({ width: 250, height: 150, isModal: true, text: "Laden recept ...", theme: theme }); function setReadonly(ro) { var rw = ! ro; var w100 = 110; var w80 = 80; if (ro) { // jqxNumberInput width -20 for no spinbuttons w100 = 90; w80 = 60; } $("#batch_size").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#boil_size").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#boil_time").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#efficiency").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#est_og").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); // id="st_fg_min" margin-left 15/35 maken $("#type").jqxDropDownList({ disabled: ro }); $("#styleSelect").jqxDropDownList({ disabled: ro }); $("#color_method").jqxDropDownList({ disabled: ro }); $("#ibu_method").jqxDropDownList({ disabled: ro }); $("#Delete").jqxButton({ disabled: ro }); $("#fermentableGrid").jqxGrid({ editable: rw }); $("#faddrowbutton").jqxDropDownList({ disabled: ro }); $("#finstockbutton").jqxCheckBox({ disabled: ro }); $("#fdeleterowbutton").jqxButton({ disabled: ro }); $("#hopGrid").jqxGrid({ editable: rw }); $("#haddrowbutton").jqxDropDownList({ disabled: ro }); $("#hinstockbutton").jqxCheckBox({ disabled: ro }); $("#hdeleterowbutton").jqxButton({ disabled: ro }); $("#miscGrid").jqxGrid({ editable: rw }); $("#maddrowbutton").jqxDropDownList({ disabled: ro }); $("#minstockbutton").jqxCheckBox({ disabled: ro }); $("#mdeleterowbutton").jqxButton({ disabled: ro }); $("#yeastGrid").jqxGrid({ editable: rw }); $("#yaddrowbutton").jqxDropDownList({ disabled: ro }); $("#yinstockbutton").jqxCheckBox({ disabled: ro }); $("#ydeleterowbutton").jqxButton({ disabled: ro }); $("#mashGrid").jqxGrid({ editable: rw }); $("#saddrowbutton").jqxButton({ disabled: ro }); $("#sdeleterowbutton").jqxButton({ disabled: ro }); $("#w1_name").jqxDropDownList({ disabled: ro }); $("#w2_name").jqxDropDownList({ disabled: ro }); $("#pr_name").jqxDropDownList({ disabled: ro }); $("#wa_cacl2").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#wa_caso4").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#wa_mgso4").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#wa_nacl").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#mash_ph").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#calc_acid").jqxCheckBox({ disabled: ro }); $("#wa_base_name").jqxDropDownList({ disabled: ro }); $("#wa_base").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#wa_acid_name").jqxDropDownList({ disabled: ro }); $("#wa_acid").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#wa_acid_perc").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w80 }); $("#sparge_temp").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#sparge_volume").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#sparge_ph").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); $("#sparge_source").jqxDropDownList({ disabled: ro }); $("#sparge_acid_type").jqxDropDownList({ disabled: ro }); $("#sparge_acid_perc").jqxNumberInput({ spinButtons: rw, readOnly: ro, width: w100 }); }; function calcPercentages() { console.log("calcPercentages()"); var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; if (rowscount > 1) { var tw = 0; for (i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_added < 4) tw += Math.round(rowdata.f_amount * 1000) / 1000; }; tw = Math.round(tw * 1000) / 1000; for (i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_added < 4) { var percentage = Math.round(rowdata.f_amount / tw * 1000) / 10.0; $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", percentage); } else { $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_percentage", 0); } }; } else { $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100); } } function calcFermentables() { console.log("calcFermentables()"); sugarsf = 0; // fermentable sugars mash + boil sugarsm = 0; // fermentable sugars in mash psugar = 0; pcara = 0; mashkg = 0; var vol = 0; // Volume sugars after boil var addedS = 0; // Added sugars after boil var addedmass = 0; // Added mass after boil var mvol = 0; // mash volume var colort = 0; // Colors srm * vol totals var colorh = 0; // Colors ebc * vol * kt var colorn = 0; // Colors ebc * pt * pct var my_100 = false; var mashtime = 0; // Total mash time var mashtemp = 0; // Average mash temperature var bv = 0.925; // Bierverlies rendement var sr = 0.95; // Mash en spoel rendement var lintner = 0; // Total recipe lintner if ((rows = $('#mashGrid').jqxGrid('getrows'))) { for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.step_type == 0) // Infusion mvol += parseFloat(row.step_infuse_amount); if (row.step_temp <= 75) { // Ignore mashout mashtime += row.step_time; mashtemp += row.step_time * row.step_temp; } } mashtemp = mashtemp / mashtime; } if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) { return; // grid not yet loaded. } var s = 0; for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.f_adjust_to_total_100) my_100 = true; if (row.f_type == 1 && row.f_added < 4) // Sugar psugar += row.f_percentage; if (row.f_graintype == 2 && row.f_added < 4) // Crystal pcara += row.f_percentage; var d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100); if (row.f_added == 0) { // Mash if (mvol > 0) { // Only if mash already known mvol += row.f_amount * row.f_moisture / 100; s += d; } d = parseFloat(dataRecord.efficiency) / 100 * d; sugarsm += d; mashkg += row.f_amount; } if (row.f_added == 0 || row.f_added == 1) // Mash or Boil sugarsf += d; if (row.f_added == 2 || row.f_added == 3) { // Fermentation or lagering var x = (row.f_yield / 100) * (1 - row.f_moisture / 100); addedS += row.f_amount * x; addedmass += row.f_amount; vol += (x * sugardensity + (1 - x) * 1) * row.f_amount; } if (row.f_added == 0 && (row.f_type == 0 || row.f_type == 4) && row.f_color < 50) { // Mash and Grain/Adjunct and Color < 50 lintner += row.f_diastatic_power * row.f_amount; } if (row.f_added < 4) { colort += row.f_amount * ebc_to_srm(row.f_color); colorh += row.f_amount * row.f_color * get_kt(row.f_color); colorn += (row.f_percentage / 100) * row.f_color; // For 8.6 Pt wort. } } $("#ferm_lintner").val(Math.round(parseFloat(lintner / mashkg))); console.log("lintner:"+lintner+" kg:"+mashkg); to_100 = my_100; if (to_100) { $("#wf_amount").jqxNumberInput({ width: 90, readOnly: true, spinButtons: false }); } else { $("#wf_amount").jqxNumberInput({ width: 110, readOnly: false, spinButtons: true }); } // Estimate total recipe OG. dataRecord.est_og = estimate_sg(sugarsf + addedS, parseFloat(dataRecord.batch_size)); $('#est_og').val(dataRecord.est_og); $('#est_og2').val(dataRecord.est_og); // Estimate SG in kettle before boil preboil_sg = estimate_sg(sugarsm, parseFloat(dataRecord.boil_size)); // Color of the wort if (dataRecord.color_method == 4) { var color = Math.round(((sg_to_plato(dataRecord.est_og) / 8.6) * colorn) + (dataRecord.boil_time / 60)); } else if (dataRecord.color_method == 3) { // Hans Halberstadt var color = Math.round((4.46 * bv * sr) / parseFloat(dataRecord.batch_size) * colorh); } else { var cw = colort / parseFloat(dataRecord.batch_size) * 8.34436; var color = kw_to_ebc(dataRecord.color_method, cw); } dataRecord.est_color = color; $('#est_color').val(color); $('#est_color2').val(color); var scolor = ebc_to_color(color); document.getElementById("bcolor").style.background= scolor; document.getElementById("bcolor2").style.background= scolor; // Progress bars pmalts = mashkg / (dataRecord.boil_size / 3) * 100; $("#perc_malts").jqxProgressBar('val', pmalts); $("#perc_sugars").jqxProgressBar('val', psugar); $("#perc_cara").jqxProgressBar('val', pcara); // Calculate estimated svg. svg = 0; // default. var rows = $('#yeastGrid').jqxGrid('getrows'); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.y_use == 0) { // Primary if (parseFloat(row.y_attenuation) > svg) svg = parseFloat(row.y_attenuation); // Take the highest if multiple yeasts. } // TODO: brett in secondary ?? } if (svg == 0) svg = 77; if ((mashkg > 0) && (mash_infuse > 0) && (mashtime > 0) && (mashtemp > 0)) { dataRecord.est_fg = estimate_fg(psugar, pcara, mash_infuse / mashkg, mashtime, mashtemp, svg, dataRecord.est_og); } else { dataRecord.est_fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, dataRecord.est_og); } $('#est_fg').val(dataRecord.est_fg); $('#est_fg2').val(dataRecord.est_fg); dataRecord.est_abv = abvol(dataRecord.est_og, dataRecord.est_fg); $("#est_abv").val(dataRecord.est_abv); $("#est_abv2").val(dataRecord.est_abv); }; function hopFlavourContribution(bt, vol, use, amount) { var result; if (use == 1) { // First wort result = 0.15; // assume 15% flavourcontribution for fwh } else if (bt > 50) { result = 0.10; // assume 10% flavourcontribution as a minimum } else { result = 15.25 / (6 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 21) /6, 2)); if (result < 0.10) result = 0.10; // assume 10% flavourcontribution as a minimum } return (result * amount * 1000) / vol; } function hopAromaContribution(bt, vol, use, amount) { var result = 0; if (use == 5) { // Dry hop result = 1.33; } else if (bt > 20) { result = 0; } else if (bt > 7.5) { result = 10.03 / (4 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 7.5) /4, 2)); } else if (use == 2) { // Boil result = 1; } else if (use == 3) { // Aroma / vlamuit result = 1.2; } else if (use == 4) { // Whirlpool result = 1.2; } return (result * amount * 1000) / vol; } function calcMash() { if (!(rows = $('#mashGrid').jqxGrid('getrows'))) return; if (mashkg == 0) return; var infused = 0; for (var i = 0; i < rows.length; i++) { var row = $("#mashGrid").jqxGrid('getrowdata', i); if (row.step_type == 0) // Infusion infused += row.step_infuse_amount; $("#mashGrid").jqxGrid('setcellvalue', i, "step_thickness", infused / mashkg); } } function calcIBUs() { var total_ibus = 0; hop_aroma = hop_flavour = 0; var rows = {}; if (!(rows = $('#hopGrid').jqxGrid('getrows'))) { return; } for (var i = 0; i < rows.length; i++) { var row = rows[i]; total_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.batch_size), parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method); hop_flavour += hopFlavourContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount)); hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount)); } total_ibus = Math.round(total_ibus * 10) / 10; hop_flavour = Math.round(hop_flavour * 1000 / 5) / 10; hop_aroma = Math.round(hop_aroma * 1000 / 6) / 10; if (hop_flavour > 100) hop_flavour = 100; if (hop_aroma > 100) hop_aroma = 100; console.log("calcIBUs(): " + total_ibus + " flavour: " + hop_flavour + " aroma: " + hop_aroma); dataRecord.est_ibu = total_ibus; $('#est_ibu').val(total_ibus); $('#est_ibu2').val(total_ibus); $("#hop_flavour").jqxProgressBar('val', hop_flavour); $("#hop_aroma").jqxProgressBar('val', hop_aroma); }; function adjustHops(factor) { console.log("adjustHops("+factor+")"); var rowscount = $("#hopGrid").jqxGrid('getdatainformation').rowscount; if (rowscount == 0) return; for (var i = 0; i < rowscount; i++) { var row = $("#hopGrid").jqxGrid('getrowdata', i); var amount = row.h_amount * factor; $("#hopGrid").jqxGrid('setcellvalue', i, "h_amount", amount); } }; function adjustMiscs(factor) { console.log("adjustMiscs("+factor+")"); var rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; if (rowscount == 0) return; for (var i = 0; i < rowscount; i++) { var row = $("#miscGrid").jqxGrid('getrowdata', i); var amount = row.m_amount * factor; $("#miscGrid").jqxGrid('setcellvalue', i, "m_amount", amount); switch (row.m_name) { case 'CaCl2': $("#wa_cacl2").val(row.m_amount * 1000); break; case 'CaSO4': $("#wa_caso4").val(row.m_amount * 1000); break; case 'MgSO4': $("#wa_mgso4").val(row.m_amount * 1000); break; case 'NaCl': $("#wa_nacl").val(row.m_amount * 1000); break; case 'Melkzuur': case 'Zoutzuur': case 'Fosforzuur': case 'Zwavelzuur': $("#wa_acid").val(row.m_amount * 1000); break; case 'NaHCO3': case 'Na2CO3': case 'CaCO3': case 'Ca(OH)2': $("#wa_base").val(row.m_amount * 1000); break; } } }; function adjustYeasts(factor) { console.log("adjustYeasts("+factor+")"); var rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; if (rowscount == 0) return; for (var i = 0; i < rowscount; i++) { var row = $("#yeastGrid").jqxGrid('getrowdata', i); if (row.y_form == 1) { // Only adjust dry yeast var amount = row.y_amount * factor; $("#yeastGrid").jqxGrid('setcellvalue', i, "y_amount", amount); } } }; function adjustWaters(factor) { console.log("adjustWaters("+factor+")"); var rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; if (rowscount == 0) return; mash_infuse = 0; for (var i = 0; i < rowscount; i++) { var row = $("#mashGrid").jqxGrid('getrowdata', i); if (row.step_type == 0) { // Infusion var amount = Math.round(row.step_infuse_amount * factor * 10) / 10; $("#mashGrid").jqxGrid('setcellvalue', i, "step_infuse_amount", amount); mash_infuse += amount; } } if (dataRecord.w2_amount == 0) { dataRecord.w1_amount = mash_infuse; $("#w1_amount").val(mash_infuse); } else { dataRecord.w1_amount = (dataRecord.w1_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; dataRecord.w2_amount = (dataRecord.w2_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; $("#w1_amount").val(dataRecord.w1_amount); $("#w2_amount").val(dataRecord.w2_amount); } $('#wg_amount').val(mash_infuse); }; function GetBUGU() { var gu = (dataRecord.est_og - 1) * 1000; if (gu > 0) return dataRecord.est_ibu / gu; else return 0.5; } function GetOptClSO4ratio() { var BUGU = GetBUGU(); return (-1.2 * BUGU + 1.4); } function setWaterAgent(name, amount) { //console.log("setWaterAgent(" + name + ", " + amount + ")"); var rows = $('#miscGrid').jqxGrid('getrows'); if (amount == 0) { for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.m_name == name) { var id = $("#miscGrid").jqxGrid('getrowid', i); var commit = $("#miscGrid").jqxGrid('deleterow', id); } } } else { var found = false; for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.m_name == name) { found = true; $("#miscGrid").jqxGrid('setcellvalue', i, 'm_amount', amount / 1000); break; } } if (! found) { var miscs = new $.jqx.dataAdapter(miscInvSource, { loadComplete: function () { var records = miscs.records; for (var i = 0; i < records.length; i++) { var record = records[i]; if (record.name == name) { var row = {}; row["m_name"] = record.name; row["m_amount"] = amount / 1000; row["m_cost"] = record.cost; row["m_type"] = record.type; row["m_use_use"] = record.use_use; row["m_time"] = 0; row["m_amount_is_weight"] = record.amount_is_weight; row["m_inventory"] = record.inventory; row["m_avail"] = 1; var commit = $("#miscGrid").jqxGrid('addrow', null, row); } } } }); miscs.dataBind(); return; } } } function setRangeIndicator(ion, rangeCode) { if ((rangeCode == "laag") || (rangeCode == "hoog")) $("#wr_"+ion).html("<img src='images/dialog-error.png'><span style='vertical-align: top; font-size: 10px; font-style: italic;'>"+rangeCode + "</span>"); else $("#wr_"+ion).html("<img src='images/dialog-ok-apply.png'>"); } function mix(v1, v2, c1, c2) { if ((v1 + v2) > 0) { return ((v1 * c1) + (v2 * c2)) / (v1 + v2); } return 0; } // mg/l as CaCO3 function ResidualAlkalinity(total_alkalinity, calcium, magnesium) { return total_alkalinity - (calcium / 1.4 + magnesium / 1.7); } var Ka1 = 0.0000004445; var Ka2 = 0.0000000000468; function PartCO3(pH) { var H = Math.pow(10, -pH); return 100 * Ka1 * Ka2 / (H*H + H * Ka1 + Ka1 * Ka2); } function PartHCO3(pH) { var H = Math.pow(10, -pH); return 100 * Ka1 * H / (H*H + H * Ka1 + Ka1 * Ka2); } function Charge(pH) { return (-2 * PartCO3(pH) - PartHCO3(pH)); } //Z alkalinity is the amount of acid (in mEq/l) needed to bring water to the target pH (Z pH) function ZAlkalinity(pHZ) { var C43 = Charge(4.3); var Cw = Charge(parseFloat($("#wg_ph").jqxNumberInput('decimal'))); var Cz = Charge(pHZ); var DeltaCNaught = -C43+Cw; var CT = parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')) / 50 / DeltaCNaught; var DeltaCZ = -Cz+Cw; return CT * DeltaCZ; } //Z Residual alkalinity is the amount of acid (in mEq/l) needed to bring the water in the mash to the target pH (Z pH) function ZRA(pHZ) { var Calc = parseFloat($("#wg_calcium").jqxNumberInput('decimal')) / (MMCa / 2); var Magn = parseFloat($("#wg_magnesium").jqxNumberInput('decimal')) / (MMMg / 2); var Z = ZAlkalinity(pHZ); return Z - (Calc / 3.5 + Magn / 7); } function ProtonDeficit(pHZ) { var Result = ZRA(pHZ) * parseFloat($("#wg_amount").jqxNumberInput('decimal')); // proton deficit for the grist var rows = $('#fermentableGrid').jqxGrid('getrows'); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt // Check if acid is required var C1 = 0; if ((row.f_di_ph != 5.7) && ((row.f_acid_to_ph_57 < - 0.1) || (row.f_acid_to_ph_57 > 0.1))) { C1 = row.f_acid_to_ph_57 / (row.f_di_ph - 5.7); } else { // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid. var ebc = row.f_color; switch (row.f_graintype) { case 0: // Base, Special, Kilned case 3: case 5: C1 = 0.014 * ebc - 34.192; break; case 2: C1 = -0.0597 * ebc - 32.457; // Crystal break; case 1: C1 = 0.0107 * ebc - 54.768; // Roast break; case 4: C1 = -149; // Sour malt break; } } x = C1 * (pHZ - row.f_di_ph); // AcidRequired(ZpH) Result += x * row.f_amount; } } return Result; } function MashpH() { var n = 0; var pH = 5.4; var deltapH = 0.001; var deltapd = 0.1; var pd = ProtonDeficit(pH); while (((pd < -deltapd) || (pd > deltapd)) && (n < 2000)) { n++; if (pd < -deltapd) pH -= deltapH; else if (pd > deltapd) pH += deltapH; pd = ProtonDeficit(pH); } console.log("MashpH() n: "+n+" pH: "+pH); return pH; } function GetAcidSpecs(AT) { switch(AT) { case 0: return { // Melkzuur pK1: 3.86, pK2: 20, pK3: 20, MolWt: 90.08, AcidSG: 1214, AcidPrc: 0.88 }; case 1: return { // Zoutzuur pK1: -7, pK2: 20, pK3: 20, MolWt: 36.46, AcidSG: 1142, AcidPrc: 0.28 }; case 2: return { // Fosforzuur pK1: 2.12, pK2: 7.20, pK3: 12.44, MolWt: 98.00, AcidSG: 1170, AcidPrc: 0.25 }; case 3: return { // Zwavelzuur pK1: -1, pK2: 1.92, pK3: 20, MolWt: 98.07, AcidSG: 1700, AcidPrc: 0.93 }; } console.log("Bummer, AT is " + AT); } // Procedure TFrmWaterAdjustment.CalcWater2; function calcWater() { console.log("calcWater()"); var liters = 0; var calcium = 0; var magnesium = 0; var sodium = 0; var total_alkalinity = 0; var bicarbonate = 0; var chloride = 0; var sulfate = 0; var ph = 0; var RA = 0; var acid = 0; var frac = 0; var TpH = 0; var protonDeficit = 0; if (dataRecord.w1_name == "") { return; } // Check for a recipe too. Fermentables, Mash schedule? // If there is a dillute water source, mix the waters. if (dataRecord.w2_name != "") { liters = dataRecord.w1_amount + dataRecord.w2_amount; calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium); magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium); sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium); chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride); sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate); total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity); ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters); } else { liters = dataRecord.w1_amount; calcium = dataRecord.w1_calcium; magnesium = dataRecord.w1_magnesium; sodium = dataRecord.w1_sodium; chloride = dataRecord.w1_chloride; sulfate = dataRecord.w1_sulfate; total_alkalinity = dataRecord.w1_total_alkalinity; ph = dataRecord.w1_ph; } $('#wg_amount').val(liters); var wg_calcium = calcium; $('#wg_calcium').val(Math.round(calcium * 10) / 10); var wg_magnesium = magnesium; $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); var wg_sodium = sodium; $('#wg_sodium').val(Math.round(sodium * 10) / 10); var wg_total_alkalinity = total_alkalinity; $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); var wg_chloride = chloride; $('#wg_chloride').val(Math.round(chloride * 10) / 10); var wg_sulfate = sulfate; $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); // Note: brouwhulp has the malts included here in the result. var wg_ph = ph; $('#wg_ph').val(Math.round(ph * 10) / 10); $('#wb_ph').val(Math.round(MashpH() * 10) / 10); bicarbonate = total_alkalinity * 1.22; var wg_bicarbonate = bicarbonate; // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. // Calculate Ca RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4; calcium += 1000 * RA / liters; // Calculate Mg RA = parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMMg / MMMgSO4; magnesium += 1000 * RA / liters; // Calculate Na RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl; sodium += 1000 * RA / liters; // Calculate SO4 RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4; sulfate += 1000 * RA / liters; // Calculate Cl RA = 2 * parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl; chloride += 1000 * RA / liters; // Einde noot. if ($("#wa_acid_name").val() < 0 || $("#wa_acid_name").val() > 3) { console.log("fix wa_acid_name"); $("#wa_acid_name").val(0); dataRecord.wa_acid_name = 0; } if (last_acid == '') last_acid = AcidTypeData[$("#wa_acid_name").val()].nl; if ($("#wa_base_name").val() < 0 || $("#wa_base_name").val() > 3) { console.log("fix wa_base_name"); $("#wa_base_name").val(0); dataRecord.wa_base_name = 0; } if (last_base == '') last_base = BaseTypeData[$("#wa_base_name").val()].nl; var AT = dataRecord.wa_acid_name; var BT = dataRecord.wa_base_name; var result = GetAcidSpecs(AT); var pK1 = result.pK1; var pK2 = result.pK2; var pK3 = result.pK3; var MolWt = result.MolWt; var AcidSG = result.AcidSG; var AcidPrc = result.AcidPrc; if (dataRecord.calc_acid) { TpH = parseFloat(dataRecord.mash_ph); protonDeficit = ProtonDeficit(TpH); console.log("calc_acid tgt: "+TpH+" protonDeficit: "+protonDeficit); if (protonDeficit > 0) { // Add acid $("#wa_base").val(0); setWaterAgent(last_base, 0); frac = CalcFrac(TpH, pK1, pK2, pK3); Acid = protonDeficit / frac; Acid *= MolWt; // mg Acidmg = Acid; Acid = Acid / AcidSG; // ml if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) $("#wa_acid_perc").val(AcidPrc); Acid = Acid * AcidPrc / (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml console.log("Final ml: "+Acid); $("#wa_acid").val(Math.round(Acid * 100) / 100); setWaterAgent(AcidTypeData[AT].nl, Math.round(Acid * 100) / 100); bicarbonate = bicarbonate - protonDeficit * frac / liters; total_alkalinity = bicarbonate * 50 / 61; } else if (protonDeficit < 0) { //Add base $("#wa_acid").val(0); setWaterAgent(last_acid, 0); var r1d = Math.pow(10, (TpH - 6.38)); var r2d = Math.pow(10, (TpH - 10.38)); var f1d = 1 / (1 + r1d + r1d * r2d); var f2d = f1d * r1d; var f3d = f2d * r2d; switch (BT) { case 0: RA = -protonDeficit / (f1d - f3d); //Sodiumbicarbonate, mmol totaal RA = RA * MMNaHCO3/1000; //gram $("#wa_base").val(Math.round(RA * 100) / 100); setWaterAgent('NaHCO3', Math.round(RA * 100) / 100); if (liters > 0) { // Na RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; RA = 1000 * RA / liters; sodium = wg_sodium + RA; // HCO3 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; RA = 1000 * RA / liters; bicarbonate = wg_bicarbonate + RA; total_alkalinity = bicarbonate * 50 / 61; RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); } break; case 1: RA = -protonDeficit / (2 * f1d + f2d); // Sodiumcarbonate, mmol totaal RA = RA * MMNa2CO3/1000; //gram $("#wa_base").val(Math.round(RA * 100) / 100); setWaterAgent('Na2CO3', Math.round(RA * 100) / 100); if (liters > 0) { RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; RA = 1000 * RA / liters; sodium = wg_sodium + RA; // HCO3 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; RA = 1000 * RA / liters; bicarbonate = wg_bicarbonate + RA; total_alkalinity = bicarbonate * 50 / 61; RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); } break; case 2: RA = -protonDeficit * (f1d - f3d); // Calciumcarbonate, mmol totaal RA = RA * MMCaCO3/1000; //gram //but only 1/3 is effective, so add 3 times as much RA = 3 * RA; $("#wa_base").val(Math.round(RA * 100) / 100); setWaterAgent('CaCO3', Math.round(RA * 100) / 100); if (liters > 0) { //Bicarbonate RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; RA = 1000 * RA / liters; bicarbonate = wg_bicarbonate + RA; total_alkalinity = bicarbonate * 50 / 61; //Ca precipitates out as Ca10(PO4)6(OH)2 RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; RA = 1000 * RA / liters; calcium = wg_calcium + RA; RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); } break; case 3: RA = -protonDeficit / 19.3; // Calciumhydroxide $("#wa_base").val(Math.round(RA * 100) / 100); setWaterAgent('Ca(OH)2', Math.round(RA * 100) / 100); if (liters > 0) { // Bicarbonate RA = -protonDeficit / liters; total_alkalinity = wg_total_alkalinity + RA; bicarbonate = total_alkalinity * 61 / 50; // Calcium RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaOH2; RA = 1000 * RA / liters; calcium = wg_calcium + RA; RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); } break; } } ph = TpH; $('#wb_ph').val(Math.round(ph * 10) / 10); } else { // Manual console.log("calc_acid no"); // First add base salts if (parseFloat($("#wa_base").jqxNumberInput('decimal')) > 0) { if (liters > 0) { switch (BT) { case 0: // Sodiumbicarbonate, Na RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; RA = 1000 * RA / liters; sodium = wg_sodium + RA; // HCO3 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; RA = 1000 * RA / liters; bicarbonate = wg_bicarbonate + RA; total_alkalinity = bicarbonate * 50 / 61; RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); break; case 1: // Sodiumcarbonate RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; RA = 1000 * RA / liters; sodium = wg_sodium + RA; // HCO3 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; RA = 1000 * RA / liters; bicarbonate = wg_bicarbonate + RA; total_alkalinity = bicarbonate * 50 / 61; RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); break; case 2: // Calciumcarbonate: Bicarbonate RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; RA = 1000 * RA / liters; bicarbonate = wg_bicarbonate + RA; total_alkalinity = bicarbonate * 50 / 61; RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); // Ca RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; RA = 1000 * RA / liters; calcium = wg_calcium + RA; break; } } } TpH = parseFloat(dataRecord.mash_ph); pHa = MashpH(); // This one is in demi water, should be in adjusted water??? // Then calculate the new pH with added acids if (parseFloat($("#wa_acid").jqxNumberInput('decimal')) > 0) { console.log("TpH: "+TpH+" water: "+pHa); Acid = parseFloat($("#wa_acid").jqxNumberInput('decimal')); if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) $("#wa_acid_perc").val(AcidPrc); Acid = Acid / AcidPrc * (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml Acid *= AcidSG; // ml Acid /= MolWt; // mg Acidmg = Acid; //find the pH where the protondeficit = protondeficit by the acid frac = CalcFrac(pHa, pK1, pK2, pK3); protonDeficit = Acid * frac; var deltapH = 0.001; var deltapd = 0.1; var pd = ProtonDeficit(pHa); var n = 0; while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 2000)) { n++; if (pd < (protonDeficit-deltapd)) pHa -= deltapH; else if (pd > (protonDeficit+deltapd)) pHa += deltapH; frac = CalcFrac(pHa, pK1, pK2, pK3); protonDeficit = Acid * frac; pd = ProtonDeficit(pHa); } console.log("n: "+n+" pd: "+pd+" protonDeficit: "+protonDeficit+" frac: "+frac+" pHa: "+pHa); RA = wg_bicarbonate - protonDeficit * frac / liters; bicarbonate = RA; total_alkalinity = RA * 50 / 61; ph = pHa; $('#wb_ph').val(Math.round(ph * 10) / 10); } } if ((AT == 3) && (liters > 0)) { // Sulfuctic / Zwavelzuur RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 + Acidmg / 1000 * MMSO4 / (MMSO4 + 2); RA = 1000 * RA / liters; sulfate = wg_sulfate + RA; // Not add to sulfate?? } else if ((AT == 1) && (liters > 0)) { // Hydrochloric, Zoutzuur RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl + Acidmg / 1000 * MMCl / (MMCl + 1); RA = 1000 * RA / liters; chloride = wg_chloride + RA; } // 2:1 Sulfate to Chroride IPA's, Pale Ales. // 1:1 Sulfate to Chloride Balanced // 1:2 Sulfate to Chloride Malty // Note, values below are the other way, cl to so4! // So: 0.5 is IPA's, Pale Ales. // 1 Balanced // 2 Malty. $('#tgt_bu').val(Math.round(GetBUGU() * 100) / 100); // From brouwhulp. if (GetBUGU() < 0.32) $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig en zoet</span>"); else if (GetBUGU() < 0.43) $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig, zoet</span>"); else if (GetBUGU() < 0.52) $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Evenwichtig</span>"); else if (GetBUGU() < 0.63) $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht hoppig, bitter</span>"); else $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Extra hoppig, zeer bitter</span>"); $('#tgt_cl_so4').val(Math.round(GetOptClSO4ratio() * 10) / 10); if (sulfate > 0) RA = chloride / sulfate; else RA = 10; $('#got_cl_so4').val(Math.round(RA * 10) / 10); var piCLSO4_low = 0.8 * GetOptClSO4ratio(); var piCLSO4_high = 1.2 * GetOptClSO4ratio(); var Res = 'normaal'; if (RA < piCLSO4_low) Res = 'laag'; else if (RA > piCLSO4_high) Res = 'hoog'; setRangeIndicator('cl_so4', Res); $('#wb_calcium').val(Math.round(calcium * 10) / 10); $('#wb_magnesium').val(Math.round(magnesium * 10) / 10); $('#wb_sodium').val(Math.round(sodium * 10) / 10); $('#wb_sulfate').val(Math.round(sulfate * 10) / 10); $('#wb_chloride').val(Math.round(chloride * 10) / 10); $('#wb_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); if (calcium < 40) { setRangeIndicator("calcium", "laag"); } else if (calcium > 150) { setRangeIndicator("calcium", "hoog"); } else { setRangeIndicator("calcium", "normaal"); } if (magnesium >= 0 && magnesium <= 30) { setRangeIndicator("magnesium", "normaal"); } else { setRangeIndicator("magnesium", "hoog"); } if (sodium <= 150) { setRangeIndicator("sodium", "normaal"); } else { setRangeIndicator("sodium", "hoog"); } // Both chloride and sulfate should be above 50 according to // John Palmer. So the Cl/SO4 ratio calculation will work. if (chloride <= 50) { setRangeIndicator("chloride", "laag"); } else if (chloride <= 100) { setRangeIndicator("chloride", "normaal"); } else { setRangeIndicator("chloride", "hoog"); } if (sulfate <= 50) { setRangeIndicator("sulfate", "laag"); } else if (sulfate <= 350) { setRangeIndicator("sulfate", "normaal"); } else { setRangeIndicator("sulfate", "hoog"); } if (ph < 5.2) { setRangeIndicator("ph", "laag"); } else if (ph > 5.6) { setRangeIndicator("ph", "hoog"); } else { setRangeIndicator("ph", "normaal"); } calcSparge(); } function calcSparge() { // Code from BrewBuddy/Brouwhulp, who got it from http://www.brewery.org/brewery/library/Acidi0,00fWaterAJD0497.html var TargetpH = dataRecord.sparge_ph; var Source_pH = dataRecord.w1_ph; var Source_alkalinity = dataRecord.w1_total_alkalinity; // Select watersource or fallback to the first source. if (dataRecord.sparge_source == 1) { // Source 2 if (dataRecord.w2_ph > 0.0) { Source_pH = dataRecord.w2_ph; Source_alkalinity = dataRecord.w2_total_alkalinity; } else { dataRecord.sparge_source = 0; // Source 1 $("#sparge_source").val(0); } } else if (dataRecord.sparge_source == 2) { // Mixed if (dataRecord.w2_ph > 0.0) { Source_pH = parseFloat($("#wg_ph").jqxNumberInput('decimal')); Source_alkalinity = parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')); } else { dataRecord.sparge_source = 0; $("#sparge_source").val(0); } } //console.log("calcSparge() target pH: "+TargetpH+" Source: "+Source_pH+" alkalinity: "+Source_alkalinity); // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH var r1 = Math.pow(10, Source_pH - 6.38); var r2 = Math.pow(10, Source_pH - 10.373); var d = 1 + r1 + r1*r2; var f1 = 1/d; var f2 = r1/d; var f3 = r1 * r2 / d; //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) var r143 = Math.pow(10, 4.3 - 6.38); var r243 = Math.pow(10, 4.3 - 10.373); var d43 = 1 + r143 + r143*r243; var f143 = 1/d43; var f243 = r143 / d43; var f343 = r143 * r243 / d43; //Step 3. Convert the sample alkalinity to milliequivalents/L var alkalinity = Source_alkalinity / 50; //Step 4. Solve var Ct = (alkalinity - 1000 * (Math.pow(10, -4.3) - Math.pow(10, -Source_pH))) / ((f143-f1)+(f3-f343)); //Step 5. Compute mole fractions at desired pH var r1g = Math.pow(10, TargetpH - 6.38); var r2g = Math.pow(10, TargetpH - 10.373); var dg = 1 + r1g + r1g*r2g; var f1g = 1/dg; var f2g = r1g / dg; var f3g = r1g * r2g / dg; //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) var Acid = Ct * ((f1g-f1)+(f3-f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l Acid += 0.01; // Add acid that would be required for distilled water. if (dataRecord.sparge_acid_type < 0 || dataRecord.sparge_acid_type > 3) { dataRecord.sparge_acid_type = 0; $("#sparge_acid_type").val(0); } //Step 8. Get the acid data. var AT = dataRecord.sparge_acid_type; var result = GetAcidSpecs(AT); var pK1 = result.pK1; var pK2 = result.pK2; var pK3 = result.pK3; var MolWt = result.MolWt; var AcidSG = result.AcidSG; var AcidPrc = result.AcidPrc; var fract = CalcFrac(TargetpH, pK1, pK2, pK3); //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. Acid /= fract; //Step 10. Multiply by molecular weight of the acid Acid *= MolWt; //mg Acid = Acid / AcidSG; //ml ; 88% lactic solution var f1 = dataRecord.sparge_acid_perc; if (f1 <= 0.1) f1 = AcidPrc; Acid = Acid * AcidPrc / (f1 / 100); Acid *= dataRecord.sparge_volume; //ml lactic acid total Acid = Math.round(Acid * 100) / 100; dataRecord.sparge_acid_amount = Acid / 1000; $("#sparge_acid_amount").val(Acid); } /* * Change OG of recipe but keep the water volumes. */ function calcFermentablesFromOG(OG) { console.log("calcFermentablesFromOG("+OG+")"); var efficiency = parseFloat($("#efficiency").jqxNumberInput('decimal')); var sug = sg_to_plato(OG) * parseFloat($("#batch_size").jqxNumberInput('decimal')) * OG / 100; //total amount of sugars in kg var tot = 0; var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; for (var i = 0; i < rowscount; i++) { var row = $("#fermentableGrid").jqxGrid('getrowdata', i); if (row.f_added < 4) { var d = row.f_percentage / 100 * (row.f_yield / 100) * (1 - row.f_moisture / 100); if (row.f_added == 0) // Mash d = efficiency / 100 * d; tot += d; } } var totmass = 0; if (tot) totmass = Math.round((sug / tot) * 1000) / 1000; if (totmass) { for (i = 0; i < rowscount; i++) { var row = $("#fermentableGrid").jqxGrid('getrowdata', i); if (row.f_added < 4) { var amount = Math.round(row.f_percentage * 10 * totmass) / 1000; $("#fermentableGrid").jqxGrid('setcellvalue', i, "f_amount", amount); } } } }; function calcInit () { console.log("calc.init()"); $("#calc_acid").on('checked', function (event) { dataRecord.calc_acid = 1; calcWater(); }); $("#calc_acid").on('unchecked', function (event) { dataRecord.calc_acid = 0; calcWater(); }); $("#w1_name").jqxDropDownList('selectItem', dataRecord.w1_name); $("#w2_name").jqxDropDownList('selectItem', dataRecord.w2_name); // Fix tap water if zero using mash infuse amount. if (parseFloat($("#w1_amount").jqxNumberInput('decimal')) == 0 && mash_infuse > 0) { $("#w1_amount").val(mash_infuse); dataRecord.w1_amount = mash_infuse; $("#wg_amount").val(mash_infuse); $("#w2_amount").val(0); dataRecord.w2_amount = 0; } calcWater(); $("#w2_amount").on('change', function (event) { var newval = parseFloat(event.args.value); if (newval > mash_infuse) { $("#w2_amount").val(dataRecord.w2_amount); return; } dataRecord.w1_amount = parseFloat($("#wg_amount").jqxNumberInput('decimal')) - newval; $("#w1_amount").val(dataRecord.w1_amount); dataRecord.w2_amount = newval; console.log("new: "+event.args.value+" w1: "+dataRecord.w1_amount+" w2: "+dataRecord.w2_amount); calcWater(); }); $('#wa_cacl2').on('change', function (event) { if (event.args) { setWaterAgent('CaCl2', 0); // This can prevent double entries. setWaterAgent('CaCl2', event.args.value); calcWater(); } }); $('#wa_caso4').on('change', function (event) { if (event.args) { setWaterAgent('CaSO4', 0); setWaterAgent('CaSO4', event.args.value); calcWater(); } }); $('#wa_mgso4').on('change', function (event) { if (event.args) { setWaterAgent('MgSO4', 0); setWaterAgent('MgSO4', event.args.value); calcWater(); } }); $('#wa_nacl').on('change', function (event) { if (event.args) { setWaterAgent('NaCl', 0); setWaterAgent('NaCl', event.args.value); calcWater(); } }); $('#wa_base_name').on('change', function (event) { if (event.args) { var index = event.args.index; console.log("wa_base_name "+index); setWaterAgent(last_base, 0); last_base = BaseTypeData[index].nl; setWaterAgent(last_base, parseFloat($("#wa_base").jqxNumberInput('decimal'))); dataRecord.wa_base_name = index; calcWater(); } }); $('#wa_base').on('change', function (event) { var name = BaseTypeData[$("#wa_base_name").val()].nl; setWaterAgent(name, parseFloat(event.args.value)); calcWater(); }); $('#wa_acid_name').on('change', function (event) { if (event.args) { var index = event.args.index; console.log("wa_acid_name "+index); setWaterAgent(last_acid, 0); last_acid = AcidTypeData[index].nl; setWaterAgent(last_acid, parseFloat($("#wa_acid").jqxNumberInput('decimal'))); dataRecord.wa_acid_name = index; calcWater(); } }); $('#wa_acid').on('change', function (event) { var name = AcidTypeData[$("#wa_acid_name").val()].nl; setWaterAgent(name, parseFloat(event.args.value)); calcWater(); }); $('#wa_acid_perc').on('change', function (event) { calcWater(); }); $('#color_method').on('change', function (event) { dataRecord.color_method = event.args.index; calcFermentables(); }); $('#ibu_method').on('change', function (event) { dataRecord.ibu_method = event.args.index; calcFermentables(); calcIBUs(); }); $('#batch_size').on('change', function (event) { console.log("batch_size change:"+event.args.value+" old:"+dataRecord.batch_size); var new_boil = parseFloat(event.args.value) + dataRecord.boil_size - dataRecord.batch_size; var factor = parseFloat(event.args.value) / dataRecord.batch_size; dataRecord.boil_size = new_boil; $("#boil_size").val(Math.round(new_boil * 100) / 100); dataRecord.sparge_volume *= factor; $("#sparge_volume").val(dataRecord.sparge_volume); dataRecord.batch_size = parseFloat(event.args.value); calcFermentablesFromOG(parseFloat($("#est_og").jqxNumberInput('decimal'))); // Keep the OG adjustWaters(factor); calcFermentables(); adjustHops(factor); adjustMiscs(factor); adjustYeasts(factor); calcIBUs(); calcWater(); calcSparge(); calcMash(); }); $('#boil_time').on('change', function (event) { console.log("boil_time change:"+parseFloat(event.args.value)+" old:"+dataRecord.boil_time); var old_evap = parseFloat(dataRecord.boil_size) - parseFloat(dataRecord.batch_size); var new_evap = old_evap * (parseFloat(event.args.value) / dataRecord.boil_time); var new_boil = parseFloat(dataRecord.batch_size) + new_evap; // console.log("old_evap:"+old_evap+" new_evap:"+new_evap+" new_boil:"+new_boil); dataRecord.boil_time = parseFloat(event.args.value); dataRecord.boil_size = new_boil; $("#boil_size").val(Math.round(new_boil * 100) / 100); calcFermentables(); // TODO: adjust the hops, miscs, yeast, water. calcIBUs(); }); $('#efficiency').on('change', function (event) { var estog = parseFloat($("#est_og").jqxNumberInput('decimal')); dataRecord.efficiency = parseFloat(event.args.value); console.log("efficiency change:"+dataRecord.efficiency); calcFermentablesFromOG(estog); // Keep the OG calcFermentables(); calcIBUs(); }); $('#est_og').on('change', function (event) { dataRecord.est_og = parseFloat(event.args.value); console.log("est_og change:"+dataRecord.est_og); calcFermentablesFromOG(dataRecord.est_og); // Adjust fermentables amounts calcFermentables(); // Update the recipe details calcIBUs(); // and the IBU's. calcMash(); }); $('#mash_ph').on('change', function (event) { dataRecord.mash_ph = parseFloat(event.args.value); calcWater(); }); $('#sparge_ph').on('change', function (event) { dataRecord.sparge_ph = parseFloat(event.args.value); calcSparge(); }); $('#sparge_volume').on('change', function (event) { dataRecord.sparge_volume = parseFloat(event.args.value); calcSparge(); }); $('#sparge_source').on('change', function (event) { if (event.args) { var index = event.args.index; dataRecord.sparge_source= index; calcSparge(); } }); $('#sparge_acid_type').on('change', function (event) { if (event.args) { var index = event.args.index; dataRecord.sparge_acid_type = index; console.log("new sparge_acid_type: "+dataRecord.sparge_acid_type); calcSparge(); } }); $('#sparge_acid_perc').on('change', function (event) { dataRecord.sparge_acid_perc = parseFloat(event.args.value); calcSparge(); }); $('#locked').on('checked', function (event) { dataRecord.locked = 1; setReadonly(true); }); $('#locked').on('unchecked', function (event) { dataRecord.locked = 0; setReadonly(false); }); // setReadonly(false); }; $("#styleSelect").jqxDropDownList({ placeHolder: "Kies bierstijl:", theme: theme, source: styleslist, displayMember: "name", width: 180, height: 23, dropDownVerticalAlignment: 'top', dropDownWidth: 500, dropDownHeight: 380, renderer: function (index, label, value) { var datarecord = styleslist.records[index]; return datarecord.style_guide + " " + datarecord.style_letter+ " " + datarecord.name; } }); $("#styleSelect").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = styleslist.records[index]; $("#st_name").val(datarecord.name); $("#st_category").val(datarecord.category); $("#st_category_number").val(datarecord.category_number); $("#st_letter").val(datarecord.style_letter); $("#st_guide").val(datarecord.style_guide); $("#st_type").val(StyleTypeData[datarecord.type].nl); $("#st_og_min").val(datarecord.og_min); $("#st_og_max").val(datarecord.og_max); $("#st_fg_min").val(datarecord.fg_min); $("#st_fg_max").val(datarecord.fg_max); $("#st_ibu_min").val(datarecord.ibu_min); $("#st_ibu_max").val(datarecord.ibu_max); $("#st_color_min").val(datarecord.color_min); $("#st_color_max").val(datarecord.color_max); $("#st_carb_min").val(datarecord.carb_min); $("#st_carb_max").val(datarecord.carb_max); $("#st_abv_min").val(datarecord.abv_min); $("#st_abv_max").val(datarecord.abv_max); } }); function saveRecord() { var fermentablerow = $('#fermentableGrid').jqxGrid('getrows'); var hoprow = $('#hopGrid').jqxGrid('getrows'); var miscrow = $('#miscGrid').jqxGrid('getrows'); var yeastrow = $('#yeastGrid').jqxGrid('getrows'); var mashrow = $('#mashGrid').jqxGrid('getrows'); var row = { record: my_record, uuid: dataRecord.uuid, name: $("#name").val(), locked: dataRecord.locked, notes: $("#notes").val(), st_name: $('#st_name').val(), st_letter: $('#st_letter').val(), st_guide: $('#st_guide').val(), st_type: dataRecord.st_type, st_category: $('#st_category').val(), st_category_number: parseFloat($("#st_category_number").jqxNumberInput('decimal')), st_og_min: parseFloat($("#st_og_min").jqxNumberInput('decimal')), st_og_max: parseFloat($("#st_og_max").jqxNumberInput('decimal')), st_fg_min: parseFloat($("#st_fg_min").jqxNumberInput('decimal')), st_fg_max: parseFloat($("#st_fg_max").jqxNumberInput('decimal')), st_ibu_min: parseFloat($("#st_ibu_min").jqxNumberInput('decimal')), st_ibu_max: parseFloat($("#st_ibu_max").jqxNumberInput('decimal')), st_color_min: parseFloat($("#st_color_min").jqxNumberInput('decimal')), st_color_max: parseFloat($("#st_color_max").jqxNumberInput('decimal')), st_carb_min: parseFloat($("#st_carb_min").jqxNumberInput('decimal')), st_carb_max: parseFloat($("#st_carb_max").jqxNumberInput('decimal')), st_abv_min: parseFloat($("#st_abv_min").jqxNumberInput('decimal')), st_abv_max: parseFloat($("#st_abv_max").jqxNumberInput('decimal')), type: $("#type").val(), batch_size: parseFloat($("#batch_size").jqxNumberInput('decimal')), boil_size: parseFloat($("#boil_size").jqxNumberInput('decimal')), boil_time: parseFloat($("#boil_time").jqxNumberInput('decimal')), efficiency: parseFloat($("#efficiency").jqxNumberInput('decimal')), est_og: parseFloat($("#est_og").jqxNumberInput('decimal')), est_fg: parseFloat($("#est_fg").jqxNumberInput('decimal')), est_abv: parseFloat($("#est_abv").jqxNumberInput('decimal')), est_color: parseFloat($("#est_color").jqxNumberInput('decimal')), color_method: $("#color_method").val(), est_ibu: parseFloat($("#est_ibu").jqxNumberInput('decimal')), ibu_method: $("#ibu_method").val(), est_carb: parseFloat($("#est_carb").jqxNumberInput('decimal')), mash_name: $("#mash_name").val(), mash_ph: parseFloat($("#mash_ph").jqxNumberInput('decimal')), sparge_temp: parseFloat($("#sparge_temp").jqxNumberInput('decimal')), sparge_ph: parseFloat($("#sparge_ph").jqxNumberInput('decimal')), sparge_volume: parseFloat($("#sparge_volume").jqxNumberInput('decimal')), sparge_source: $("#sparge_source").val(), sparge_acid_type: $("#sparge_acid_type").val(), sparge_acid_perc: parseFloat($("#sparge_acid_perc").jqxNumberInput('decimal')), sparge_acid_amount: dataRecord.sparge_acid_amount, calc_acid: dataRecord.calc_acid, w1_name: $("#w1_name").val(), w1_amount: parseFloat($("#w1_amount").jqxNumberInput('decimal')), w1_calcium: parseFloat($("#w1_calcium").jqxNumberInput('decimal')), w1_sulfate: parseFloat($("#w1_sulfate").jqxNumberInput('decimal')), w1_chloride: parseFloat($("#w1_chloride").jqxNumberInput('decimal')), w1_sodium: parseFloat($("#w1_sodium").jqxNumberInput('decimal')), w1_magnesium: parseFloat($("#w1_magnesium").jqxNumberInput('decimal')), w1_total_alkalinity: parseFloat($("#w1_total_alkalinity").jqxNumberInput('decimal')), w1_ph: parseFloat($("#w1_ph").jqxNumberInput('decimal')), w1_cost: dataRecord.w1_cost, w2_name: $("#w2_name").val(), w2_amount: parseFloat($("#w2_amount").jqxNumberInput('decimal')), w2_calcium: parseFloat($("#w2_calcium").jqxNumberInput('decimal')), w2_sulfate: parseFloat($("#w2_sulfate").jqxNumberInput('decimal')), w2_chloride: parseFloat($("#w2_chloride").jqxNumberInput('decimal')), w2_sodium: parseFloat($("#w2_sodium").jqxNumberInput('decimal')), w2_magnesium: parseFloat($("#w2_magnesium").jqxNumberInput('decimal')), w2_total_alkalinity: parseFloat($("#w2_total_alkalinity").jqxNumberInput('decimal')), w2_ph: parseFloat($("#w2_ph").jqxNumberInput('decimal')), w2_cost: dataRecord.w2_cost, wg_amount: parseFloat($("#wg_amount").jqxNumberInput('decimal')), wg_calcium: parseFloat($("#wg_calcium").jqxNumberInput('decimal')), wg_sulfate: parseFloat($("#wg_sulfate").jqxNumberInput('decimal')), wg_chloride: parseFloat($("#wg_chloride").jqxNumberInput('decimal')), wg_sodium: parseFloat($("#wg_sodium").jqxNumberInput('decimal')), wg_magnesium: parseFloat($("#wg_magnesium").jqxNumberInput('decimal')), wg_total_alkalinity: parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')), wg_ph: parseFloat($("#wg_ph").jqxNumberInput('decimal')), wb_calcium: parseFloat($("#wb_calcium").jqxNumberInput('decimal')), wb_sulfate: parseFloat($("#wb_sulfate").jqxNumberInput('decimal')), wb_chloride: parseFloat($("#wb_chloride").jqxNumberInput('decimal')), wb_sodium: parseFloat($("#wb_sodium").jqxNumberInput('decimal')), wb_magnesium: parseFloat($("#wb_magnesium").jqxNumberInput('decimal')), wb_total_alkalinity: parseFloat($("#wb_total_alkalinity").jqxNumberInput('decimal')), wb_ph: parseFloat($("#wb_ph").jqxNumberInput('decimal')), wa_acid_name: $("#wa_acid_name").val(), wa_acid_perc: parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')), wa_base_name: $("#wa_base_name").val(), fermentables: fermentablerow, hops: hoprow, miscs: miscrow, yeasts: yeastrow, mashs: mashrow }; var data = "update=true&" + $.param(row); $.ajax({ dataType: 'json', url: url, cache: false, async: false, data: data, type: "POST", success: function (data, status, xhr) { console.log("saveRecord() success"); }, error: function(jqXHR, textStatus, errorThrown) { console.log("saveRecord() error"); } }); }; var dataRecord = {}; var url = "includes/db_recipes.php"; // prepare the data var source = { datatype: "json", cache: false, datafields: [ { name: 'record', type: 'number' }, { name: 'uuid', type: 'string' }, { name: 'locked', type: 'int' }, { name: 'st_name', type: 'string' }, { name: 'st_letter', type: 'string' }, { name: 'st_guide', type: 'string' }, { name: 'st_type', type: 'int' }, { name: 'st_category', type: 'string' }, { name: 'st_category_number', type: 'float' }, { name: 'st_og_min', type: 'float' }, { name: 'st_og_max', type: 'float' }, { name: 'st_fg_min', type: 'float' }, { name: 'st_fg_max', type: 'float' }, { name: 'st_ibu_min', type: 'float' }, { name: 'st_ibu_max', type: 'float' }, { name: 'st_color_min', type: 'float' }, { name: 'st_color_max', type: 'float' }, { name: 'st_carb_min', type: 'float' }, { name: 'st_carb_max', type: 'float' }, { name: 'st_abv_min', type: 'float' }, { name: 'st_abv_max', type: 'float' }, { name: 'name', type: 'string' }, { name: 'notes', type: 'string' }, { name: 'type', type: 'int' }, { name: 'batch_size', type: 'float' }, { name: 'boil_size', type: 'float' }, { name: 'boil_time', type: 'float' }, { name: 'efficiency', type: 'float' }, { name: 'est_og', type: 'float' }, { name: 'est_fg', type: 'float' }, { name: 'est_abv', type: 'float' }, { name: 'est_color', type: 'float' }, { name: 'color_method', type: 'int' }, { name: 'est_ibu', type: 'float' }, { name: 'ibu_method', type: 'int' }, { name: 'est_carb', type: 'float' }, { name: 'sparge_temp', type: 'float' }, { name: 'sparge_ph', type: 'float' }, { name: 'sparge_volume', type: 'float' }, { name: 'sparge_source', type: 'int' }, { name: 'sparge_acid_type', type: 'int' }, { name: 'sparge_acid_perc', type: 'float' }, { name: 'sparge_acid_amount', type: 'float' }, { name: 'mash_ph', type: 'float' }, { name: 'mash_name', type: 'string' }, { name: 'calc_acid', type: 'int' }, { name: 'w1_name', type: 'string' }, { name: 'w1_amount', type: 'float' }, { name: 'w1_calcium', type: 'float' }, { name: 'w1_sulfate', type: 'float' }, { name: 'w1_chloride', type: 'float' }, { name: 'w1_sodium', type: 'float' }, { name: 'w1_magnesium', type: 'float' }, { name: 'w1_total_alkalinity', type: 'float' }, { name: 'w1_ph', type: 'float' }, { name: 'w1_cost', type: 'float' }, { name: 'w2_name', type: 'string' }, { name: 'w2_amount', type: 'float' }, { name: 'w2_calcium', type: 'float' }, { name: 'w2_sulfate', type: 'float' }, { name: 'w2_chloride', type: 'float' }, { name: 'w2_sodium', type: 'float' }, { name: 'w2_magnesium', type: 'float' }, { name: 'w2_total_alkalinity', type: 'float' }, { name: 'w2_ph', type: 'float' }, { name: 'w2_cost', type: 'float' }, { name: 'wg_amount', type: 'float' }, { name: 'wg_calcium', type: 'float' }, { name: 'wg_sulfate', type: 'float' }, { name: 'wg_chloride', type: 'float' }, { name: 'wg_sodium', type: 'float' }, { name: 'wg_magnesium', type: 'float' }, { name: 'wg_total_alkalinity', type: 'float' }, { name: 'wg_ph', type: 'float' }, { name: 'wb_calcium', type: 'float' }, { name: 'wb_sulfate', type: 'float' }, { name: 'wb_chloride', type: 'float' }, { name: 'wb_sodium', type: 'float' }, { name: 'wb_magnesium', type: 'float' }, { name: 'wb_total_alkalinity', type: 'float' }, { name: 'wb_ph', type: 'float' }, { name: 'wa_acid_name', type: 'int' }, { name: 'wa_acid_perc', type: 'int' }, { name: 'wa_base_name', type: 'int' }, { name: 'fermentables', type: 'array' }, { name: 'hops', type: 'array' }, { name: 'miscs', type: 'array' }, { name: 'yeasts', type: 'array' }, { name: 'mashs', type: 'array' } ], id: 'record', url: url + '?record=' + my_record }; // Load data and select one record. var dataAdapter = new $.jqx.dataAdapter(source, { loadComplete: function () { var records = dataAdapter.records; dataRecord = records[0]; // Hidden record uuid $("#name").val(dataRecord.name); $("#notes").val(dataRecord.notes); $("#locked").val(dataRecord.locked); $("#st_name").val(dataRecord.st_name); $("#st_letter").val(dataRecord.st_letter); $("#st_guide").val(dataRecord.st_guide); $("#st_category").val(dataRecord.st_category); $("#st_category_number").val(dataRecord.st_category_number); $("#st_type").val(StyleTypeData[dataRecord.st_type].nl); $("#type").val(dataRecord.type); $("#batch_size").val(dataRecord.batch_size); $("#boil_size").val(dataRecord.boil_size); $("#boil_time").val(dataRecord.boil_time); $("#efficiency").val(dataRecord.efficiency); $("#est_og").val(dataRecord.est_og); $("#est_og2").val(dataRecord.est_og); $("#st_og_min").val(dataRecord.st_og_min); $("#st_og_max").val(dataRecord.st_og_max); $("#est_fg").val(dataRecord.est_fg); $("#est_fg2").val(dataRecord.est_fg); $("#st_fg_min").val(dataRecord.st_fg_min); $("#st_fg_max").val(dataRecord.st_fg_max); $("#est_color").val(dataRecord.est_color); $("#est_color2").val(dataRecord.est_color); $("#est_abv").val(dataRecord.est_abv); $("#est_abv2").val(dataRecord.est_abv); $("#st_abv_min").val(dataRecord.st_abv_min); $("#st_abv_max").val(dataRecord.st_abv_max); $("#st_color_min").val(dataRecord.st_color_min); $("#st_color_max").val(dataRecord.st_color_max); $("#color_method").val(dataRecord.color_method); $("#est_ibu").val(dataRecord.est_ibu); $("#est_ibu2").val(dataRecord.est_ibu); $("#st_ibu_min").val(dataRecord.st_ibu_min); $("#st_ibu_max").val(dataRecord.st_ibu_max); $("#ibu_method").val(dataRecord.ibu_method); $("#est_carb").val(dataRecord.est_carb); $("#st_carb_min").val(dataRecord.st_carb_min); $("#st_carb_max").val(dataRecord.st_carb_max); $("#mash_name").val(dataRecord.mash_name); $("#mash_ph").val(dataRecord.mash_ph); $("#sparge_temp").val(dataRecord.sparge_temp); $("#sparge_ph").val(dataRecord.sparge_ph); $("#sparge_volume").val(dataRecord.sparge_volume); $("#sparge_source").val(dataRecord.sparge_source); $("#sparge_acid_type").val(dataRecord.sparge_acid_type); $("#sparge_acid_perc").val(dataRecord.sparge_acid_perc); $("#sparge_acid_amount").val(dataRecord.sparge_acid_amount * 1000); $("#calc_acid").val(dataRecord.calc_acid); $("#w1_name").val(dataRecord.w1_name); $("#w1_amount").val(dataRecord.w1_amount); $("#w1_calcium").val(dataRecord.w1_calcium); $("#w1_sulfate").val(dataRecord.w1_sulfate); $("#w1_chloride").val(dataRecord.w1_chloride); $("#w1_sodium").val(dataRecord.w1_sodium); $("#w1_magnesium").val(dataRecord.w1_magnesium); $("#w1_total_alkalinity").val(dataRecord.w1_total_alkalinity); $("#w1_ph").val(dataRecord.w1_ph); $("#w1_cost").val(dataRecord.w1_cost); $("#w2_name").val(dataRecord.w2_name); $("#w2_amount").val(dataRecord.w2_amount); $("#w2_calcium").val(dataRecord.w2_calcium); $("#w2_sulfate").val(dataRecord.w2_sulfate); $("#w2_chloride").val(dataRecord.w2_chloride); $("#w2_sodium").val(dataRecord.w2_sodium); $("#w2_magnesium").val(dataRecord.w2_magnesium); $("#w2_total_alkalinity").val(dataRecord.w2_total_alkalinity); $("#w2_ph").val(dataRecord.w2_ph); $("#w2_cost").val(dataRecord.w2_cost); $("#wg_amount").val(dataRecord.wg_amount); $("#wg_calcium").val(dataRecord.wg_calcium); $("#wg_sulfate").val(dataRecord.wg_sulfate); $("#wg_chloride").val(dataRecord.wg_chloride); $("#wg_sodium").val(dataRecord.wg_sodium); $("#wg_magnesium").val(dataRecord.wg_magnesium); $("#wg_total_alkalinity").val(dataRecord.wg_total_alkalinity); $("#wg_ph").val(dataRecord.wg_ph); $("#wb_calcium").val(dataRecord.wb_calcium); $("#wb_sulfate").val(dataRecord.wb_sulfate); $("#wb_chloride").val(dataRecord.wb_chloride); $("#wb_sodium").val(dataRecord.wb_sodium); $("#wb_magnesium").val(dataRecord.wb_magnesium); $("#wb_total_alkalinity").val(dataRecord.wb_total_alkalinity); $("#wb_ph").val(dataRecord.wb_ph); $("#wa_acid_name").val(dataRecord.wa_acid_name); $("#wa_acid_perc").val(dataRecord.wa_acid_perc); $("#wa_base_name").val(dataRecord.wa_base_name); editFermentable(dataRecord); editHop(dataRecord); editMisc(dataRecord); editYeast(dataRecord); editMash(dataRecord); $('#jqxTabs').jqxTabs('next'); }, loadError: function (jqXHR, status, error) { }, beforeLoadComplete: function (records) { $('#jqxLoader').jqxLoader('open'); } }); dataAdapter.dataBind(); // Inline fermentables editor var editFermentable = function (data) { var fermentableSource = { localdata: data.fermentables, datatype: "local", cache: false, async: false, datafields: [ { name: 'f_name', type: 'string' }, { name: 'f_origin', type: 'string' }, { name: 'f_supplier', type: 'string' }, { name: 'f_amount', type: 'float' }, { name: 'f_cost', type: 'float' }, { name: 'f_type', type: 'int' }, { name: 'f_yield', type: 'float' }, { name: 'f_color', type: 'float' }, { name: 'f_coarse_fine_diff', type: 'float' }, { name: 'f_moisture', type: 'float' }, { name: 'f_diastatic_power', type: 'float' }, { name: 'f_protein', type: 'float' }, { name: 'f_max_in_batch', type: 'float' }, { name: 'f_graintype', type: 'int' }, { name: 'f_added', type: 'int' }, { name: 'f_dissolved_protein', type: 'float' }, { name: 'f_recommend_mash', type: 'int' }, { name: 'f_add_after_boil', type: 'int' }, { name: 'f_adjust_to_total_100', type: 'int' }, { name: 'f_percentage', type: 'float' }, { name: 'f_di_ph', type: 'float' }, { name: 'f_acid_to_ph_57', type: 'float' }, { name: 'f_inventory', type: 'float' }, { name: 'f_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { //console.log("fermentable addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { //console.log("fermentable deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { //console.log("fermentable updaterow "+rowid); commit(true); } }; var fermentableAdapter = new $.jqx.dataAdapter(fermentableSource); $("#fermentableGrid").jqxGrid({ width: 1240, height: 470, source: fermentableAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="faddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="finstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="fdeleterowbutton" type="button" value="Verwijder mout" />'); // add fermentable from dropdownlist. $("#faddrowbutton").jqxDropDownList({ placeHolder: "Kies mout:", theme: theme, template: "primary", source: fermentablelist, displayMember: "name", width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = fermentablelist.records[index]; return datarecord.supplier+ " / " + datarecord.name + " (" + datarecord.color + " EBC)"; } }); $("#faddrowbutton").on('select', function (event) { if (event.args) { var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; var index = event.args.index; var datarecord = fermentablelist.records[index]; var row = {}; row["f_name"] = datarecord.name; row["f_origin"] = datarecord.origin; row["f_supplier"] = datarecord.supplier; row["f_amount"] = 0; row["f_cost"] = datarecord.cost; row["f_type"] = datarecord.type; row["f_yield"] = datarecord.yield; row["f_color"] = datarecord.color; row["f_coarse_fine_diff"] = datarecord.coarse_fine_diff; row["f_moisture"] = datarecord.moisture; row["f_diastatic_power"] = datarecord.diastatic_power; row["f_protein"] = datarecord.protein; row["f_max_in_batch"] = datarecord.max_in_batch; row["f_graintype"] = datarecord.graintype; if (datarecord.add_after_boil) { row["f_added"] = 2; // Fermentation } else if ((datarecord.type == 1) || (datarecord.type == 4)) { // Sugar or Adjunct row["f_added"] = 1; // Boil } else { row["f_added"] = 0; // Mash } row["f_dissolved_protein"] = datarecord.dissolved_protein; row["f_recommend_mash"] = datarecord.recommend_mash; row["f_add_after_boil"] = datarecord.add_after_boil; if (rowscount == 0) { // The first fermentable row["f_adjust_to_total_100"] = 1; row["f_percentage"] = 100; } else { row["f_adjust_to_total_100"] = 0; row["f_percentage"] = 0; } row["f_di_ph"] = datarecord.di_ph; row["f_acid_to_ph_57"] = datarecord.acid_to_ph_57; row["f_inventory"] = datarecord.inventory; var commit = $("#fermentableGrid").jqxGrid('addrow', null, row); } }); $("#finstockbutton").jqxCheckBox({ theme: theme, height: 27 }); $("#finstockbutton").on('change', function (event) { fermentableinstock = event.args.checked; fermentablelist.dataBind(); }); // delete selected fermentable. $("#fdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150 }); $("#fdeleterowbutton").on('click', function () { var selectedrowindex = $("#fermentableGrid").jqxGrid('getselectedrowindex'); var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#fermentableGrid").jqxGrid('getrowid', selectedrowindex); var percent = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_percentage"); var amount = $('#fermentableGrid').jqxGrid('getcellvalue', id, "f_amount"); var commit = $("#fermentableGrid").jqxGrid('deleterow', id); } rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; if (rowscount > 1) { if (to_100) { for (var i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_adjust_to_total_100) { rowdata.f_percentage += percent; rowdata.f_amount += amount; } } } else { calcPercentages(); } } else { $("#fermentableGrid").jqxGrid('setcellvalue', 0, "f_percentage", 100); } calcFermentables(); calcIBUs(); }); }, ready: function() { calcFermentables(); $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Vergistbaar ingrediënt', datafield: 'f_name', cellsrenderer: function (index, datafield, value, defaulvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + rowdata.f_supplier+" / "+rowdata.f_name+" ("+rowdata.f_color+" EBC)</span>"; } }, { text: 'Type', width: 100, datafield: 'f_type', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + FermentableTypeData[value].nl + "</span>"; } }, { text: 'Moment', width: 110, datafield: 'f_added', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + AddedData[value].nl + "</span>"; } }, { text:'Maxinbatch', datafield: 'f_max_in_batch', hidden: true }, { text: 'Opbrengst', editable: false, datafield: 'f_yield', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, { text: 'Gewicht Kg', datafield: 'f_amount', width: 120, align: 'right', cellsalign: 'right', cellsformat: 'f3' }, { text: 'Voorr. Kg', datafield: 'f_inventory', width: 120, align: 'right', cellsrenderer: function (row, columnfield, value, defaulthtml, columnproperties, rowdata) { var color = '#ffffff'; if (value < rowdata.f_amount) color = '#ff4040'; return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' +fermentableAdapter.formatNumber(value, "f3") + '</span>'; } }, { text: 'Procent', datafield: 'f_percentage', width: 90, align: 'right', cellsrenderer: function (row, columnfield, value, defaulthtml, columnproperties, rowdata) { var color = '#ffffff'; if (value > rowdata.f_max_in_batch) color = '#ff4040'; return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' +fermentableAdapter.formatNumber(value, "p1") + '</span>'; } }, { text: '100%', align: 'center', datafield: 'f_adjust_to_total_100', columntype: 'checkbox', width: 70 }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { fermentableRow = row; fermentableData = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); $("#wf_name").val(fermentableData.f_name); $("#wf_amount").val(fermentableData.f_amount); $("#wf_percentage").val(fermentableData.f_percentage); $("#wf_max_in_batch").val(fermentableData.f_max_in_batch); $("#wf_adjust_to_total_100").val(fermentableData.f_adjust_to_total_100); $("#wf_added").val(fermentableData.f_added); // show the popup window. $("#popupFermentable").jqxWindow('open'); } } ] }); }; // Inline hops editor var editHop = function (data) { var hopSource = { localdata: data.hops, datatype: "local", cache: false, async: false, datafields: [ { name: 'h_name', type: 'string' }, { name: 'h_origin', type: 'string' }, { name: 'h_amount', type: 'float' }, { name: 'h_cost', type: 'float' }, { name: 'h_type', type: 'int' }, { name: 'h_form', type: 'int' }, { name: 'h_useat', type: 'int' }, { name: 'h_time', type: 'float' }, { name: 'h_alpha', type: 'float' }, { name: 'h_beta', type: 'float' }, { name: 'h_hsi', type: 'float' }, { name: 'h_humulene', type: 'float' }, { name: 'h_caryophyllene', type: 'float' }, { name: 'h_cohumulone', type: 'float' }, { name: 'h_myrcene', type: 'float' }, { name: 'h_total_oil', type: 'float' }, { name: 'h_inventory', type: 'float' }, { name: 'h_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { console.log("hop addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { console.log("hop deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { console.log("hop updaterow "+rowid); commit(true); } }; var hopAdapter = new $.jqx.dataAdapter(hopSource); $("#hopGrid").jqxGrid({ width: 1240, height: 560, source: hopAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="haddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="hinstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="hdeleterowbutton" type="button" value="Verwijder hop" />'); // add hop from dropdownlist. $("#haddrowbutton").jqxDropDownList({ placeHolder: "Kies hop:", theme: theme, template: "primary", source: hoplist, displayMember: "name", width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = hoplist.records[index]; return datarecord.origin+ " / " + datarecord.name + " (" + datarecord.alpha + "% α)"; } }); $("#haddrowbutton").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = hoplist.records[index]; var row = {}; row["h_name"] = datarecord.name; row["h_origin"] = datarecord.origin; row["h_amount"] = 0; row["h_cost"] = datarecord.cost; row["h_type"] = datarecord.type; row["h_form"] = datarecord.form; row["h_useat"] = 2; // Boil row["h_time"] = 0; row["h_alpha"] = datarecord.alpha; row["h_beta"] = datarecord.beta; row["h_hsi"] = datarecord.hsi; row["h_humulene"] = datarecord.humulene; row["h_caryophyllene"] = datarecord.caryophyllene; row["h_cohumulone"] = datarecord.cohumulone; row["h_myrcene"] = datarecord.myrcene; row["h_total_oil"] = datarecord.total_oil; row["h_inventory"] = datarecord.inventory; var commit = $("#hopGrid").jqxGrid('addrow', null, row); } $("#haddrowbutton").jqxDropDownList('clearSelection'); }); $("#hinstockbutton").jqxCheckBox({ theme: theme, height: 27 }); $("#hinstockbutton").on('change', function (event) { hopinstock = event.args.checked; hoplist.dataBind(); }); // delete selected hop. $("#hdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150 }); $("#hdeleterowbutton").on('click', function () { var selectedrowindex = $("#hopGrid").jqxGrid('getselectedrowindex'); var rowscount = $("#hopGrid").jqxGrid('getdatainformation').rowscount; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#hopGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#hopGrid").jqxGrid('deleterow', id); } calcIBUs(); }); }, ready: function() { calcIBUs(); $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Hop', datafield: 'h_name', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" +rowdata.h_origin+" / "+rowdata.h_name+"</span>"; }, }, { text: 'Type', width: 90, datafield: 'h_type', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopTypeData[value].nl + '</span>'; } }, { text: 'Vorm', width: 90, datafield: 'h_form', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopFormData[value].nl + '</span>'; } }, { text: 'Alpha', datafield: 'h_alpha', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, { text: 'Gebruik', width: 110, datafield: 'h_useat', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopUseData[value].nl + '</span>'; } }, { text: 'Tijdsduur', datafield: 'h_time', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var duration = ''; if ((rowdata.h_useat == 2) || (rowdata.h_useat == 4)) // Boil, Whirlpool duration = dataAdapter.formatNumber(value, "f0")+" min."; else if (rowdata.h_useat == 5) // Dry hop duration = dataAdapter.formatNumber(value/1440, "f0")+" dagen"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>'; } }, { text: 'IBU', datafield: 'ibu', width: 80, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var ibu = toIBU(rowdata.h_useat, rowdata.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time), parseFloat(rowdata.h_alpha), $("#ibu_method").val()); return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(ibu, "f1") + '</span>'; } }, { text: 'Gewicht', datafield: 'h_amount', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var amount = dataAdapter.formatNumber(value, "f1") + ' kg'; if (value < 1) amount = dataAdapter.formatNumber(value * 1000, "f1") + ' gr'; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>'; } }, { text: 'Voorraad', datafield: 'h_inventory', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var color = '#ffffff'; if (value < rowdata.h_amount) color = '#ff4040'; var amount = dataAdapter.formatNumber(value, "f1") + ' kg'; if (value < 1) amount = dataAdapter.formatNumber(value * 1000, "f1") + ' gr'; return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>'; } }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { hopRow = row; hopData = $("#hopGrid").jqxGrid('getrowdata', hopRow); $("#wh_name").val(hopData.h_name); $("#wh_amount").val(hopData.h_amount * 1000); var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $("#ibu_method").val() ); $("#wh_ibu").val(ibu); if (hopData.h_useat == 5) // Dry hop $("#wh_time").val(hopData.h_time / 1440); else $("#wh_time").val(hopData.h_time); $("#wh_useat").val(hopData.h_useat); // show the popup window. $("#popupHop").jqxWindow('open'); } } ] }); }; // Inline miscs editor var editMisc = function (data) { var miscSource = { localdata: data.miscs, datatype: "local", cache: false, async: false, datafields: [ { name: 'm_name', type: 'string' }, { name: 'm_amount', type: 'float' }, { name: 'm_cost', type: 'float' }, { name: 'm_type', type: 'int' }, { name: 'm_use_use', type: 'int' }, { name: 'm_time', type: 'float' }, { name: 'm_amount_is_weight', type: 'int' }, { name: 'm_inventory', type: 'float' }, { name: 'm_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { console.log("misc addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { console.log("misc deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { console.log("misc updaterow "+rowid); commit(true); } }; var miscAdapter = new $.jqx.dataAdapter(miscSource, { beforeLoadComplete: function (records) { var data = new Array(); for (var i = 0; i < records.length; i++) { var row = records[i]; data.push(row); // Initial set water agent values. switch (row.m_name) { case 'CaCl2': $("#wa_cacl2").val(row.m_amount * 1000); break; case 'CaSO4': $("#wa_caso4").val(row.m_amount * 1000); break; case 'MgSO4': $("#wa_mgso4").val(row.m_amount * 1000); break; case 'NaCl': $("#wa_nacl").val(row.m_amount * 1000); break; case 'Melkzuur': $("#wa_acid_name").val(0); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Melkzuur'; break; case 'Zoutzuur': $("#wa_acid_name").val(1); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Zoutzuur'; break; case 'Fosforzuur': $("#wa_acid_name").val(2); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Fosforzuur'; break; case 'Zwavelzuur': $("#wa_acid_name").val(3); $("#wa_acid").val(row.m_amount * 1000); $("#wa_acid_perc").val(80); last_acid = 'Zwavelzuur'; break; case 'NaHCO3': $("#wa_base_name").val(0); $("#wa_base").val(row.m_amount * 1000); last_base = 'NaHCO3'; break; case 'Na2CO3': $("#wa_base_name").val(1); $("#wa_base").val(row.m_amount * 1000); last_base = 'Na2CO3'; break; case 'CaCO3': $("#wa_base_name").val(2); $("#wa_base").val(row.m_amount * 1000); last_base = 'CaCO3'; break; case 'Ca(OH)2': $("#wa_base_name").val(3); $("#wa_base").val(row.m_amount * 1000); last_base = 'Ca(OH)2'; break; } } return data; }, loadError: function(jqXHR, status, error) { $('#err').text(status + ' ' + error); }, }); $("#miscGrid").jqxGrid({ width: 1240, height: 575, source: miscAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="maddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="minstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="mdeleterowbutton" type="button" value="Verwijder ingrediënt" />'); // add misc from dropdownlist. $("#maddrowbutton").jqxDropDownList({ placeHolder: "Kies ingrediënt:", theme: theme, template: "primary", source: misclist, displayMember: "name", width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500 }); $("#maddrowbutton").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = misclist.records[index]; var row = {}; row["m_name"] = datarecord.name; row["m_amount"] = 0; row["m_cost"] = datarecord.cost; row["m_type"] = datarecord.type; row["m_use_use"] = datarecord.use_use; row["m_time"] = 0; row["m_amount_is_weight"] = datarecord.amount_is_weight; row["m_inventory"] = datarecord.inventory; var commit = $("#miscGrid").jqxGrid('addrow', null, row); } }); $("#minstockbutton").jqxCheckBox({ theme: theme, height: 27 }); $("#minstockbutton").on('change', function (event) { miscinstock = event.args.checked; misclist.dataBind(); }); // delete selected misc. $("#mdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150 }); $("#mdeleterowbutton").on('click', function () { var selectedrowindex = $("#miscGrid").jqxGrid('getselectedrowindex'); var rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; var type = $("#miscGrid").jqxGrid('getcellvalue', selectedrowindex, "m_type"); if (selectedrowindex >= 0 && selectedrowindex < rowscount && type != 4) { // Water agent var id = $("#miscGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#miscGrid").jqxGrid('deleterow', id); } }); }, ready: function() { $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Ingredient', datafield: 'm_name' }, { text: 'Type', width: 140, datafield: 'm_type', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + MiscTypeData[value].nl + "</span>"; } }, { text: 'Gebruik', width: 140, datafield: 'm_use_use', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<span style='margin: 3px; margin-top: 6px; float: left;'>" + MiscUseData[value].nl + "</span>"; } }, { text: 'Tijd', datafield: 'm_time', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var duration = ''; if (rowdata.m_use_use == 2) // Boil duration = dataAdapter.formatNumber(value, "f0")+" min."; else if ((rowdata.m_use_use == 3) || (rowdata.m_use_use == 4)) // Primary or Secondary duration = dataAdapter.formatNumber(value/1440, "f0")+" dagen"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>'; }, }, { text: 'Hoeveel', datafield: 'm_amount', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var vstr = rowdata.m_amount_is_weight ? "gr":"ml"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value * 1000,"f2")+" "+vstr + '</span>'; }, }, { text: 'Voorraad', datafield: 'm_inventory', width: 110, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var vstr = rowdata.m_amount_is_weight ? "gr":"ml"; var color = '#ffffff'; if (value < rowdata.m_amount) color = '#ff4040'; var amount = dataAdapter.formatNumber(value * 1000,"f2")+" "+vstr; return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>'; }, }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { miscRow = row; miscData = $("#miscGrid").jqxGrid('getrowdata', miscRow); if (miscData.m_type == 4) { alert("Brouwzouten wijzigen in de water tab."); } else { if (miscData.m_amount_is_weight) $("#wm_pmpt_amount").html("Gewicht gram:"); else $("#wm_pmpt_amount").html("Volume ml:"); $("#wm_name").val(miscData.m_name); $("#wm_amount").val(miscData.m_amount * 1000); if ((miscData.m_use_use == 3) || (miscData.m_use_use == 4)) // Primary or Secondary $("#wm_time").val(miscData.m_time / 1440); else $("#wm_time").val(miscData.m_time); $("#wm_use_use").val(miscData.m_use_use); // show the popup window. $("#popupMisc").jqxWindow('open'); } } } ] }); }; // Inline yeasts editor var editYeast = function (data) { var yeastSource = { localdata: data.yeasts, datatype: "local", cache: false, async: false, datafields: [ { name: 'y_name', type: 'string' }, { name: 'y_laboratory', type: 'string' }, { name: 'y_product_id', type: 'string' }, { name: 'y_amount', type: 'float' }, { name: 'y_cost', type: 'float' }, { name: 'y_type', type: 'int' }, { name: 'y_form', type: 'int' }, { name: 'y_flocculation', type: 'int' }, { name: 'y_min_temperature', type: 'float' }, { name: 'y_max_temperature', type: 'float' }, { name: 'y_attenuation', type: 'float' }, { name: 'y_use', type: 'int' }, { name: 'y_cells', type: 'float' }, { name: 'y_tolerance', type: 'float' }, { name: 'y_inventory', type: 'float' }, { name: 'y_avail', type: 'int' } ], addrow: function (rowid, rowdata, position, commit) { console.log("yeast addrow "+rowid); commit(true); }, deleterow: function (rowid, commit) { console.log("yeast deleterow "+rowid); commit(true); }, updaterow: function (rowid, rowdata, commit) { console.log("yeast updaterow "+rowid); commit(true); } }; var yeastAdapter = new $.jqx.dataAdapter(yeastSource); $("#yeastGrid").jqxGrid({ width: 1240, height: 350, source: yeastAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<div style="float: left; margin-left: 165px;" id="yaddrowbutton"></div>'); container.append('<div style="float: left; margin-left: 10px; margin-top: 5px;">In voorraad:</div>'); container.append('<div style="float: left; margin-left: 10px;" id="yinstockbutton"></div>'); container.append('<input style="float: left; margin-left: 400px;" id="ydeleterowbutton" type="button" value="Verwijder gist" />'); // add yeast from dropdownlist. $("#yaddrowbutton").jqxDropDownList({ placeHolder: "Kies gist:", theme: theme, template: "primary", source: yeastlist, displayMember: "name", width: 150, height: 27, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = yeastlist.records[index]; return datarecord.laboratory+" "+datarecord.product_id+" "+datarecord.name; } }); $("#yaddrowbutton").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = yeastlist.records[index]; var row = {}; row["y_name"] = datarecord.name; row["y_laboratory"] = datarecord.laboratory; row["y_product_id"] = datarecord.product_id; row["y_type"] = datarecord.type; row["y_form"] = datarecord.form; row["y_amount"] = 0; row["y_cost"] = datarecord.cost; row["y_use"] = 0; row["y_min_temperature"] = datarecord.min_temperature; row["y_max_temperature"] = datarecord.max_temperature; row["y_attenuation"] = datarecord.attenuation; row["y_flocculation"] = datarecord.flocculation; row["y_cells"] = datarecord.cells; row["y_tolerance"] = datarecord.tolerance; row["y_inventory"] = datarecord.inventory; var commit = $("#yeastGrid").jqxGrid('addrow', null, row); } $("#yaddrowbutton").jqxDropDownList('clearSelection'); }); $("#yinstockbutton").jqxCheckBox({ theme: theme, height: 27 }); $("#yinstockbutton").on('change', function (event) { yeastinstock = event.args.checked; yeastlist.dataBind(); }); // delete selected yeast. $("#ydeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150 }); $("#ydeleterowbutton").on('click', function () { var selectedrowindex = $("#yeastGrid").jqxGrid('getselectedrowindex'); var rowscount = $("#yeastGrid").jqxGrid('getdatainformation').rowscount; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#yeastGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#yeastGrid").jqxGrid('deleterow', id); } }); }, ready: function() { calcFermentables(); $('#jqxTabs').jqxTabs('next'); }, columns: [ { text: 'Gist', datafield: 'y_name' }, { text: 'Laboratorium', width: 150, datafield: 'y_laboratory' }, { text: 'Code', width: 90, datafield: 'y_product_id' }, { text: 'Soort', width: 100, datafield: 'y_form', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastFormData[value].nl + '</span>'; } }, { text: 'Min. °C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_min_temperature' }, { text: 'Max. °C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_max_temperature' }, { text: 'Tol. %', width: 60, align: 'right', cellsalign: 'right', datafield: 'y_tolerance', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var color = '#ffffff'; var amount = ""; if (value > 0) { amount = dataAdapter.formatNumber(value, "f1"); if (dataRecord.est_abv > value) color = '#ff4040'; } return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>'; } }, { text: 'Attn. %', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_attenuation', cellsformat: 'f1' }, { text: 'Voor', width: 120, datafield: 'y_use', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastUseData[value].nl + '</span>'; } }, { text: 'Hoeveel', datafield: 'y_amount', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var amount = dataAdapter.formatNumber(value*1000, "f0")+" ml"; if (rowdata.y_form == 0) // Liquid amount = dataAdapter.formatNumber(value, "f0")+" pk"; else if (rowdata.y_form == 1) // Dry amount = dataAdapter.formatNumber(value*1000, "f1")+" gr"; return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>'; } }, { text: 'Voorraad', datafield: 'y_inventory', width: 90, align: 'right', cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { var color = '#ffffff'; if (value < rowdata.y_amount) color = '#ff4040'; var amount = dataAdapter.formatNumber(value*1000, "f0")+" ml"; if (rowdata.y_form == 0) // Liquid amount = dataAdapter.formatNumber(value, "f0")+" pk"; else if (rowdata.y_form == 1) // Dry amount = dataAdapter.formatNumber(value*1000, "f1")+" gr"; return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>'; } }, { text: '', datafield: 'Edit', columntype: 'button', width: 90, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { yeastRow = row; yeastData = $("#yeastGrid").jqxGrid('getrowdata', yeastRow); if (yeastData.y_form == 0) { $("#wy_pmpt_amount").html("Pak(ken):"); $("#wy_amount").val(yeastData.y_amount); $("#wy_amount").jqxNumberInput({ decimalDigits: 0 }); } else if (yeastData.y_form == 1) { $("#wy_pmpt_amount").html("Gewicht gram:"); $("#wy_amount").val(yeastData.y_amount * 1000); $("#wy_amount").jqxNumberInput({ decimalDigits: 1 }); } else { $("#wy_pmpt_amount").html("Volume ml:"); $("#wy_amount").val(yeastData.y_amount * 1000); $("#wy_amount").jqxNumberInput({ decimalDigits: 0 }); } $("#wy_name").val(yeastData.y_name); $("#wy_laboratory").val(yeastData.y_laboratory); $("#wy_product_id").val(yeastData.y_product_id); $("#wy_use").val(yeastData.y_use); // show the popup window. $("#popupYeast").jqxWindow('open'); } } ] }); }; // inline mash editor var editMash = function (data) { var generaterow = function () { var row = {}; row["step_name"] = "Stap 1"; row["step_type"] = 0; row["step_infuse_amount"] = 15; row["step_temp"] = 62.0; row['step_time'] = 20.0; row['step_thickness'] = 0; row['ramp_time'] = 1.0; row['end_temp'] = 62.0; return row; } var mashSource = { localdata: data.mashs, datatype: "local", cache: false, async: false, datafields: [ { name: 'step_name', type: 'string' }, { name: 'step_type', type: 'int' }, { name: 'step_infuse_amount', type: 'float' }, { name: 'step_temp', type: 'float' }, { name: 'step_time', type: 'float' }, { name: 'step_thickness', type: 'float' }, { name: 'ramp_time', type: 'float' }, { name: 'end_temp', type: 'float' } ], addrow: function (rowid, rowdata, position, commit) { commit(true); }, deleterow: function (rowid, commit) { commit(true); } }; var mashAdapter = new $.jqx.dataAdapter(mashSource, { beforeLoadComplete: function (records) { mash_infuse = 0; var data = new Array(); for (var i = 0; i < records.length; i++) { var row = records[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); row.step_thickness = 0; // Init this field. data.push(row); } }, }); $("#mashGrid").jqxGrid({ width: 1240, height: 400, source: mashAdapter, theme: theme, selectionmode: 'singlerow', showtoolbar: true, rendertoolbar: function (toolbar) { var me = this; var container = $("<div style='overflow: hidden; position: relative; margin: 5px;'></div>"); toolbar.append(container); container.append('<input style="float: left; margin-left: 165px;" id="saddrowbutton" type="button" value="Nieuwe stap" />'); container.append('<input style="float: left; margin-left: 565px;" id="sdeleterowbutton" type="button" value="Verwijder stap" />'); $("#saddrowbutton").jqxButton({ template: "primary", theme: theme, height: 27, width: 150 }); $("#saddrowbutton").on('click', function () { var datarow = generaterow(); var commit = $("#mashGrid").jqxGrid('addrow', null, datarow); }); // delete selected yeast. $("#sdeleterowbutton").jqxButton({ template: "danger", theme: theme, height: 27, width: 150 }); $("#sdeleterowbutton").on('click', function () { var selectedrowindex = $("#mashGrid").jqxGrid('getselectedrowindex'); var rowscount = $("#mashGrid").jqxGrid('getdatainformation').rowscount; if (selectedrowindex >= 0 && selectedrowindex < rowscount) { var id = $("#mashGrid").jqxGrid('getrowid', selectedrowindex); var commit = $("#mashGrid").jqxGrid('deleterow', id); } }); }, ready: function() { calcFermentables(); calcInit(); calcMash(); $('#jqxLoader').jqxLoader('close'); $('#jqxTabs').jqxTabs('first'); }, columns: [ { text: 'Stap naam', datafield: 'step_name' }, { text: 'Stap type', datafield: 'step_type', width: 175, cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { return "<div style='margin: 4px;'>" + MashStepTypeData[value].nl + "</div>"; } }, { text: 'Start °C', datafield: 'step_temp', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, { text: 'Eind °C', datafield: 'end_temp', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, { text: 'Rust min.', datafield: 'step_time', width: 90, align: 'right', cellsalign: 'right' }, { text: 'Stap min.', datafield: 'ramp_time', width: 90, align: 'right', cellsalign: 'right' }, { text: 'Infuse L.', datafield: 'step_infuse_amount', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, { text: 'L/Kg.', datafield: 'step_thickness', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'f2' }, { text: '', datafield: 'Edit', columntype: 'button', width: 100, align: 'center', cellsrenderer: function () { return "Wijzig"; }, buttonclick: function (row) { mashRow = row; mashData = $("#mashGrid").jqxGrid('getrowdata', mashRow); $("#wstep_name").val(mashData.step_name); $("#wstep_type").val(mashData.step_type); $("#wstep_infuse_amount").val(mashData.step_infuse_amount); $("#wstep_temp").val(mashData.step_temp); $("#wend_temp").val(mashData.end_temp); $("#wstep_time").val(mashData.step_time); $("#wramp_time").val(mashData.ramp_time); if (mashData.step_type == 0) { $("#wstep_infuse_amount").show(); $("#wstep_pmpt").show(); } else { $("#wstep_infuse_amount").hide(); $("#wstep_pmpt").hide(); } // show the popup window. $("#popupMash").jqxWindow('open'); } } ] }); }; // initialize the input fields. // Tab 1, Algemeen $("#name").jqxTooltip({ content: 'De naam voor dit recept.' }); $("#name").jqxInput({ theme: theme, width: 640, height: 23 }); $("#locked").jqxCheckBox({ theme: theme, width: 120, height: 23 }); $("#notes").jqxTooltip({ content: 'De uitgebreide opmerkingen over dit recept.' }); $("#notes").jqxInput({ theme: theme, width: 960, height: 200 }); $("#type").jqxTooltip({ content: 'Het brouw type van dit recept.' }); $("#type").jqxDropDownList({ theme: theme, source: RecipeTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#efficiency").jqxTooltip({ content: 'Het rendement van maischen en koken.' }); $("#efficiency").jqxNumberInput( Perc1dec ); $("#batch_size").jqxTooltip({ content: 'Het volume van het gekoelde wort na het koken.' }); $("#batch_size").jqxNumberInput( Spin1dec ); $("#batch_size").jqxNumberInput({ min: 4 }); $("#boil_size").jqxTooltip({ content: 'Het volume van het wort voor het koken.' }); $("#boil_size").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 90, height: 23, decimalDigits: 2, readOnly: true }); $("#boil_time").jqxTooltip({ content: 'De kooktijd in minuten.' }); $("#boil_time").jqxNumberInput( PosInt ); $("#boil_time").jqxNumberInput({ min: 4, max: 360 }); $("#st_name").jqxTooltip({ content: 'De bierstijl naam voor dit recept.'}); $("#st_name").jqxInput({ theme: theme, width: 250, height: 23 }); $("#st_letter").jqxTooltip({ content: 'De bierstijl letter voor dit recept.'}); $("#st_letter").jqxInput({ theme: theme, width: 100, height: 23 }); $("#st_guide").jqxTooltip({ content: 'De bierstijl gids voor dit recept.'}); $("#st_guide").jqxInput({ theme: theme, width: 250, height: 23 }); $("#st_category").jqxTooltip({ content: 'De Amerikaanse bierstijl categorie.'}); $("#st_category").jqxInput({ theme: theme, width: 250, height: 23 }); $("#st_category_number").jqxTooltip({ content: 'De Amerikaanse bierstijl categorie sub nummer.'}); $("#st_category_number").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#st_type").jqxTooltip({ content: 'Het bierstijl type.'}); $("#st_type").jqxInput({ theme: theme, width: 250, height: 23 }); $("#est_og").jqxTooltip({ content: 'Het begin SG wat je wilt bereiken. De moutstort wordt automatisch herberekend.' }); $("#est_og").jqxNumberInput( SGopts ); $("#st_og_min").jqxTooltip({ content: 'Het minimum begin SG voor deze bierstijl.'}); $("#st_og_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#st_og_max").jqxTooltip({ content: 'Het maximum begin SG voor deze bierstijl.'}); $("#st_og_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#est_fg").jqxTooltip({ content: 'Het eind SG. Dit wordt automatisch berekend.' }); $("#est_fg").jqxNumberInput( Show3dec ); $("#st_fg_min").jqxTooltip({ content: 'Het minimum eind SG voor deze bierstijl.'}); $("#st_fg_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#st_fg_max").jqxTooltip({ content: 'Het maximum eind SG voor deze bierstijl.'}); $("#st_fg_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); $("#est_abv").jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' }); $("#est_abv").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_abv_min").jqxTooltip({ content: 'Het minimum alcohol volume % voor deze bierstijl.'}); $("#st_abv_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_abv_max").jqxTooltip({ content: 'Het maximum alcohol volume % voor deze bierstijl.'}); $("#st_abv_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#est_color").jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' }); $("#est_color").jqxNumberInput( Show0dec ); $("#st_color_min").jqxTooltip({ content: 'De minimum kleur voor deze bierstijl.'}); $("#st_color_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#st_color_max").jqxTooltip({ content: 'De maximum kleur voor deze bierstijl.'}); $("#st_color_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#color_method").jqxDropDownList({ theme: theme, source: ColorMethodAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#est_ibu").jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' }); $("#est_ibu").jqxNumberInput( Show0dec ); $("#st_ibu_min").jqxTooltip({ content: 'De minimum bitterheid voor deze bierstijl.'}); $("#st_ibu_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#st_ibu_max").jqxTooltip({ content: 'De maximum bitterheid voor deze bierstijl.'}); $("#st_ibu_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#ibu_method").jqxDropDownList({ theme: theme, source: IBUmethodAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#est_carb").jqxTooltip({ content: 'Koolzuur volume. Dit wordt automatisch berekend.' }); $("#est_carb").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_carb_min").jqxTooltip({ content: 'Het minimum koolzuur volume voor deze bierstijl.'}); $("#st_carb_min").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#st_carb_max").jqxTooltip({ content: 'Het maximum koolzuur volume voor deze bierstijl.'}); $("#st_carb_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); // Tab 2, Vergistbaar $("#est_color2").jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' }); $("#est_color2").jqxNumberInput( Show0dec ); $("#est_og2").jqxTooltip({ content: 'Het begin SG wat je wilt bereiken. De moutstort wordt automatisch herberekend.' }); $("#est_og2").jqxNumberInput( Show3dec ); $("#perc_malts").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 120, animationDuration: 0, colorRanges: [ { stop: 90, color: '#008C00' }, { stop: 100, color: '#EB7331' }, { stop: 120, color: '#FF0000' } ], renderText: function (text) { return (Math.round(parseInt(text) * 1.2)) + '%'; } }); $("#perc_sugars").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0, colorRanges: [ { stop: 20, color: '#008C00' }, { stop: 50, color: '#FF0000' } ], renderText: function (text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; } }); $("#perc_cara").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0, colorRanges: [ { stop: 25, color: '#008C00' }, { stop: 50, color: '#FF0000' } ], renderText: function (text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; } }); $("#ferm_lintner").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, max: 200, animationDuration: 0, colorRanges: [ { stop: 30, color: '#FF0000' }, { stop: 40, color: '#EB7331' }, { stop: 200, color: '#008C00' } ], renderText: function (text) { return (parseInt(text) * 2) + ' lintner'; } }); $("#popupFermentable").jqxWindow({ width: 800, height: 300, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#FermentableReady"), modalOpacity: 0.40 }); $("#FermentableReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#FermentableReady").click(function () { var rowID = $("#fermentableGrid").jqxGrid('getrowid', fermentableRow); console.log("FermentableReady row:"+fermentableRow+" ID:"+rowID); var row = { f_name: fermentableData.f_name, f_origin: fermentableData.f_origin, f_supplier: fermentableData.f_supplier, f_amount: fermentableData.f_amount, f_cost: fermentableData.f_cost, f_type: fermentableData.f_type, f_yield: fermentableData.f_yield, f_color: fermentableData.f_color, f_coarse_fine_diff: fermentableData.f_coarse_fine_diff, f_moisture: fermentableData.f_moisture, f_diastatic_power: fermentableData.f_diastatic_power, f_protein: fermentableData.f_protein, f_max_in_batch: fermentableData.f_max_in_batch, f_graintype: fermentableData.f_graintype, f_added: fermentableData.f_added, f_dissolved_protein: fermentableData.f_dissolved_protein, f_recommend_mash: fermentableData.f_recommend_mash, f_add_after_boil: fermentableData.f_add_after_boil, f_adjust_to_total_100: fermentableData.f_adjust_to_total_100, f_percentage: fermentableData.f_percentage, f_di_ph: fermentableData.f_di_ph, f_acid_to_ph_57: fermentableData.f_acid_to_ph_57, f_inventory: fermentableData.f_inventory, f_avail: fermentableData.f_avail }; $("#fermentableGrid").jqxGrid('updaterow', rowID, row); calcPercentages(); calcFermentables(); calcIBUs(); calcMash(); // Waters: yes there is impact. }); $("#wf_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wf_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wf_instock").on('change', function (event) { fermentableinstock = event.args.checked; fermentablelist.dataBind(); }); $("#wf_select").jqxDropDownList({ placeHolder: "Kies mout:", theme: theme, source: fermentablelist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = fermentablelist.records[index]; return datarecord.supplier+ " / " + datarecord.name + " (" + datarecord.color + " EBC)"; } }); $("#wf_select").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = fermentablelist.records[index]; $("#wf_name").val(datarecord.name); fermentableData.f_name = datarecord.name; fermentableData.f_origin = datarecord.origin; fermentableData.f_supplier = datarecord.supplier; fermentableData.f_type = datarecord.type; fermentableData.f_cost = datarecord.cost; fermentableData.f_yield = datarecord.yield; fermentableData.f_color = datarecord.color; fermentableData.f_coarse_fine_diff = datarecord.coarse_fine_diff; fermentableData.f_moisture = datarecord.moisture; fermentableData.f_diastatic_power = datarecord.diastatic_power; fermentableData.f_protein = datarecord.protein; fermentableData.f_max_in_batch = datarecord.max_in_batch; fermentableData.f_graintype = datarecord.graintype; fermentableData.f_dissolved_protein = datarecord.dissolved_protein; fermentableData.f_recommend_mash = datarecord.recommend_mash; fermentableData.f_add_after_boil = datarecord.add_after_boil; fermentableData.f_di_ph = datarecord.di_ph; fermentableData.f_acid_to_ph_57 = datarecord.acid_to_ph_57; fermentableData.f_inventory = datarecord.inventory; } }); $("#wf_amount").jqxNumberInput( Spin3dec ); $('#wf_amount').on('change', function (event) { console.log("amount changed: "+event.args.value); $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_amount', event.args.value); fermentableData.f_amount = event.args.value; if (! to_100) { calcPercentages(); calcFermentables(); calcMash(); }; }); $("#wf_percentage").jqxNumberInput( Perc1dec ); $("#wf_percentage").on('change', function (event) { var oldvalue = Math.round(fermentableData.f_percentage * 10) / 10.0; var newvalue = event.args.value; console.log("percentage changed: "+newvalue+" old: "+oldvalue); fermentableData.f_percent = newvalue; var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; if ((oldvalue != newvalue) && (rowscount > 1)) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); if (rowdata.f_adjust_to_total_100) { $("#wf_percentage").val(oldvalue); } else { var diff = newvalue - oldvalue; var tw = 0; // total weight for (i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_added < 4) tw += Math.round(rowdata.f_amount * 1000) / 1000; } tw = Math.round(tw * 1000) / 1000; if (to_100) { // Adjust this row and the 100% row. var damount = Math.round(tw * diff *10) / 1000; var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', fermentableRow); var namount = Math.round((rowdata.f_amount + damount) * 1000) / 1000; $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_amount', namount); $("#wf_amount").val(namount); $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_percentage', rowdata.f_percentage + diff); for (i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_adjust_to_total_100) { namount = rowdata.f_amount - damount; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', rowdata.f_percentage - diff); $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', namount); } } calcFermentables(); cacMash(); } else { // Adjust all the rows. var nw = tw * diff / 100; for (i = 0; i < rowscount; i++) { var rowdata = $("#fermentableGrid").jqxGrid('getrowdata', i); if (rowdata.f_added < 4) { if (i == fermentableRow) { var namount = Math.round((rowdata.f_amount + nw) * 1000) / 1000; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', namount); // $("#wf_amount").val(namount); // Will crash the script. $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', newvalue); } else { var namount = Math.round((rowdata.f_amount - (nw / (rowscount - 1))) * 1000) / 1000; var newperc = Math.round((namount / tw) * 1000) / 10.0; $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_amount', namount); $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', newperc); } } else { $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_percentage', 0); } } calcFermentables(); calcMash(); } } } }); $("#wf_max_in_batch").jqxNumberInput( Show1dec ); $("#wf_adjust_to_total_100").jqxCheckBox({ theme: theme, width: 120, height: 23 }); $("#wf_adjust_to_total_100").on('checked', function (event) { if (fermentableData.f_adjust_to_total_100 == 0) { if (to_100) { // Reset other flag first. var rowscount = $("#fermentableGrid").jqxGrid('getdatainformation').rowscount; for (var i = 0; i < rowscount; i++) { if (i != fermentableRow) { $("#fermentableGrid").jqxGrid('setcellvalue', i, 'f_adjust_to_total_100', 0); } } } $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_adjust_to_total_100', 1); calcFermentables(); } }); $("#wf_adjust_to_total_100").on('unchecked', function (event) { if (fermentableData.f_adjust_to_total_100 != 0) { $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_adjust_to_total_100', 0); calcFermentables(); } }); $("#wf_added").jqxDropDownList({ theme: theme, source: AddedAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wf_added").on('select', function (event) { if (event.args) { var index = event.args.index; $("#fermentableGrid").jqxGrid('setcellvalue', fermentableRow, 'f_added', index); calcFermentables(); calcIBUs(); calcMash(); } }); // Tab 3, Hoppen $("#est_ibu2").jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' }); $("#est_ibu2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 0, readOnly: true }); $("#hop_flavour").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, animationDuration: 0, colorRanges: [ { stop: 20, color: '#004D00' }, { stop: 40, color: '#008C00' }, { stop: 60, color: '#00BF00' }, { stop: 80, color: '#00FF00' }, { stop: 100, color: '#80FF80' } ], renderText: function (text) { var val = parseInt(text); if (val < 20) return 'Weinig'; else if (val < 40) return 'Matig'; else if (val < 60) return 'Redelijk'; else if (val < 80) return 'Veel'; else return 'Zeer veel'; } }); $("#hop_aroma").jqxProgressBar({ width: 300, height: 23, theme: theme, showText: true, animationDuration: 0, colorRanges: [ { stop: 20, color: '#004D00' }, { stop: 40, color: '#008C00' }, { stop: 60, color: '#00BF00' }, { stop: 80, color: '#00FF00' }, { stop: 100, color: '#80FF80' } ], renderText: function (text) { var val = parseInt(text); if (val < 20) return 'Weinig'; else if (val < 40) return 'Matig'; else if (val < 60) return 'Redelijk'; else if (val < 80) return 'Veel'; else return 'Zeer veel'; } }); $("#popupHop").jqxWindow({ width: 800, height: 300, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#HopReady"), modalOpacity: 0.40 }); $("#HopReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#HopReady").click(function () { var rowID = $("#hopGrid").jqxGrid('getrowid', hopRow); console.log("HopReady row:"+hopRow+" ID:"+rowID); var row = { h_name: $("#wh_name").val(), h_origin: hopData.h_origin, h_amount: parseFloat($("#wh_amount").jqxNumberInput('decimal')) / 1000, h_cost: hopData.h_cost, h_type: hopData.h_type, h_form: hopData.h_form, h_useat: $("#wh_useat").val(), h_time: hopData.h_time, h_alpha: hopData.h_alpha, h_beta: hopData.h_beta, h_hsi: hopData.h_hsi, h_humulene: hopData.h_humulene, h_caryophyllene: hopData.h_caryophyllene, h_cohumulone: hopData.h_cohumulone, h_myrcene: hopData.h_myrcene, h_total_oil: hopData.h_total_oil, h_inventory: hopData.h_inventory, h_avail: hopData.h_avail }; $("#hopGrid").jqxGrid('updaterow', rowID, row); calcIBUs(); }); $("#wh_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wh_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wh_instock").on('change', function (event) { hopinstock = event.args.checked; hoplist.dataBind(); }); $("#wh_select").jqxDropDownList({ placeHolder: "Kies hop:", theme: theme, source: hoplist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = hoplist.records[index]; return datarecord.origin+ " / " + datarecord.name + " (" + datarecord.alpha + " % α)"; } }); $("#wh_select").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = hoplist.records[index]; $("#wh_name").val(datarecord.name); hopData.h_name = datarecord.name; hopData.h_origin = datarecord.origin; hopData.h_cost = datarecord.cost; hopData.h_type = datarecord.type; hopData.h_form = datarecord.form; hopData.h_alpha = datarecord.alpha; hopData.h_beta = datarecord.beta; hopData.h_hsi = datarecord.hsi; hopData.h_humulene = datarecord.humulene; hopData.h_caryophyllene = datarecord.caryophyllene; hopData.h_cohumulone = datarecord.cohumulone; hopData.h_myrcene = datarecord.myrcene; hopData.h_total_oil = datarecord.total_oil; hopData.h_inventory = datarecord.inventory; } }); $("#wh_amount").jqxNumberInput( Spin1dec ); $('#wh_amount').on('change', function (event) { console.log("amount changed: "+event.args.value+" time:"+hopData.h_time+" alpha:"+hopData.h_alpha); var amount = parseFloat(event.args.value) / 1000; var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), amount, parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $("#ibu_method").val() ); hopData.h_amount = amount; $("#wh_ibu").val(ibu); }); $("#wh_ibu").jqxNumberInput( Show1dec ); $("#wh_time").jqxNumberInput( PosInt ); $("#wh_time").on('change', function (event) { var newtime = parseFloat(event.args.value); // Check limits and correct if (hopData.h_useat == 2) { // Boil if (newtime > parseFloat($("#boil_time").jqxNumberInput('decimal'))) { newtime = parseFloat($("#boil_time").jqxNumberInput('decimal')); $("#wh_time").val(newtime); } hopData.h_time = newtime; } else if (hopData.h_useat == 4) { // Whirlpool if (newtime > 120) { newtime = 120; $("#wh_time").val(newtime); } hopData.h_time = newtime; } else if (hopData.h_useat == 5) { // Dry hop if (newtime > 21) { newtime = 21; $("#wh_time").val(newtime); } hopData.h_time = newtime * 1440; } var ibu = toIBU(hopData.h_useat, hopData.h_form, preboil_sg, parseFloat($("#batch_size").jqxNumberInput('decimal')), parseFloat(hopData.h_amount), parseFloat(hopData.h_time), parseFloat(hopData.h_alpha), $("#ibu_method").val()); $("#wh_ibu").val(ibu); }); $("#wh_useat").jqxDropDownList({ theme: theme, source: HopUseAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wh_useat").on('select', function (event) { if (event.args) { var index = event.args.index; hopData.h_useat = index; if ((index == 0) || (index == 1)) { // Mashhop or First wort hop hopData.h_time = parseFloat(dataRecord.boil_time); $("#wh_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); $("#wh_time").val(hopData.h_time); } else if (index == 3) { // Aroma hopData.h_time = 0; $("#wh_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); $("#wh_time").val(0); } else { // Boil, Whirlpool or Dry hop $("#wh_time").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); } if (index == 5) // Dry hop $("#wh_pmpt_time").html("Tijd in dagen"); else $("#wh_pmpt_time").html("Tijd in minuten"); } }); // Tab 4, Diversen $("#popupMisc").jqxWindow({ width: 800, height: 275, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#MiscReady"), modalOpacity: 0.40 }); $("#MiscReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#MiscReady").click(function () { var rowID = $("#miscGrid").jqxGrid('getrowid', miscRow); console.log("MiscReady row:"+miscRow+" ID:"+rowID); var row = { m_name: miscData.m_name, m_amount: miscData.m_amount, m_cost: miscData.m_cost, m_type: miscData.m_type, m_use_use: miscData.m_use_use, m_time: miscData.m_time, m_amount_is_weight: miscData.m_amount_is_weight, m_inventory: miscData.m_inventory, m_avail: miscData.m_avail }; $("#miscGrid").jqxGrid('updaterow', rowID, row); }); $("#wm_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wm_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wm_instock").on('change', function (event) { miscinstock = event.args.checked; misclist.dataBind(); }); $("#wm_select").jqxDropDownList({ placeHolder: "Kies ingrediënt:", theme: theme, source: misclist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500 }); $("#wm_select").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = misclist.records[index]; $("#wm_name").val(datarecord.name); miscData.m_name = datarecord.name; miscData.m_cost = datarecord.cost; miscData.m_type = datarecord.type; miscData.m_use_use = datarecord.use_use; miscData.m_amount_is_weight = datarecord.amount_is_weight; miscData.m_inventory = datarecord.inventory; } }); $("#wm_amount").jqxNumberInput( Spin1dec ); $('#wm_amount').on('change', function (event) { console.log("amount changed: "+event.args.value); miscData.m_amount = parseFloat(event.args.value) / 1000; }); $("#wm_time").jqxNumberInput( PosInt ); $("#wm_time").on('change', function (event) { console.log("time changed: "+event.args.value); var newtime = parseFloat(event.args.value); if (miscData.m_use_use == 2) { // Boil if (newtime > parseFloat($("#boil_time").jqxNumberInput('decimal'))) { newtime = parseFloat($("#boil_time").jqxNumberInput('decimal')); $("#wm_time").val(newtime); } miscData.m_time = newtime; } else if ((miscData.m_use_use == 3) || (miscData.m_use_use == 4)) { // Primary or Secondary if (newtime > 21) { newtime = 21; $("#wm_time").val(newtime); } miscData.m_time = newtime * 1440; } }); $("#wm_use_use").jqxDropDownList({ theme: theme, source: MiscUseAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wm_use_use").on('select', function (event) { if (event.args) { var index = event.args.index; miscData.m_use_use = index; if ((index == 2) || (index == 3) || (index == 4)) { // Boil, Primary or Secondary $("#wm_time").jqxNumberInput({ spinButtons: true, readOnly: false, width: 110 }); } else { miscData.m_time = 0; $("#wm_time").jqxNumberInput({ spinButtons: false, readOnly: true, width: 90 }); $("#wm_time").val(0); } } }); // Tab 5, Gist $("#est_fg2").jqxTooltip({ content: 'Het eind SG. Dit wordt automatisch berekend.' }); $("#est_fg2").jqxNumberInput( Show3dec ); $("#est_abv2").jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' }); $("#est_abv2").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 1, readOnly: true }); $("#popupYeast").jqxWindow({ width: 800, height: 300, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#YeastReady"), modalOpacity: 0.40 }); $("#YeastReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#YeastReady").click(function () { var rowID = $("#yeastGrid").jqxGrid('getrowid', yeastRow); console.log("YeastReady row:"+yeastRow+" ID:"+rowID); var row = { y_name: yeastData.y_name, y_laboratory: yeastData.y_laboratory, y_product_id: yeastData.y_product_id, y_amount: yeastData.y_amount, y_cost: yeastData.y_cost, y_type: yeastData.y_type, y_form: yeastData.y_form, y_flocculation: yeastData.y_flocculation, y_min_temperature: yeastData.y_min_temperature, y_max_temperature: yeastData.y_max_temperature, y_attenuation: yeastData.y_attenuation, y_use: yeastData.y_use, y_cells: yeastData.y_cells, y_tolerance: yeastData.y_tolerance, y_inventory: yeastData.y_inventory, y_avail: yeastData.y_avail }; $("#yeastGrid").jqxGrid('updaterow', rowID, row); calcFermentables(); }); $("#wy_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wy_laboratory").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wy_product_id").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wy_instock").jqxCheckBox({ theme: theme, height: 23 }); $("#wy_instock").on('change', function (event) { yeastinstock = event.args.checked; yeastlist.dataBind(); }); $("#wy_select").jqxDropDownList({ placeHolder: "Kies gist:", theme: theme, source: yeastlist, displayMember: "name", width: 150, height: 23, dropDownWidth: 500, dropDownHeight: 500, renderer: function (index, label, value) { var datarecord = yeastlist.records[index]; return datarecord.laboratory+" "+datarecord.product_id+" "+datarecord.name; } }); $("#wy_select").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = yeastlist.records[index]; $("#wy_name").val(datarecord.name); $("#wy_laboratory").val(datarecord.laboratory); $("#wy_product_id").val(datarecord.product_id); yeastData.y_name = datarecord.name; yeastData.y_cost = datarecord.cost; yeastData.y_type = datarecord.type; yeastData.y_form = datarecord.form; yeastData.y_laboratory = datarecord.laboratory; yeastData.y_product_id = datarecord.product_id; yeastData.y_min_temperature = datarecord.min_temperature; yeastData.y_max_temperature = datarecord.max_temperature; yeastData.y_flocculation = datarecord.flocculation; yeastData.y_attenuation = datarecord.attenuation; yeastData.y_cells = datarecord.cells; yeastData.y_inventory = datarecord.inventory; if (yeastData.y_form == 0) { $("#wy_pmpt_amount").html("Pak(ken):"); } else if (yeastData.y_form == 1) { $("#wy_pmpt_amount").html("Gewicht gram:"); } else { $("#wy_pmpt_amount").html("Volume ml:"); } calcFermentables(); } }); $("#wy_amount").jqxNumberInput( Spin1dec ); $('#wy_amount').on('change', function (event) { console.log("amount changed: "+event.args.value); if (yeastData.y_form == 0) // Liquid var amount = parseFloat(event.args.value); else var amount = parseFloat(event.args.value) / 1000; yeastData.y_amount = amount; calcFermentables(); }); $("#wy_use").jqxDropDownList({ theme: theme, source: YeastUseAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true, dropDownVerticalAlignment: 'top' }); $("#wy_use").on('select', function (event) { if (event.args) { var index = event.args.index; yeastData.y_use = index; calcFermentabes(); } }); // Tab 6, Maischen $("#mash_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#mash_select").jqxDropDownList({ placeHolder: "Kies schema:", theme: theme, source: mashlist, displayMember: "name", width: 250, height: 23, dropDownWidth: 500, dropDownHeight: 500, dropDownHorizontalAlignment: 'right' }); $("#mash_select").on('select', function (event) { if (event.args) { var index = event.args.index; // First delete all current steps var rowIDs = new Array(); var rows = $("#mashGrid").jqxGrid('getdisplayrows'); for (var i = 0; i < rows.length; i++) { var row = rows[i]; rowIDs.push(row.uid); } $("#mashGrid").jqxGrid('deleterow', rowIDs); // Then add the new steps var datarecord = mashlist.records[index]; $("#mash_name").val(datarecord.name); for (var i = 0; i < datarecord.steps.length; i++) { var data = datarecord.steps[i]; var row = {}; row["step_name"] = data.step_name; row["step_type"] = data.step_type; // For now, but this must be smarter. if (mash_infuse == 0 && dataRecord.w1_amount > 0) mash_infuse = dataRecord.w1_amount; if (i == 0) row["step_infuse_amount"] = mash_infuse; else row["step_infuse_amount"] = 0; row["step_temp"] = data.step_temp; if (mashkg > 0) row["step_thickness"] = parseFloat(mash_infuse / mashkg); else row["step_thickness"] = 0; row["end_temp"] = data.end_temp; row["step_time"] = data.step_time; row["ramp_time"] = data.ramp_time; var commit = $("#mashGrid").jqxGrid('addrow', null, row); } } }); $("#popupMash").jqxWindow({ width: 800, height: 350, position: { x: 230, y: 100 }, resizable: false, theme: theme, isModal: true, autoOpen: false, cancelButton: $("#MashReady"), modalOpacity: 0.40 }); $("#MashReady").jqxButton({ template: "success", width: '90px', theme: theme }); $("#MashReady").click(function () { calcMash(); }); $("#wstep_name").jqxInput({ theme: theme, width: 320, height: 23 }); $("#wstep_name").on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_name = event.args.value; }); $("#wstep_type").jqxDropDownList({ theme: theme, source: MashStepTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 180, height: 23, autoDropDownHeight: true }); $("#wstep_type").on('select', function (event) { if (event.args) { var index = event.args.index; var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_type = index; if (index == 0) { $("#wstep_infuse_amount").show(); $("#wstep_pmpt").show(); } else { rowdata.step_infuse_amount = 0; $("#wstep_infuse_amount").hide(); $("#wstep_pmpt").hide(); } mash_infuse = 0; var rows = $('#mashGrid').jqxGrid('getrows'); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); } } }); $("#wstep_temp").jqxNumberInput( Spin1dec ); $('#wstep_temp').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_temp = parseFloat(event.args.value); }); $("#wend_temp").jqxNumberInput( Spin1dec ); $('#wend_temp').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.end_temp = parseFloat(event.args.value); }); $("#wstep_time").jqxNumberInput( PosInt ); $('#wstep_time').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_time = parseFloat(event.args.value); }); $("#wramp_time").jqxNumberInput( PosInt ); $('#wramp_time').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.ramp_time = parseFloat(event.args.value); }); $("#wstep_infuse_amount").jqxNumberInput( Spin1dec ); $('#wstep_infuse_amount').on('change', function (event) { var rowdata = $("#mashGrid").jqxGrid('getrowdata', mashRow); rowdata.step_infuse_amount = parseFloat(event.args.value); mash_infuse = 0; var rows = $('#mashGrid').jqxGrid('getrows'); for (var i = 0; i < rows.length; i++) { var row = rows[i]; if (row.step_type == 0) // Infusion mash_infuse += parseFloat(row.step_infuse_amount); } if (dataRecord.w2_amount == 0) { dataRecord.w1_amount = mash_infuse; $("#w1_amount").val(mash_infuse); } else { dataRecord.w1_amount = (dataRecord.w1_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; dataRecord.w2_amount = (dataRecord.w2_amount / (dataRecord.w1_amount + dataRecord.w2_amount)) * mash_infuse; $("#w1_amount").val(dataRecord.w1_amount); $("#w2_amount").val(dataRecord.w2_amount); } $('#wg_amount').val(mash_infuse); }); // Tab 7, Water $("#tgt_bu").jqxNumberInput( Show2wat ); $("#tgt_cl_so4").jqxNumberInput( Show1wat ); $("#got_cl_so4").jqxNumberInput( Show1wat ); // Water source 1 $("#w1_name").jqxDropDownList({ placeHolder: "Kies hoofd water:", theme: theme, source: waterlist, displayMember: "name", width: 250, height: 27, dropDownWidth: 400, dropDownHeight: 400 }); $("#w1_name").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = waterlist.records[index]; dataRecord.w1_name = datarecord.name; $("#w1_calcium").val(datarecord.calcium); dataRecord.w1_calcium = datarecord.calcium; $("#w1_sulfate").val(datarecord.sulfate); dataRecord.w1_sulfate = datarecord.sulfate; $("#w1_chloride").val(datarecord.chloride); dataRecord.w1_chloride = datarecord.chloride; $("#w1_sodium").val(datarecord.sodium); dataRecord.w1_sodium = datarecord.sodium; $("#w1_magnesium").val(datarecord.magnesium); dataRecord.w1_magnesium = datarecord.magnesium; $("#w1_total_alkalinity").val(datarecord.total_alkalinity); dataRecord.w1_total_alkalinity = datarecord.total_alkalinity; $("#w1_ph").val(datarecord.ph); dataRecord.w1_ph = datarecord.ph; $("#w1_cost").val(datarecord.cost); dataRecord.w1_cost = datarecord.cost; calcWater(); } }); $("#w1_amount").jqxNumberInput( Show1wat ); $("#w1_calcium").jqxNumberInput( Show1wat ); $("#w1_magnesium").jqxNumberInput( Show1wat ); $("#w1_sodium").jqxNumberInput( Show1wat ); $("#w1_total_alkalinity").jqxNumberInput( Show1wat ); $("#w1_chloride").jqxNumberInput( Show1wat ); $("#w1_sulfate").jqxNumberInput( Show1wat ); $("#w1_ph").jqxNumberInput( Show1wat ); // Water source 2 $("#w2_name").jqxDropDownList({ placeHolder: "Kies meng water:", theme: theme, source: waterlist, displayMember: "name", width: 250, height: 27, dropDownWidth: 400, dropDownHeight: 400 }); $("#w2_name").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = waterlist.records[index]; dataRecord.w2_name = datarecord.name; $("#w2_calcium").val(datarecord.calcium); dataRecord.w2_calcium = datarecord.calcium; $("#w2_sulfate").val(datarecord.sulfate); dataRecord.w2_sulfate = datarecord.sulfate; $("#w2_chloride").val(datarecord.chloride); dataRecord.w2_chloride = datarecord.chloride; $("#w2_sodium").val(datarecord.sodium); dataRecord.w2_sodium = datarecord.sodium; $("#w2_magnesium").val(datarecord.magnesium); dataRecord.w2_magnesium = datarecord.magnesium; $("#w2_total_alkalinity").val(datarecord.total_alkalinity); dataRecord.w2_total_alkalinity = datarecord.total_alkalinity; $("#w2_ph").val(datarecord.ph); dataRecord.w2_ph = datarecord.ph; $("#w2_cost").val(datarecord.cost); dataRecord.w2_cost = datarecord.cost; $("#w2_amount").jqxNumberInput({ max: 100000, readOnly: false }); // Set high max to enable the spinbuttons. calcWater(); } }); $("#w2_amount").jqxTooltip({ content: 'De verdeling van het hoofd en meng water. Het totale maisch water volume blijft gelijk.'}); $("#w2_amount").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 94, height: 23, min: 0, max: 0, decimalDigits: 1, spinButtons: true, readOnly: true }); $("#w2_calcium").jqxNumberInput( Show1wat ); $("#w2_magnesium").jqxNumberInput( Show1wat ); $("#w2_sodium").jqxNumberInput( Show1wat ); $("#w2_total_alkalinity").jqxNumberInput( Show1wat ); $("#w2_chloride").jqxNumberInput( Show1wat ); $("#w2_sulfate").jqxNumberInput( Show1wat ); $("#w2_ph").jqxNumberInput( Show1wat ); // Water mixed $("#wg_amount").jqxNumberInput( Show1wat ); $("#wg_calcium").jqxNumberInput( Show1wat ); $("#wg_magnesium").jqxNumberInput( Show1wat ); $("#wg_sodium").jqxNumberInput( Show1wat ); $("#wg_total_alkalinity").jqxNumberInput( Show1wat ); $("#wg_chloride").jqxNumberInput( Show1wat ); $("#wg_sulfate").jqxNumberInput( Show1wat ); $("#wg_ph").jqxNumberInput( Show1wat ); // Water treated $("#wb_calcium").jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'}); $("#wb_calcium").jqxNumberInput( Show1wat ); $("#wb_magnesium").jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is lager dan 30.'}); $("#wb_magnesium").jqxNumberInput( Show1wat ); $("#wb_sodium").jqxTooltip({ content: 'De ideale hoeveelheid Natrium is lager dan 150.'}); $("#wb_sodium").jqxNumberInput( Show1wat ); $("#wb_chloride").jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 100.'}); $("#wb_chloride").jqxNumberInput( Show1wat ); $("#wb_sulfate").jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 350.'}); $("#wb_sulfate").jqxNumberInput( Show1wat ); $("#wb_total_alkalinity").jqxNumberInput( Show1wat ); $("#wb_ph").jqxNumberInput( Show1wat ); // Water target profile $("#pr_name").jqxDropDownList({ placeHolder: "Kies doel profiel:", theme: theme, source: waterprofiles, displayMember: "name", width: 250, height: 27, dropDownWidth: 400, dropDownHeight: 300 }); $("#pr_name").on('select', function (event) { if (event.args) { var index = event.args.index; var datarecord = waterprofiles.records[index]; $("#pr_calcium").val(datarecord.calcium); $("#pr_sulfate").val(datarecord.sulfate); $("#pr_chloride").val(datarecord.chloride); $("#pr_sodium").val(datarecord.sodium); $("#pr_magnesium").val(datarecord.magnesium); $("#pr_total_alkalinity").val(datarecord.total_alkalinity); } }); $("#pr_calcium").jqxNumberInput( Show1wat ); $("#pr_magnesium").jqxNumberInput( Show1wat ); $("#pr_sodium").jqxNumberInput( Show1wat ); $("#pr_total_alkalinity").jqxNumberInput( Show1wat ); $("#pr_chloride").jqxNumberInput( Show1wat ); $("#pr_sulfate").jqxNumberInput( Show1wat ); // Water agents $("#wa_cacl2").jqxTooltip({ content: 'Voor het maken van een ander waterprofiel. Voegt calcium en chloride toe. Voor het verbeteren van zoetere bieren.'}); $("#wa_cacl2").jqxNumberInput( Spin1dec ); $("#wa_caso4").jqxTooltip({ content: 'Gips. Voor het maken van een ander waterprofiel. Voegt calcium en sulfaat toe. Voor het verbeteren van bittere bieren.'}); $("#wa_caso4").jqxNumberInput( Spin1dec ); $("#wa_mgso4").jqxTooltip({ content: 'Epsom zout. Voor het maken van een ander waterprofiel. Voegt magnesium en sulfaat toe. Gebruik spaarzaam!'}); $("#wa_mgso4").jqxNumberInput( Spin1dec ); $("#wa_nacl").jqxTooltip({ content: 'Keukenzout. Voor het maken van een ander waterprofiel. Voegt natrium en chloride toe. Voor het accentueren van zoetheid. Bij hoge dosering wordt het bier ziltig.'}); $("#wa_nacl").jqxNumberInput( Spin1dec ); $("#mash_ph").jqxTooltip({ content: 'Maisch pH tussen 5.2 en 5.6. Gebruik 5.2 voor lichte en 5.5 voor donkere bieren.'}); $("#mash_ph").jqxNumberInput( SpinpH ); $("#calc_acid").jqxCheckBox({ theme: theme, width: 120, height: 23 }); $("#wa_base_name").jqxDropDownList({ theme: theme, source: BaseTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 170, height: 23, autoDropDownHeight: true }); $("#wa_base").jqxNumberInput( Spin2dec ); $("#wa_base").jqxNumberInput({ symbol: ' gr', symbolPosition: 'right' }); $("#wa_acid_name").jqxDropDownList({ theme: theme, source: AcidTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 170, height: 23, autoDropDownHeight: true }); $("#wa_acid").jqxNumberInput( Spin2dec ); $("#wa_acid").jqxNumberInput({ symbol: ' ml', symbolPosition: 'right' }); $("#wa_acid_perc").jqxNumberInput( Perc0 ); $("#wa_acid_perc").jqxNumberInput({ width: 70, symbol: '%', symbolPosition: 'right' }); // Sparge water $("#sparge_temp").jqxNumberInput( Spin1dec ); $("#sparge_volume").jqxNumberInput( Spin1dec ); $("#sparge_ph").jqxNumberInput( SpinpH ); $("#sparge_source").jqxDropDownList({ theme: theme, source: SpargeSourceAdapter, valueMember: 'id', displayMember: 'nl', width: 110, height: 23, autoDropDownHeight: true }); $("#sparge_acid_amount").jqxNumberInput( Spin2dec ); $("#sparge_acid_amount").jqxNumberInput({ spinButtons: false, readOnly: true, symbol: ' ml', symbolPosition: 'right' }); $("#sparge_acid_type").jqxDropDownList({ theme: theme, source: AcidTypeAdapter, valueMember: 'id', displayMember: 'nl', width: 110, height: 23, autoDropDownHeight: true }); $("#sparge_acid_perc").jqxNumberInput( Perc0 ); $("#sparge_acid_perc").jqxNumberInput({ symbol: '%', symbolPosition: 'right' }); // Tabs inside the popup window. $('#jqxTabs').jqxTabs({ theme: theme, width: 1280, height: 660, autoHeight: false, position: 'top' }); // Buttons below $("#Export").jqxButton({ template: "info", width: '80px', theme: theme }); $("#Export").bind('click', function () { saveRecord(); var url="rec_export.php?record=" + my_record + "&return=" + my_return + "&name=" + dataRecord.name; window.location.href = url; }); $("#Delete").jqxButton({ template: "danger", width: '80px', theme: theme }); $("#Delete").bind('click', function () { // Open a popup to confirm this action. $('#eventWindow').jqxWindow('open'); $("#delOk").click(function () { var data = "delete=true&" + $.param({ record: my_record }); $.ajax({ dataType: 'json', url: url, cache: false, data: data, type: "POST", success: function (data, status, xhr) { // delete command is executed. window.location.href = my_return; }, error: function (jqXHR, textStatus, errorThrown) { } }); }); }); $("#Cancel").jqxButton({ template: "primary", width: '80px', theme: theme }); $("#Cancel").bind('click', function () { window.location.href = my_return; }); $("#Save").jqxButton({ template: "success", width: '80px', theme: theme }); $("#Save").bind('click', function () { saveRecord(); window.location.href = my_return; }); createDelElements(); });