Improved form validation handling (closes #1836)

This commit is contained in:
Bernd Bestel 2022-03-26 10:34:00 +01:00
parent 6aae97de73
commit 81b54182de
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
33 changed files with 180 additions and 17 deletions

View File

@ -61,6 +61,7 @@
### General ### 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 - Fixed an server error (on every page) when not having any quantity unit
### API ### API

View File

@ -382,7 +382,7 @@ window.FontAwesomeConfig = {
} }
Grocy.FrontendHelpers = {}; Grocy.FrontendHelpers = {};
Grocy.FrontendHelpers.ValidateForm = function(formId) Grocy.FrontendHelpers.ValidateForm = function(formId, reportValidity = false)
{ {
var form = document.getElementById(formId); var form = document.getElementById(formId);
if (form === null || form === undefined) if (form === null || form === undefined)
@ -390,17 +390,14 @@ Grocy.FrontendHelpers.ValidateForm = function(formId)
return; return;
} }
if (form.checkValidity() === true) $(form).addClass('was-validated');
if (reportValidity)
{ {
$(form).find(':submit').removeClass('disabled'); form.reportValidity();
$(form).find('.keep-disabled').addClass('disabled');
}
else
{
$(form).find(':submit').addClass('disabled');
} }
$(form).addClass('was-validated'); return form.checkValidity();
} }
Grocy.FrontendHelpers.BeginUiBusy = function(formId = null) Grocy.FrontendHelpers.BeginUiBusy = function(formId = null)

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("battery-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("batterytracking-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("chore-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("choretracking-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("consume-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;
@ -145,6 +150,11 @@ $('#save-mark-as-open-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("consume-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("equipment-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("inventory-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("location-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -497,6 +497,11 @@ $('#save-add-recipe-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("add-recipe-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;
@ -543,6 +548,11 @@ $('#save-add-note-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("add-note-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;
@ -591,6 +601,11 @@ $('#save-add-product-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("add-product-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;
@ -645,6 +660,11 @@ $('#save-copy-day-button').on('click', function(e)
{ {
e.preventDefault(); 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 if (document.getElementById("copy-day-form").checkValidity() === false) //There is at least one validation error
{ {
return false; return false;
@ -727,9 +747,9 @@ $('#add-product-form input').keydown(function(event)
$(document).on("keydown", "#servings", function(e) $(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 if (document.getElementById("add-recipe-form").checkValidity() === false) //There is at least one validation error
{ {

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("mealplansection-form", true))
{
return;
}
var jsonData = $('#mealplansection-form').serializeJSON(); var jsonData = $('#mealplansection-form').serializeJSON();
Grocy.FrontendHelpers.BeginUiBusy("mealplansection-form"); Grocy.FrontendHelpers.BeginUiBusy("mealplansection-form");

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("barcode-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -82,6 +82,11 @@ $('.save-product-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("product-form", true))
{
return;
}
var jsonData = $('#product-form').serializeJSON(); var jsonData = $('#product-form').serializeJSON();
var parentProductId = jsonData.product_id; var parentProductId = jsonData.product_id;
delete jsonData.product_id; delete jsonData.product_id;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("product-group-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -4,6 +4,11 @@ $('#save-purchase-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("purchase-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("quconversion-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("quantityunit-form", true))
{
return;
}
var jsonData = $('#quantityunit-form').serializeJSON(); var jsonData = $('#quantityunit-form').serializeJSON();
Grocy.FrontendHelpers.BeginUiBusy("quantityunit-form"); Grocy.FrontendHelpers.BeginUiBusy("quantityunit-form");

View File

@ -30,6 +30,11 @@ $('.save-recipe').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("recipe-form", true))
{
return;
}
var jsonData = $('#recipe-form').serializeJSON(); var jsonData = $('#recipe-form').serializeJSON();
Grocy.FrontendHelpers.BeginUiBusy("recipe-form"); Grocy.FrontendHelpers.BeginUiBusy("recipe-form");
@ -301,6 +306,11 @@ $('#save-recipe-include-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("recipe-include-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -4,6 +4,11 @@ $('#save-recipe-pos-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("recipe-pos-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("shopping-list-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -4,6 +4,11 @@ $('#save-shoppinglist-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("shoppinglist-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;
@ -284,7 +289,7 @@ eitherRequiredFields.on('input', function()
eitherRequiredFields.not(this).prop('required', !$(this).val().length); eitherRequiredFields.not(this).prop('required', !$(this).val().length);
Grocy.FrontendHelpers.ValidateForm('shoppinglist-form'); Grocy.FrontendHelpers.ValidateForm('shoppinglist-form');
}); });
eitherRequiredFields.trigger("input");
if (GetUriParam("product-name") != null) if (GetUriParam("product-name") != null)
{ {

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("shoppinglocation-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("stockentry-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("task-category-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("task-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("transfer-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("userentity-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("userfield-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -28,6 +28,11 @@ $('#save-user-button').on('click', function(e)
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("user-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -2,6 +2,11 @@
{ {
e.preventDefault(); e.preventDefault();
if (!Grocy.FrontendHelpers.ValidateForm("userobject-form", true))
{
return;
}
if ($(".combobox-menu-visible").length) if ($(".combobox-menu-visible").length)
{ {
return; return;

View File

@ -200,7 +200,6 @@
class="btn btn-secondary" class="btn btn-secondary"
data-dismiss="modal">{{ $__t('Cancel') }}</button> data-dismiss="modal">{{ $__t('Cancel') }}</button>
<button id="save-add-recipe-button" <button id="save-add-recipe-button"
data-dismiss="modal"
class="btn btn-success">{{ $__t('Save') }}</button> class="btn btn-success">{{ $__t('Save') }}</button>
</div> </div>
</div> </div>
@ -251,7 +250,6 @@
class="btn btn-secondary" class="btn btn-secondary"
data-dismiss="modal">{{ $__t('Cancel') }}</button> data-dismiss="modal">{{ $__t('Cancel') }}</button>
<button id="save-add-note-button" <button id="save-add-note-button"
data-dismiss="modal"
class="btn btn-success">{{ $__t('Save') }}</button> class="btn btn-success">{{ $__t('Save') }}</button>
</div> </div>
</div> </div>
@ -304,7 +302,6 @@
class="btn btn-secondary" class="btn btn-secondary"
data-dismiss="modal">{{ $__t('Cancel') }}</button> data-dismiss="modal">{{ $__t('Cancel') }}</button>
<button id="save-add-product-button" <button id="save-add-product-button"
data-dismiss="modal"
class="btn btn-success">{{ $__t('Save') }}</button> class="btn btn-success">{{ $__t('Save') }}</button>
</div> </div>
</div> </div>
@ -343,7 +340,6 @@
class="btn btn-secondary" class="btn btn-secondary"
data-dismiss="modal">{{ $__t('Cancel') }}</button> data-dismiss="modal">{{ $__t('Cancel') }}</button>
<button id="save-copy-day-button" <button id="save-copy-day-button"
data-dismiss="modal"
class="btn btn-primary">{{ $__t('Copy') }}</button> class="btn btn-primary">{{ $__t('Copy') }}</button>
</div> </div>
</div> </div>

View File

@ -405,7 +405,6 @@
class="btn btn-secondary" class="btn btn-secondary"
data-dismiss="modal">{{ $__t('Cancel') }}</button> data-dismiss="modal">{{ $__t('Cancel') }}</button>
<button id="save-recipe-include-button" <button id="save-recipe-include-button"
data-dismiss="modal"
class="btn btn-success">{{ $__t('Save') }}</button> class="btn btn-success">{{ $__t('Save') }}</button>
</div> </div>
</div> </div>