From edf307dffa6aa5ec37ea8fa50f4067dc58f94555 Mon Sep 17 00:00:00 2001 From: Mike Masey Date: Fri, 31 Jul 2020 11:41:51 +0100 Subject: [PATCH] Errors do not receive focus on submit (Accessibility) (#8278) --- .../src/common/services/formhelper.service.js | 30 +++++++++++++++++++ .../dropdownFlexible.controller.js | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js index 90fbd76ec9..5f59a72159 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js @@ -33,6 +33,7 @@ function formHelper(angularHelper, serverValidationManager, notificationsService if (!args.scope) { throw "args.scope cannot be null"; } + if (!args.formCtrl) { //try to get the closest form controller currentForm = angularHelper.getRequiredCurrentForm(args.scope); @@ -44,9 +45,12 @@ function formHelper(angularHelper, serverValidationManager, notificationsService //the first thing any form must do is broadcast the formSubmitting event args.scope.$broadcast("formSubmitting", { scope: args.scope, action: args.action }); + this.focusOnFirstError(currentForm); + //then check if the form is valid if (!args.skipValidation) { if (currentForm.$invalid) { + return false; } } @@ -57,6 +61,32 @@ function formHelper(angularHelper, serverValidationManager, notificationsService return true; }, + /** + * @ngdoc function + * @name umbraco.services.formHelper#focusOnFirstError + * @methodOf umbraco.services.formHelper + * @function + * + * @description + * Called by submitForm when a form has been submitted, it will fire a focus on the first found invalid umb-property it finds in the form.. + * + * @param {object} form Pass in a form object. + */ + focusOnFirstError: function(form) { + var invalidNgForms = form.$$element.find(`.umb-property ng-form.ng-invalid, .umb-property-editor ng-form.ng-invalid-required`); + var firstInvalidNgForm = invalidNgForms.first(); + + if(firstInvalidNgForm.length !== 0) { + var focusableFields = [...firstInvalidNgForm.find("umb-range-slider .noUi-handle,input,textarea,select,button")]; + if(focusableFields.length !== 0) { + var firstErrorEl = focusableFields.find(el => el.type !== "hidden" && el.hasAttribute("readonly") === false); + if(firstErrorEl.length !== 0) { + firstErrorEl.focus(); + } + } + } + }, + /** * @ngdoc function * @name umbraco.services.formHelper#submitForm diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index afbb4feb20..69de132715 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -18,7 +18,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo //ensure when form is saved that we don't store [] or [null] as string values in the database when no items are selected $scope.$on("formSubmitting", function () { - if ($scope.model.value.length === 0 || $scope.model.value[0] === null) { + if ($scope.model.value !== null && ($scope.model.value.length === 0 || $scope.model.value[0] === null)) { $scope.model.value = null; } });