diff --git a/changelog/67_UNRELEASED_xxxx-xx-xx.md b/changelog/67_UNRELEASED_xxxx-xx-xx.md index 987ed3e5..fe9454d4 100644 --- a/changelog/67_UNRELEASED_xxxx-xx-xx.md +++ b/changelog/67_UNRELEASED_xxxx-xx-xx.md @@ -61,6 +61,7 @@ ### General +- Optimized form validation: Save / submit buttons are now not disabled when the form is invalid, the invalid / missing fields are instead highlighted when trying to submit / save the form (making it more obvous which fields are invalid / missing exactly) - Fixed an server error (on every page) when not having any quantity unit ### API diff --git a/public/js/grocy.js b/public/js/grocy.js index 34122eb2..61121dc3 100644 --- a/public/js/grocy.js +++ b/public/js/grocy.js @@ -382,7 +382,7 @@ window.FontAwesomeConfig = { } Grocy.FrontendHelpers = {}; -Grocy.FrontendHelpers.ValidateForm = function(formId) +Grocy.FrontendHelpers.ValidateForm = function(formId, reportValidity = false) { var form = document.getElementById(formId); if (form === null || form === undefined) @@ -390,17 +390,14 @@ Grocy.FrontendHelpers.ValidateForm = function(formId) return; } - if (form.checkValidity() === true) + $(form).addClass('was-validated'); + + if (reportValidity) { - $(form).find(':submit').removeClass('disabled'); - $(form).find('.keep-disabled').addClass('disabled'); - } - else - { - $(form).find(':submit').addClass('disabled'); + form.reportValidity(); } - $(form).addClass('was-validated'); + return form.checkValidity(); } Grocy.FrontendHelpers.BeginUiBusy = function(formId = null) diff --git a/public/viewjs/batteryform.js b/public/viewjs/batteryform.js index 973ed23c..e3f7fdf5 100644 --- a/public/viewjs/batteryform.js +++ b/public/viewjs/batteryform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("battery-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/batterytracking.js b/public/viewjs/batterytracking.js index b7b64844..526349ff 100644 --- a/public/viewjs/batterytracking.js +++ b/public/viewjs/batterytracking.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("batterytracking-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/choreform.js b/public/viewjs/choreform.js index ec8fe1da..fce5e152 100644 --- a/public/viewjs/choreform.js +++ b/public/viewjs/choreform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("chore-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/choretracking.js b/public/viewjs/choretracking.js index 15c5dd03..e80c638c 100644 --- a/public/viewjs/choretracking.js +++ b/public/viewjs/choretracking.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("choretracking-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/consume.js b/public/viewjs/consume.js index a4d9d867..6f14174e 100644 --- a/public/viewjs/consume.js +++ b/public/viewjs/consume.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("consume-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; @@ -145,6 +150,11 @@ $('#save-mark-as-open-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("consume-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/equipmentform.js b/public/viewjs/equipmentform.js index b42c3e79..46822a24 100644 --- a/public/viewjs/equipmentform.js +++ b/public/viewjs/equipmentform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("equipment-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/inventory.js b/public/viewjs/inventory.js index 0500ab31..7fe93ba5 100644 --- a/public/viewjs/inventory.js +++ b/public/viewjs/inventory.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("inventory-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/locationform.js b/public/viewjs/locationform.js index a864d947..98fc54af 100644 --- a/public/viewjs/locationform.js +++ b/public/viewjs/locationform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("location-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/mealplan.js b/public/viewjs/mealplan.js index 16a3ef36..fd8bea51 100644 --- a/public/viewjs/mealplan.js +++ b/public/viewjs/mealplan.js @@ -497,6 +497,11 @@ $('#save-add-recipe-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("add-recipe-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; @@ -543,6 +548,11 @@ $('#save-add-note-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("add-note-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; @@ -591,6 +601,11 @@ $('#save-add-product-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("add-product-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; @@ -645,6 +660,11 @@ $('#save-copy-day-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("copy-day-form", true)) + { + return; + } + if (document.getElementById("copy-day-form").checkValidity() === false) //There is at least one validation error { return false; @@ -727,9 +747,9 @@ $('#add-product-form input').keydown(function(event) $(document).on("keydown", "#servings", function(e) { - if (event.keyCode === 13) //Enter + if (e.keyCode === 13) //Enter { - event.preventDefault(); + e.preventDefault(); if (document.getElementById("add-recipe-form").checkValidity() === false) //There is at least one validation error { diff --git a/public/viewjs/mealplansectionform.js b/public/viewjs/mealplansectionform.js index b926be4b..ec14e8af 100644 --- a/public/viewjs/mealplansectionform.js +++ b/public/viewjs/mealplansectionform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("mealplansection-form", true)) + { + return; + } + var jsonData = $('#mealplansection-form').serializeJSON(); Grocy.FrontendHelpers.BeginUiBusy("mealplansection-form"); diff --git a/public/viewjs/productbarcodeform.js b/public/viewjs/productbarcodeform.js index 7eca45f6..e1b3f6f4 100644 --- a/public/viewjs/productbarcodeform.js +++ b/public/viewjs/productbarcodeform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("barcode-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/productform.js b/public/viewjs/productform.js index cf77917e..6f2b4967 100644 --- a/public/viewjs/productform.js +++ b/public/viewjs/productform.js @@ -82,6 +82,11 @@ $('.save-product-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("product-form", true)) + { + return; + } + var jsonData = $('#product-form').serializeJSON(); var parentProductId = jsonData.product_id; delete jsonData.product_id; diff --git a/public/viewjs/productgroupform.js b/public/viewjs/productgroupform.js index 87523eb9..e6d54352 100644 --- a/public/viewjs/productgroupform.js +++ b/public/viewjs/productgroupform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("product-group-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/purchase.js b/public/viewjs/purchase.js index 762c402b..63bf057a 100644 --- a/public/viewjs/purchase.js +++ b/public/viewjs/purchase.js @@ -4,6 +4,11 @@ $('#save-purchase-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("purchase-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/quantityunitconversionform.js b/public/viewjs/quantityunitconversionform.js index 7f206d4b..85f1f847 100644 --- a/public/viewjs/quantityunitconversionform.js +++ b/public/viewjs/quantityunitconversionform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("quconversion-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/quantityunitform.js b/public/viewjs/quantityunitform.js index f61a4ebf..14db0978 100644 --- a/public/viewjs/quantityunitform.js +++ b/public/viewjs/quantityunitform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("quantityunit-form", true)) + { + return; + } + var jsonData = $('#quantityunit-form').serializeJSON(); Grocy.FrontendHelpers.BeginUiBusy("quantityunit-form"); diff --git a/public/viewjs/recipeform.js b/public/viewjs/recipeform.js index 775410b9..33f057ec 100644 --- a/public/viewjs/recipeform.js +++ b/public/viewjs/recipeform.js @@ -30,6 +30,11 @@ $('.save-recipe').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("recipe-form", true)) + { + return; + } + var jsonData = $('#recipe-form').serializeJSON(); Grocy.FrontendHelpers.BeginUiBusy("recipe-form"); @@ -301,6 +306,11 @@ $('#save-recipe-include-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("recipe-include-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/recipeposform.js b/public/viewjs/recipeposform.js index 70f66dd0..acec2007 100644 --- a/public/viewjs/recipeposform.js +++ b/public/viewjs/recipeposform.js @@ -4,6 +4,11 @@ $('#save-recipe-pos-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("recipe-pos-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/shoppinglistform.js b/public/viewjs/shoppinglistform.js index 8792db90..8d7c5915 100644 --- a/public/viewjs/shoppinglistform.js +++ b/public/viewjs/shoppinglistform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("shopping-list-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/shoppinglistitemform.js b/public/viewjs/shoppinglistitemform.js index 3e5fcf64..fa444703 100644 --- a/public/viewjs/shoppinglistitemform.js +++ b/public/viewjs/shoppinglistitemform.js @@ -4,6 +4,11 @@ $('#save-shoppinglist-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("shoppinglist-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; @@ -284,7 +289,7 @@ eitherRequiredFields.on('input', function() eitherRequiredFields.not(this).prop('required', !$(this).val().length); Grocy.FrontendHelpers.ValidateForm('shoppinglist-form'); }); - +eitherRequiredFields.trigger("input"); if (GetUriParam("product-name") != null) { diff --git a/public/viewjs/shoppinglocationform.js b/public/viewjs/shoppinglocationform.js index 09e81cf2..16e90208 100644 --- a/public/viewjs/shoppinglocationform.js +++ b/public/viewjs/shoppinglocationform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("shoppinglocation-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/stockentryform.js b/public/viewjs/stockentryform.js index 62710970..51484574 100644 --- a/public/viewjs/stockentryform.js +++ b/public/viewjs/stockentryform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("stockentry-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/taskcategoryform.js b/public/viewjs/taskcategoryform.js index ae02241f..4ec20607 100644 --- a/public/viewjs/taskcategoryform.js +++ b/public/viewjs/taskcategoryform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("task-category-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/taskform.js b/public/viewjs/taskform.js index 298a586b..397fb1b3 100644 --- a/public/viewjs/taskform.js +++ b/public/viewjs/taskform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("task-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/transfer.js b/public/viewjs/transfer.js index 4ad149ee..a88838ac 100644 --- a/public/viewjs/transfer.js +++ b/public/viewjs/transfer.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("transfer-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/userentityform.js b/public/viewjs/userentityform.js index eac5ff67..a02cea61 100644 --- a/public/viewjs/userentityform.js +++ b/public/viewjs/userentityform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("userentity-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/userfieldform.js b/public/viewjs/userfieldform.js index 14d79a02..a7b89d38 100644 --- a/public/viewjs/userfieldform.js +++ b/public/viewjs/userfieldform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("userfield-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/userform.js b/public/viewjs/userform.js index ce348650..87c227a5 100644 --- a/public/viewjs/userform.js +++ b/public/viewjs/userform.js @@ -28,6 +28,11 @@ $('#save-user-button').on('click', function(e) { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("user-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/public/viewjs/userobjectform.js b/public/viewjs/userobjectform.js index 4cb33321..ca42ddce 100644 --- a/public/viewjs/userobjectform.js +++ b/public/viewjs/userobjectform.js @@ -2,6 +2,11 @@ { e.preventDefault(); + if (!Grocy.FrontendHelpers.ValidateForm("userobject-form", true)) + { + return; + } + if ($(".combobox-menu-visible").length) { return; diff --git a/views/mealplan.blade.php b/views/mealplan.blade.php index 8853f146..e0b49ef8 100644 --- a/views/mealplan.blade.php +++ b/views/mealplan.blade.php @@ -200,7 +200,6 @@ class="btn btn-secondary" data-dismiss="modal">{{ $__t('Cancel') }} @@ -251,7 +250,6 @@ class="btn btn-secondary" data-dismiss="modal">{{ $__t('Cancel') }} @@ -304,7 +302,6 @@ class="btn btn-secondary" data-dismiss="modal">{{ $__t('Cancel') }} @@ -343,7 +340,6 @@ class="btn btn-secondary" data-dismiss="modal">{{ $__t('Cancel') }} diff --git a/views/recipeform.blade.php b/views/recipeform.blade.php index e20968e4..1a5e465f 100644 --- a/views/recipeform.blade.php +++ b/views/recipeform.blade.php @@ -405,7 +405,6 @@ class="btn btn-secondary" data-dismiss="modal">{{ $__t('Cancel') }}