From 48e300bba6d059a95b16045872aa4bee2f8791af Mon Sep 17 00:00:00 2001 From: M-Byte Date: Sun, 4 Oct 2020 23:02:01 +0200 Subject: [PATCH] Recipe templates Fractions of the total ingredients required can be mentioned in recipes. This can be helpful when, for example, only half of some ingredient is needed at the start of the recipe. The proper values are automatically calculated when the number of servings is adjusted. --- public/viewjs/recipeform.js | 72 +++++++++++++++++++++++++++++++++++++ public/viewjs/recipes.js | 29 +++++++++++++++ views/recipeform.blade.php | 29 +++++++++------ views/recipes.blade.php | 1 + 4 files changed, 121 insertions(+), 10 deletions(-) diff --git a/public/viewjs/recipeform.js b/public/viewjs/recipeform.js index 09501c47..18e8c1ec 100644 --- a/public/viewjs/recipeform.js +++ b/public/viewjs/recipeform.js @@ -28,6 +28,9 @@ $('.save-recipe').on('click', function(e) { e.preventDefault(); + $(".note-editable span.ingredient").removeClass(["badge", "btn", "btn-secondary"]); + $("#description").text($("#description").siblings(".note-editor").find(".note-editable").html()); + var jsonData = $('#recipe-form').serializeJSON(); Grocy.FrontendHelpers.BeginUiBusy("recipe-form"); @@ -230,6 +233,62 @@ $(document).on('click', '.recipe-pos-edit-button', function(e) }); }); +$(document).on('click', '.recipe-pos-insert-button', function(e) +{ + e.preventDefault(); + + var recipePosId = $(e.currentTarget).attr('data-recipe-pos-id').toString(); + var recipePosName = $(e.currentTarget).attr('data-recipe-pos-name').toString(); + var recipePosAmount = parseFloat($(e.currentTarget).attr('data-recipe-pos-amount').toString()); + var recipePosQu = $(e.currentTarget).attr('data-recipe-pos-qu').toString(); + var recipePosQuPlural = $(e.currentTarget).attr('data-recipe-pos-qu-plural').toString(); + var range = $.summernote.range.create(); + + bootbox.dialog({ + message: '
Factor?
', + size: 'large', + backdrop: true, + closeButton: false, + buttons: { + cancel: { + label: __t('Cancel'), + className: 'btn-secondary responsive-button', + callback: function() + { + bootbox.hideAll(); + } + }, + ok: { + label: __t('Insert'), + className: 'btn-success responsive-button', + callback: function(e) + { + var factor = $(e.delegateTarget).find('input').val(); + var amount = parseFloat(factor) * recipePosAmount; + amount = amount.toFixed(2).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1'); + var html = ' ' + [amount, __n(amount, recipePosQu, recipePosQuPlural), recipePosName].join(' ') + ' '; + if (range.so !== range.eo || range.sc !== range.ec) + { + range.deleteContents(); + range = $.summernote.range.create(); + var check = range.getWordRange(true); + if (check.toString().trim().length === 0) + check.deleteContents(); + check = range.getWordRange(false); + if (check.toString().trim().length === 0) + check.deleteContents(); + range = $.summernote.range.create(); + } + range.pasteHTML(html); + updateIngredientTags(); + bootbox.hideAll(); + $("#description").summernote('focus'); + } + } + } + }); +}); + $(document).on('click', '.recipe-include-edit-button', function(e) { var id = $(e.currentTarget).attr('data-recipe-include-id'); @@ -379,6 +438,19 @@ $(window).on("message", function(e) } }); +function updateIngredientTags() +{ + $("#description").siblings(".note-editable").find("span.ingredient").not(".badge").addClass(["badge", "btn", "btn-secondary"]).on("click", function(evt) + { + $.summernote.range.createFromNode(evt.target).select(); + }); +} +$(".wysiwyg-editor").on("summernote.init", function() +{ + updateIngredientTags(); +}); +updateIngredientTags(); + // Grocy.Components.RecipePicker.GetPicker().on('change', function (e) // { // var value = Grocy.Components.RecipePicker.GetValue(); diff --git a/public/viewjs/recipes.js b/public/viewjs/recipes.js index d176c435..4c0d0ecb 100644 --- a/public/viewjs/recipes.js +++ b/public/viewjs/recipes.js @@ -37,6 +37,35 @@ if (typeof recipe !== "undefined") // Scroll to recipe card on mobile $("#selectedRecipeCard")[0].scrollIntoView(); } + + $("#selectedRecipeCard .ingredient").each(function(id, element) + { + var data = $(element).closest(".tab-pane").data("ingredients"); + if (!data) + { + $(element).text(''); + return; + } + var ingredient = FindObjectInArrayByPropertyValue(data.recipePositions, 'recipe_pos_id', element.dataset.ingredientId); + if (!ingredient) + { + $(element).text(''); + } + var product = FindObjectInArrayByPropertyValue(data.products, 'id', ingredient.product_id); + var amount = ingredient.recipe_amount; + if (element.dataset.ingredientFactor && parseFloat(element.dataset.ingredientFactor)) + { + amount *= parseFloat(element.dataset.ingredientFactor); + } + amount = amount.toFixed(2).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1'); + var qu = FindObjectInArrayByPropertyValue(data.quantityUnits, 'id', ingredient.qu_id); + if (!qu || !product) + { + $(element).text(''); + return; + } + $(element).text([amount, __n(amount, qu.name, qu.name_plural), product.name].join(' ')); + }); } if (GetUriParam("search") !== undefined) diff --git a/views/recipeform.blade.php b/views/recipeform.blade.php index d7da2254..52424bdd 100644 --- a/views/recipeform.blade.php +++ b/views/recipeform.blade.php @@ -192,6 +192,16 @@ @if($mode == "edit") @foreach($recipePositions as $recipePosition) + @php + $product = FindObjectInArrayByPropertyValue($products, 'id', $recipePosition->product_id); + $productQuConversions = FindAllObjectsInArrayByPropertyValue($quantityUnitConversionsResolved, 'product_id', $product->id); + $productQuConversions = FindAllObjectsInArrayByPropertyValue($productQuConversions, 'from_qu_id', $product->qu_id_stock); + $productQuConversion = FindObjectInArrayByPropertyValue($productQuConversions, 'to_qu_id', $recipePosition->qu_id); + if ($productQuConversion) + { + $recipePosition->amount = $recipePosition->amount * $productQuConversion->factor; + } + @endphp + + + product_id)->name }} - @php - $product = FindObjectInArrayByPropertyValue($products, 'id', $recipePosition->product_id); - $productQuConversions = FindAllObjectsInArrayByPropertyValue($quantityUnitConversionsResolved, 'product_id', $product->id); - $productQuConversions = FindAllObjectsInArrayByPropertyValue($productQuConversions, 'from_qu_id', $product->qu_id_stock); - $productQuConversion = FindObjectInArrayByPropertyValue($productQuConversions, 'to_qu_id', $recipePosition->qu_id); - if ($productQuConversion) - { - $recipePosition->amount = $recipePosition->amount * $productQuConversion->factor; - } - @endphp @if(!empty($recipePosition->variable_amount)) {{ $recipePosition->variable_amount }} @else diff --git a/views/recipes.blade.php b/views/recipes.blade.php index 756aacd4..e4b61fe0 100644 --- a/views/recipes.blade.php +++ b/views/recipes.blade.php @@ -394,6 +394,7 @@ @endif

{{ $__t('Preparation') }}