# HG changeset patch # User Michiel Broek # Date 1537901886 -7200 # Node ID 2ff83855d5745ff56eba5e5ec6b699e4d4311974 # Parent 883e897aad40718d4c690454aaafa9762e6fa896 Added recipe editor screen diff -r 883e897aad40 -r 2ff83855d574 www/includes/global.inc.php --- a/www/includes/global.inc.php Mon Sep 24 22:13:50 2018 +0200 +++ b/www/includes/global.inc.php Tue Sep 25 20:58:06 2018 +0200 @@ -30,10 +30,20 @@ require_once($_SERVER['DOCUMENT_ROOT'].'/config.php'); require_once($_SERVER['DOCUMENT_ROOT'].'/version.php'); +if (isset($_GET['record'])) + $my_record = $_GET['record']; +else + $my_record = -1; +if (isset($_GET['return'])) + $my_return = $_GET['return']; +else + $my_return = ''; function page_header($title, $loadjs) { global $my_style; global $my_version; + global $my_record; + global $my_return; ?> @@ -46,6 +56,8 @@ diff -r 883e897aad40 -r 2ff83855d574 www/js/rec_edit.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/www/js/rec_edit.js Tue Sep 25 20:58:06 2018 +0200 @@ -0,0 +1,1150 @@ +/***************************************************************************** + * Copyright (C) 2018 + * + * Michiel Broek + * + * 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 () { + + console.log("record:" + my_record + " return:" + my_return + " theme:" + theme); + +// $("#jqxNotification").jqxNotification({ width: "auto", position: "top-right", opacity: 0.9, +// autoOpen: false, closeOnClick: true, autoClose: true, template: "info", blink: false, +// icon: { width: 25, height: 25, url: '../../images/smiley.png', padding: 5 } +// }); + + var dataReecord = {}; + var url = "includes/db_recipes.php"; + // tooltips + $("#name").jqxTooltip({ content: 'De naam voor dit recept.' }); + $("#notes").jqxTooltip({ content: 'De uitgebreide opmerkingen over dit recept.' }); + $("#st_name").jqxTooltip({ content: 'De bierstijl naam voor dit recept.'}); + $("#type").jqxTooltip({ content: 'Het brouw type van dit recept.' }); + // prepare the data + var source = { + datatype: "json", + cache: false, + datafields: [ + { name: 'record', type: 'number' }, + { name: 'st_name', type: 'string' }, + { name: 'st_letter', type: 'string' }, + { name: 'st_guide', type: 'string' }, + { 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: 'number' }, + { name: 'batch_size', type: 'float' }, + { name: 'boil_time', type: 'float' }, + { name: 'efficiency', type: 'float' }, + { name: 'est_og', type: 'float' }, + { name: 'est_fg', type: 'float' }, + { name: 'est_color', type: 'float' }, + { name: 'color_method', type: 'string' }, + { name: 'est_ibu', type: 'float' }, + { name: 'ibu_method', type: 'string' }, + { name: 'mash_sparge_temp', type: 'float' }, + { name: 'mash_ph', type: 'float' }, + { name: 'mash_name', type: 'string' }, + { name: 'fermentables', type: 'string' }, + { name: 'hops', type: 'string' }, + { name: 'miscs', type: 'string' }, + { name: 'yeasts', type: 'string' }, + { name: 'waters', type: 'array' }, + { name: 'mashs', type: 'string' } + ], + id: 'record', + url: url + }; + // Load data and select one record. + var dataAdapter = new $.jqx.dataAdapter(source, { + loadComplete: function () { + var records = dataAdapter.records; + dataRecord = records[0]; + $("#name").val(dataRecord.name); + $("#notes").val(dataRecord.notes); + $("#st_name").val(dataRecord.st_name); + $("#st_letter").val(dataRecord.st_letter); + $("#st_guide").val(dataRecord.st_guide); + $("#type").val(dataRecord.type); + $("#batch_size").val(dataRecord.batch_size); + $("#boil_time").val(dataRecord.boil_time); + $("#efficiency").val(dataRecord.efficiency); + $("#est_og").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_color").val(dataRecord.est_color); + $("#color_method").val(dataRecord.color_method); + $("#est_ibu").val(dataRecord.est_ibu); + $("#ibu_method").val(dataRecord.ibu_method); + $("#mash_name").val(dataRecord.mash_name); + $("#mash_ph").val(dataRecord.mash_ph); + $("#mash_sparge_temp").val(dataRecord.mash_sparge_temp); + editFermentable(dataRecord); + editHop(dataRecord); + editMisc(dataRecord); + editYeast(dataRecord); + editWater(dataRecord); + editMash(dataRecord); + }, + loadError: function (jqXHR, status, error) { + }, + beforeLoadComplete: function (records) { + var filteredRecords = []; + for (var i = 0; i < records.length; i++) { + if (records[i].record == my_record) { + filteredRecords.push(records[i]); + } + } + return filteredRecords; + } + }); + dataAdapter.dataBind(); + + // Inline fermentables editor + var editFermentable = function (data) { + var fermentableSource = { + localdata: data.fermentables, + datatype: "local", + 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: 'string' }, + { 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: 'string' }, + { name: 'f_added', type: 'string' }, + { name: 'f_dissolved_protein', type: 'float' }, + { name: 'f_recommend_mash', type: 'bool' }, + { name: 'f_add_after_boil', type: 'bool' }, + { name: 'f_adjust_to_total_100', type: 'bool' }, + { name: 'f_percentage', type: 'float' }, + { name: 'f_di_ph', type: 'float' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var fermentableAdapter = new $.jqx.dataAdapter(fermentableSource); + // dropdownlist datasource from inventory_fermentables + var fermentableUrl = "getfermentablesources.php"; + var fermentableInvSource = { + datatype: "json", + datafields: [ + { name: 'record', type: 'number' }, + { name: 'name', type: 'string' }, + { name: 'type', type: 'string' }, + { name: 'yield', type: 'float' }, + { name: 'color', type: 'float' }, + { name: 'add_after_boil', type: 'bool' }, + { name: 'origin', type: 'string' }, + { name: 'supplier', type: 'string' }, + { name: 'coarse_fine_diff', type: 'float' }, + { name: 'moisture', type: 'float' }, + { name: 'diastatic_power', type: 'float' }, + { name: 'protein', type: 'float' }, + { name: 'max_in_batch', type: 'float' }, + { name: 'recommend_mash', type: 'bool' }, + { name: 'graintype', type: 'string' }, + { name: 'di_ph', type: 'float' }, + { name: 'inventory', type: 'float' }, + { name: 'cost', type: 'float' } + ], + url: fermentableUrl, + async: true + }; + var fermentablelist = new $.jqx.dataAdapter(fermentableInvSource); + + $("#fermentableGrid").jqxGrid({ + width: 960, + height: 400, + source: fermentableAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedrow', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append(''); + // add fermentable from dropdownlist. + $("#faddrowbutton").jqxDropDownList({ + placeHolder: "Kies mout:", + theme: theme, + 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.type == "Sugar") { + row["f_added"] = "Boil"; + } else { + row["f_added"] = "Mash"; + } + row["f_dissolved_protein"] = 0; + 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; + var commit = $("#fermentableGrid").jqxGrid('addrow', null, row); + } + }); + + // delete selected fermentable. + // Precentage aanpassen basis mout. + $("#fdeleterowbutton").jqxButton({ 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 commit = $("#fermentableGrid").jqxGrid('deleterow', id); + } + }); + }, + columns: [ + { text: 'Mout/suiker', editable: false, datafield: 'f_name', + cellsrenderer: function (row, columnfield, value, defaulthtml, columnproperties) { + var rowData = $("#fermentableGrid").jqxGrid('getrowdata', row); + return rowData.f_name + " (" + rowData.f_color + " EBC)"; + } + }, + { text: 'Type', editable: false, width: 100, datafield: 'f_type' }, + { text: 'Opbrengst', editable: false, datafield: 'f_yield', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, + { text: 'Gewicht', datafield: 'f_amount', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'f3', + columntype: 'numberinput', + validation: function (cell, value) { + // Maximum weight is the batch_size, just a simple check. + var maxmout = parseFloat($("#batch_size").jqxNumberInput('decimal')); + if (value < 0 || value > maxmout) { + return { result: false, message: "Gewicht moet 0-"+maxmout+" zijn" }; + } + return true; + }, + initeditor: function (row, cellvalue, editor) { + editor.jqxNumberInput({ decimalDigits: 3 }); + } + }, + { text: 'Procent', datafield: 'f_percentage', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'p1', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100) { + return { result: false, message: "Percentage moet 0-100 zijn" }; + } + return true; + }, + initeditor: function (row, cellvalue, editor) { + editor.jqxNumberInput({ decimalDigits: 1 }); + } + }, + { text: '100%', datafield: 'f_adjust_to_total_100', columntype: 'checkbox', width: 80 } + ] + }); + $("#fermentableGrid").on('cellendedit', function (event) { + $('#fermentableGrid').jqxGrid('sortby', 'f_amount', 'desc'); + }); + }; + + // Inline hops editor + var editHop = function (data) { + var hopSource = { + localdata: data.hops, + datatype: "local", + cache: 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: 'string' }, + { name: 'h_form', type: 'string' }, + { name: 'h_useat', type: 'string' }, + { 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_carophyllene', type: 'float' }, + { name: 'h_cohumulone', type: 'float' }, + { name: 'h_myrcene', type: 'float' }, + { name: 'h_total_oil', type: 'float' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var hopAdapter = new $.jqx.dataAdapter(hopSource); + // dropdownlist datasource from inventory_hops + var hopUrl = "gethopsources.php"; + var hopInvSource = { + datatype: "json", + datafields: [ + { name: 'record', type: 'number' }, + { name: 'name', type: 'string' }, + { name: 'origin', type: 'string' }, + { name: 'type', type: 'string' }, + { name: 'alpha', type: 'float' }, + { name: 'beta', type: 'float' }, + { name: 'humulene', type: 'float' }, + { name: 'caryophyllene', type: 'float' }, + { name: 'cohumulone', type: 'float' }, + { name: 'myrcene', type: 'float' }, + { name: 'hsi', type: 'float' }, + { name: 'useat', type: 'string' }, + { name: 'form', type: 'string' }, + { name: 'total_oil', type: 'float' }, + { name: 'cost', type: 'float' } + ], + url: hopUrl, + async: true + }; + var hoplist = new $.jqx.dataAdapter(hopInvSource); + + $("#hopGrid").jqxGrid({ + width: 960, + height: 400, + source: hopAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedrow', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append(''); + // add hop from dropdownlist. + $("#haddrowbutton").jqxDropDownList({ + placeHolder: "Kies hop:", + theme: theme, + source: hoplist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 300 + }); + $("#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"] = datarecord.useat; + 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_carophyllene"] = datarecord.carophyllene; + row["h_cohumulone"] = datarecord.cohumulone; + row["h_myrcene"] = datarecord.myrcene; + row["h_total_oil"] = datarecord.total_oil; + var commit = $("#hopGrid").jqxGrid('addrow', null, row); + } + }); + + // delete selected hop. + $("#hdeleterowbutton").jqxButton({ 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); + } + }); + }, + columns: [ + { text: 'Hop', editable: false, datafield: 'h_name' }, + { text: 'Type', editable: false, width: 90, align: 'center', cellsalign: 'center', datafield: 'h_type' }, + { text: 'Vorm', editable: false, width: 90, align: 'center', cellsalign: 'center', datafield: 'h_form' }, + { text: 'Alpha', datafield: 'h_alpha', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'p1' }, + { text: 'Gewicht', datafield: 'h_amount', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'f3', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100000000000 ) { + return { result: false, message: "Volume moet 0-~ zijn" }; + } + return true; + } + }, + { text: 'Gebruik', width: 110, align: 'center', cellsalign: 'center', datafield: 'h_useat' }, + { text: 'Tijd', datafield: 'h_time', width: 70, align: 'right', cellsalign: 'right', cellsformat: 'f0', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100000000000 ) { + return { result: false, message: "De tijd moet 0-~ zijn" }; + } + return true; + } // TODO: Only enable editing if Boil, else use fixed values. + }, + { text: 'IBU', editable: false, datafield: 'ibu', width: 80, align: 'right', + cellsrenderer: function (index, datafield, value, defaultvalue, column, rowdata) { + var ibu = toIBU(rowdata.h_useat, + rowdata.h_form, + parseFloat($("#est_og").jqxNumberInput('decimal')), + parseFloat($("#batch_size").jqxNumberInput('decimal')), + parseFloat(rowdata.h_amount), + parseFloat(rowdata.h_time), + parseFloat(rowdata.h_alpha), + $("#ibu_method").val() + ); + return "
" + dataAdapter.formatNumber(ibu, "f1") + "
"; + } + } + ] + }) + }; + + // Inline miscs editor + var editMisc = function (data) { + var miscSource = { + localdata: data.miscs, + datatype: "local", + cache: false, + datafields: [ + { name: 'm_name', type: 'string' }, + { name: 'm_amount', type: 'float' }, + { name: 'm_cost', type: 'float' }, + { name: 'm_type', type: 'string' }, + { name: 'm_use_use', type: 'string' }, + { name: 'm_time', type: 'float' }, + { name: 'm_amount_is_weight', type: 'bool' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var miscAdapter = new $.jqx.dataAdapter(miscSource); + // dropdownlist datasource from inventory_miscs + var miscUrl = "getmiscsources.php"; + var miscInvSource = { + datatype: "json", + datafields: [ + { name: 'record', type: 'number' }, + { name: 'name', type: 'string' }, + { name: 'type', type: 'string' }, + { name: 'use_use', type: 'string' }, + { name: 'amount_is_weight', type: 'bool' }, + { name: 'time', type: 'float' }, + { name: 'cost', type: 'float' } + ], + url: miscUrl, + async: true + }; + var misclist = new $.jqx.dataAdapter(miscInvSource); + + $("#miscGrid").jqxGrid({ + width: 960, + height: 400, + source: miscAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedrow', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append(''); + // add misc from dropdownlist. + $("#maddrowbutton").jqxDropDownList({ + placeHolder: "Kies ingredient:", + theme: theme, + source: misclist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 300 + }); + $("#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; + var commit = $("#miscGrid").jqxGrid('addrow', null, row); + } + }); + // delete selected misc. + $("#mdeleterowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#mdeleterowbutton").on('click', function () { + var selectedrowindex = $("#miscGrid").jqxGrid('getselectedrowindex'); + var rowscount = $("#miscGrid").jqxGrid('getdatainformation').rowscount; + if (selectedrowindex >= 0 && selectedrowindex < rowscount) { + var id = $("#miscGrid").jqxGrid('getrowid', selectedrowindex); + var commit = $("#miscGrid").jqxGrid('deleterow', id); + } + }); + }, + columns: [ + { text: 'Ingredient', editable: false, datafield: 'm_name' }, + { text: 'Type', editable: false, width: 120, align: 'center', cellsalign: 'center', datafield: 'm_type' }, + { text: 'Gebruik', editable: false, width: 90, align: 'center', cellsalign: 'center', datafield: 'm_use_use' }, + { text: 'Gewicht', datafield: 'm_amount', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'f5', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100000000000 ) { + return { result: false, message: "Volume moet 0-~ zijn" }; + } + return true; + } + }, + { text: 'Tijd', datafield: 'm_time', width: 70, align: 'right', cellsalign: 'right', cellsformat: 'f0', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100000000000 ) { + return { result: false, message: "De tijd moet 0-~ zijn" }; + } + return true; + } + } + ] + }) + }; + + // Inline yeasts editor + var editYeast = function (data) { + var yeastSource = { + localdata: data.yeasts, + datatype: "local", + cache: 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: 'string' }, + { name: 'y_form', type: 'string' }, + { name: 'y_time', type: 'float' }, + { name: 'y_min_temperature', type: 'float' }, + { name: 'y_max_temperature', type: 'float' }, + { name: 'y_attenuation', type: 'float' }, + { name: 'y_amount_is_weight', type: 'bool' }, + { name: 'y_use', type: 'string' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var yeastAdapter = new $.jqx.dataAdapter(yeastSource); + // dropdownlist datasource from inventory_yeasts + var yeastUrl = "getyeastsources.php"; + var yeastInvSource = { + datatype: "json", + datafields: [ + { name: 'record', type: 'number' }, + { name: 'name', type: 'string' }, + { name: 'type', type: 'string' }, + { name: 'form', type: 'string' }, + { name: 'laboratory', type: 'string' }, + { name: 'product_id', type: 'string' }, + { name: 'min_temperature', type: 'float' }, + { name: 'max_temperature', type: 'float' }, + { name: 'attenuation', type: 'float' }, + { name: 'cost', type: 'float' } + ], + url: yeastUrl, + async: true + }; + var yeastlist = new $.jqx.dataAdapter(yeastInvSource); + + $("#yeastGrid").jqxGrid({ + width: 1050, + height: 300, + source: yeastAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedrow', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append(''); + // add yeast from dropdownlist. + $("#yaddrowbutton").jqxDropDownList({ + placeHolder: "Kies gist:", + theme: theme, + source: yeastlist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 300 + }); + $("#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"] = "Primary"; + row["y_time"] = 0; + if (datarecord.form == "Dry") { + row["y_amount_is_weight"] = 1; + } else { + row["y_amount_is_weight"] = 0; + } + row["y_min_temperature"] = datarecord.min_temperature; + row["y_max_temperature"] = datarecord.max_temperature; + row["y_attenuation"] = datarecord.attenuation; + var commit = $("#yeastGrid").jqxGrid('addrow', null, row); + } + }); + // delete selected yeast. + $("#ydeleterowbutton").jqxButton({ 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); + } + }); + }, + columns: [ + { text: 'Gist', editable: false, datafield: 'y_name' }, + { text: 'Laboratorium', editable: false, width: 150, datafield: 'y_laboratory' }, + { text: 'Code', editable: false, width: 90, datafield: 'y_product_id' }, + { text: 'Soort', editable: false, width: 80, align: 'center', cellsalign: 'center', datafield: 'y_form' }, + { text: 'Min.', editable: false, width: 70, align: 'right', cellsalign: 'right', datafield: 'y_min_temperature' }, + { text: 'Max.', editable: false, width: 70, align: 'right', cellsalign: 'right', datafield: 'y_max_temperature' }, + { text: 'Attn.', editable: false, width: 70, align: 'right', cellsalign: 'right', datafield: 'y_attenuation', cellsformat: 'f1' }, + { text: 'Voor', editable: false, width: 80, align: 'center', cellsalign: 'center', datafield: 'y_use' }, + { text: 'Hoeveel', datafield: 'y_amount', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'f5', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100000000000 ) { + return { result: false, message: "Volume moet 0-~ zijn" }; + } + return true; + } + } + ] + }) + }; + + // Inline waters editor + var editWater = function (data) { + var waterSource = { + localdata: data.waters, + datatype: "local", + datafields: [ + { name: 'w_name', type: 'string' }, + { name: 'w_amount', type: 'float' }, + { name: 'w_calcium', type: 'float' }, + { name: 'w_sulfate', type: 'float' }, + { name: 'w_chloride', type: 'float' }, + { name: 'w_sodium', type: 'float' }, + { name: 'w_magnesium', type: 'float' }, + { name: 'w_ph', type: 'float' }, + { name: 'w_total_alkalinity', type: 'float' }, + { name: 'w_cost', type: 'float' }, + { name: 'w_default_water', type: 'bool' } + ], + addrow: function (rowid, rowdata, position, commit) { + commit(true); + }, + deleterow: function (rowid, commit) { + commit(true); + } + }; + var waterAdapter = new $.jqx.dataAdapter(waterSource); + // dropdownlist datasource from inventory_waters + var waterUrl = "getwatersources.php"; + var waterInvSource = { + datatype: "json", + datafields: [ + { name: 'record', type: 'number' }, + { name: 'name', type: 'string' }, + { name: 'unlimited_stock', type: 'bool' }, + { name: 'calcium', type: 'float' }, + { name: 'sulfate', type: 'float' }, + { name: 'chloride', type: 'float' }, + { name: 'sodium', type: 'float' }, + { name: 'magnesium', type: 'float' }, + { name: 'ph', type: 'float' }, + { name: 'total_alkalinity', type: 'float' }, + { name: 'cost', type: 'float' }, + { name: 'default_water', type: 'bool' } + ], + url: waterUrl, + async: true + }; + var waterlist = new $.jqx.dataAdapter(waterInvSource); + + $("#waterGrid").jqxGrid({ + width: 960, + height: 200, + source: waterAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedrow', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append('
'); + container.append(''); + // add water from dropdownlist. + $("#waddrowbutton").jqxDropDownList({ + placeHolder: "Kies water:", + theme: theme, + source: waterlist, + displayMember: "name", + width: 150, + height: 27, + dropDownWidth: 300 + }); + $("#waddrowbutton").on('select', function (event) { + if (event.args) { + var index = event.args.index; + var datarecord = waterlist.records[index]; + var row = {}; + row["w_name"] = datarecord.name; + row["w_amount"] = 0; + row["w_calcium"] = datarecord.calcium; + row["w_sulfate"] = datarecord.sulfate; + row["w_chloride"] = datarecord.chloride; + row["w_sodium"] = datarecord.sodium; + row["w_magnesium"] = datarecord.magnesium; + row["w_ph"] = datarecord.ph; + row["w_total_alkalinity"] = datarecord.total_alkalinity; + row["w_default_water"] = datarecord.default_water; + row["w_cost"] = datarecord.cost; + var commit = $("#waterGrid").jqxGrid('addrow', null, row); + } + }); + + // delete selected water. + // Overgebleven waters in volume verhogen met het verwijderde water. + $("#wdeleterowbutton").jqxButton({ theme: theme, height: 27, width: 150 }); + $("#wdeleterowbutton").on('click', function () { + var selectedrowindex = $("#waterGrid").jqxGrid('getselectedrowindex'); + var rowscount = $("#waterGrid").jqxGrid('getdatainformation').rowscount; + if (selectedrowindex >= 0 && selectedrowindex < rowscount) { + var id = $("#waterGrid").jqxGrid('getrowid', selectedrowindex); + var commit = $("#waterGrid").jqxGrid('deleterow', id); + } + }); + }, + columns: [ + { text: 'Water bron', editable: false, datafield: 'w_name' }, + { text: 'Volume', datafield: 'w_amount', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1', + columntype: 'numberinput', + validation: function (cell, value) { + if (value < 0 || value > 100000000000 ) { + return { result: false, message: "Volume moet 0-~ zijn" }; + } + return true; + } + }, + // TODO: validator test max is hoeveelheid maischwater. Dan water verdelen voor totaal. + { text: 'Ca', editable: false, datafield: 'w_calcium', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, + { text: 'Mg', editable: false, datafield: 'w_magnesium', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, + { text: 'Na', editable: false, datafield: 'w_sodium', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, + { text: 'Tot Alk', editable: false, datafield: 'w_total_alkalinity', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, + { text: 'CaSO4', editable: false, datafield: 'w_sulfate', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, + { text: 'Cl', editable: false, datafield: 'w_chloride', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' }, + { text: 'pH', editable: false, datafield: 'w_ph', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' } + ] + }); + }; // editWater = function (data) { + + // inline mash editor + var editMash = function (data) { + var generaterow = function () { + var row = {}; + row["step_name"] = "Stap 1"; + row["step_type"] = "Infusion"; + row["step_infuse_amount"] = 15; + row["step_temp"] = 62.0; + row['step_time'] = 20.0; + row['ramp_time'] = 1.0; + row['end_temp'] = 62.0; + return row; + } + var mashSource = { + localdata: data.mashs, + datatype: "local", + cache: false, + datafields: [ + { name: 'step_name', type: 'string' }, + { name: 'step_type', type: 'string' }, + { name: 'step_infuse_amount', type: 'float' }, + { name: 'step_temp', type: 'float' }, + { name: 'step_time', 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); + // dropdownlist datasource from profile_mash + var mashUrl = "include/db_profile_mash.php"; + var mashInvSource = { + datatype: "json", + datafields: [ + { name: 'record', type: 'number' }, + { name: 'name', type: 'string' }, + { name: 'steps', type: 'array' } + ], + url: mashUrl, + async: true + }; + var mashlist = new $.jqx.dataAdapter(mashInvSource); + + $("#mashGrid").jqxGrid({ + width: 960, + height: 400, + source: mashAdapter, + theme: theme, + selectionmode: 'singlerow', + editmode: 'selectedrow', + editable: true, + localization: getLocalization(), + showtoolbar: true, + rendertoolbar: function (toolbar) { + var me = this; + var container = $("
"); + toolbar.append(container); + container.append(''); + container.append(''); + $("#saddrowbutton").jqxButton({ 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({ 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); + } + }); + }, + columns: [ + { text: 'Stap naam', datafield: 'step_name' }, + { text: 'Stap type', datafield: 'step_type', width: 110, columntype: 'dropdownlist', + createeditor: function (row, cellvalue, editor, celltext, cellwidth, cellheight) { + var dataSource = [ "Infusion", "Temperature", "Decoction" ]; + editor.jqxDropDownList({ source: dataSource, dropDownHeight: 105 }); + } + }, + { text: 'Temperatuur', datafield: 'step_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1', + validation: function (cell, value) { + if (value < 35 || value > 80) { + return { result: false, message: "De temperatuur moet tussen 35 en 80 zijn." }; + } + return true; + } + }, + { text: 'Eind', datafield: 'end_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1', + validation: function (cell, value) { + if (value < 35 || value > 80) { + return { result: false, message: "De temperatuur moet tussen 35 en 80 zijn." }; + } + return true; + } + }, + { text: 'Tijd', datafield: 'step_time', width: 70, align: 'right', cellsalign: 'right', + validation: function (cell, value) { + if (value < 1 || value > 360) { + return { result: false, message: "De tijd moet tussen 1 en 360 zijn." }; + } + return true; + } + }, + { text: 'Stap', datafield: 'ramp_time', width: 70, align: 'right', cellsalign: 'right', + validation: function (cell, value) { + if (value < 1 || value > 60) { + return { result: false, message: "De tijd moet tussen 1 en 60 zijn." }; + } + return true; + } + }, + { text: 'Infuse', datafield: 'step_infuse_amount', width: 70, align: 'right', cellsalign: 'right', + validation: function (cell, value) { + if (value < 0 || value > 60) { + return { result: false, message: "De waarde moet tussen 0 en 60 zijn." }; + } + return true; + } + } + ] + }); + $("#mashGrid").on('cellendedit', function (event) { + $('#mashGrid').jqxGrid('sortby', 'step_temp', 'asc'); + }); + }; + + // initialize the input fields. + var srcType = [ "All Grain", "Partial Mash", "Extract" ]; + var srcColor = [ "Morey", "Mosher", "Daniels" ]; + var srcIBU = [ "Tinseth", "Rager", "Garetz", "Daniels", "Mosher", "Noonan" ]; + $("#name").jqxInput({ theme: theme, width: 640, height: 23 }); + $("#notes").jqxInput({ theme: theme, width: 960, height: 200 }); + $("#st_name").jqxInput({ theme: theme, width: 250, height: 23 }); + $("#st_letter").jqxInput({ theme: theme, width: 100, height: 23 }); + $("#st_guide").jqxInput({ theme: theme, width: 250, height: 23 }); + $("#type").jqxDropDownList({ theme: theme, source: srcType, width: 125, height: 23, dropDownHeight: 95 }); + $("#batch_size").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 4, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: 'L', symbolPosition: 'right' }); + $("#boil_time").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', template: "success", theme: theme, width: 100, height: 23, min: 4, max: 360, decimalDigits: 0, spinButtons: true }); + $("#efficiency").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 40, max: 100, decimalDigits: 0, spinButtons: true, symbol: '%', symbolPosition: 'right' }); + $("#est_og").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 1, max: 1.9, decimalDigits: 3, spinButtons: true, spinButtonsStep: 0.001 }); + $("#st_og_min").jqxNumberInput({ disabled: true, inputMode: 'simple', width: 50, height: 23, decimalDigits: 3, readOnly: true }); + $("#st_og_max").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true }); + $("#est_fg").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, min: 0.980, max: 1.040, decimalDigits: 3, readOnly: true }); + $("#est_color").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 1, max: 200, decimalDigits: 0, spinButtons: true }); + $("#color_method").jqxDropDownList({ theme: theme, source: srcColor, width: 125, height: 23, dropDownHeight: 95 }); + $("#est_ibu").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, max: 200, decimalDigits: 0, spinButtons: true }); + $("#ibu_method").jqxDropDownList({ theme: theme, source: srcIBU, width: 125, height: 23, dropDownHeight: 180 }); + $("#mash_name").jqxInput({ theme: theme, width: 320, height: 23 }); + $("#mash_ph").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 4, max: 8, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); + $("#mash_sparge_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 70, max: 98, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 }); + + // Tabs inside the popup window. + $('#jqxTabs').jqxTabs({ + theme: theme, + width: 1280, + height: 630, + autoHeight: false, + position: 'top' + }); + + $("#Delete").jqxButton({ template: "danger", width: '80px', theme: theme }); + $("#Delete").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").click(function () { + window.location.href = my_return; + }); + + $("#Save").jqxButton({ template: "success", width: '90px', theme: theme }); + $("#Save").click(function () { + var fermentablerow = $('#fermentableGrid').jqxGrid('getrows'); + var hoprow = $('#hopGrid').jqxGrid('getrows'); + var miscrow = $('#miscGrid').jqxGrid('getrows'); + var yeastrow = $('#yeastGrid').jqxGrid('getrows'); + var waterrow = $('#waterGrid').jqxGrid('getrows'); + var mashrow = $('#mashGrid').jqxGrid('getrows'); + var row = { + record: my_record, + name: $("#name").val(), + notes: $("#notes").val(), + st_name: $('#st_name').val(), + st_letter: $('#st_letter').val(), + st_guide: $('#st_guide').val(), + st_og_min: dataRecord.st_og_min, + st_og_max: dataRecord.st_og_max, + st_fg_min: dataRecord.st_fg_min, + st_fg_max: dataRecord.st_fg_max, + st_ibu_min: dataRecord.st_ibu_min, + st_ibu_max: dataRecord.st_ibu_max, + st_color_min: dataRecord.st_color_min, + st_color_max: dataRecord.st_color_max, + st_carb_min: dataRecord.st_carb_min, + st_carb_max: dataRecord.st_carb_max, + st_abv_min: dataRecord.st_abv_min, + st_abv_max: dataRecord.st_abv_max, + type: $("#type").val(), + batch_size: parseFloat($("#batch_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_color: parseFloat($("#est_color").jqxNumberInput('decimal')), + color_method: $("#color_method").val(), + est_ibu: parseFloat($("#est_ibu").jqxNumberInput('decimal')), + ibu_method: $("#ibu_method").val(), + mash_name: $("#mash_name").val(), + mash_ph: parseFloat($("#mash_ph").jqxNumberInput('decimal')), + mash_sparge_temp: parseFloat($("#mash_sparge_temp").jqxNumberInput('decimal')), + fermentables: fermentablerow, + hops: hoprow, + miscs: miscrow, + yeasts: yeastrow, + waters: waterrow, + mashs: mashrow + }; + var data = "update=true&" + $.param(row); + $.ajax({ + dataType: 'json', + url: url, + cache: false, + data: data, + type: "POST", + success: function (data, status, xhr) { + // update command is executed. + window.location.href = my_return; + }, + error: function(jqXHR, textStatus, errorThrown) { + } + }); + }); + createDelElements(); +}); + diff -r 883e897aad40 -r 2ff83855d574 www/js/rec_main.js --- a/www/js/rec_main.js Mon Sep 24 22:13:50 2018 +0200 +++ b/www/js/rec_main.js Tue Sep 25 20:58:06 2018 +0200 @@ -74,7 +74,7 @@ return "Wijzig"; }, buttonclick: function (row) { var datarecord = dataAdapter.records[row]; - var url= "rec_edit.php?record=" + datarecord.record + "&return='rec_main.php'"; + var url= "rec_edit.php?record=" + datarecord.record + "&return=rec_main.php"; window.location.href = url; } } diff -r 883e897aad40 -r 2ff83855d574 www/rec_edit.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/www/rec_edit.php Tue Sep 25 20:58:06 2018 +0200 @@ -0,0 +1,207 @@ + + + +
+
    +
  • Algemeen
  • +
  • Vergistbaar
  • +
  • Hoppen
  • +
  • Diversen
  • +
  • Gist
  • +
  • Water
  • +
  • Maischen
  • +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Recept naam:
Opmerkingen:
Stijlgids:Bier stijl:Bier groep:
Brouw type:
Brouw volume:
Kooktijd minuten:
Brouwzaal rendement:
Start SG:
Eind SG:
Kleur EBC:
Methode:
Bitterheid IBU:
Methode:
+
+ + + +
+
+
+ +
+
+ + + + + +
Ingredienten:
Graat
+
+
+ +
+
+ + + + + +
Hoppen:
Graat
+
+
+ +
+
+ + + + + +
Diversen:
Graat
+
+
+ +
+
+ + + + + +
Gisten:
Graat
+
+
+ +
+
+ + + + + + + + + +
Water:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Water overzicht
VolumeCaMgNaCaCO3ClSO4pH
Gemengd water:
Behandeld water:
+
+
+
+
+ +
+
+ + + + + + + + + + + + + +
Maischchema:Maish pH:
Spoelwater temp:
Stappen:
Graat
+
+
+ +
+ +