MDL-81066 core_form: Validate form fields on submit only

This commit is contained in:
sam marshall 2024-02-27 12:04:34 +00:00
parent 757be30c39
commit 79038ab3a3
5 changed files with 42 additions and 11 deletions

View File

@ -2742,9 +2742,6 @@ require([
}
}
document.getElementById(\'' . $elem->_attributes['id'] . '\').addEventListener(\'blur\', function(ev) {
' . $valFunc . '
});
document.getElementById(\'' . $elem->_attributes['id'] . '\').addEventListener(\'change\', function(ev) {
' . $valFunc . '
});

View File

@ -6,6 +6,6 @@
* @copyright 2016 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define("theme_boost/form-display-errors",["jquery","core_form/events"],(function($,FormEvent){return{enhance:function(elementid){var element=document.getElementById(elementid);if(element){element.addEventListener(FormEvent.eventTypes.formFieldValidationFailed,(e=>{const msg=e.detail.message;e.preventDefault();var parent=$(element).closest(".fitem"),feedback=parent.find(".form-control-feedback");const feedbackId=feedback.attr("id");let describedBy=$(element).attr("aria-describedby");void 0===describedBy&&(describedBy="");let describedByIds=[];describedBy.length&&(describedByIds=describedBy.split(" "));const feedbackIndex=describedByIds.indexOf(feedbackId);"TEXTAREA"==$(element).prop("tagName")&&parent.find("[contenteditable]").length>0&&(element=parent.find("[contenteditable]")),""!==msg?(parent.addClass("has-danger"),parent.data("client-validation-error",!0),$(element).addClass("is-invalid"),-1===feedbackIndex&&(describedByIds.push(feedbackId),$(element).attr("aria-describedby",describedByIds.join(" "))),$(element).attr("aria-invalid",!0),feedback.attr("tabindex",0),feedback.html(msg),feedback.is(":visible")||(feedback.show(),feedback.focus())):!0===parent.data("client-validation-error")&&(parent.removeClass("has-danger"),parent.data("client-validation-error",!1),$(element).removeClass("is-invalid"),feedbackIndex>-1&&describedByIds.splice(feedbackIndex,1),describedByIds.length?(describedBy=describedByIds.join(" "),$(element).attr("aria-describedby",describedBy)):$(element).removeAttr("aria-describedby"),$(element).attr("aria-invalid",!1),feedback.hide())}));var form=element.closest("form");form&&!("boostFormErrorsEnhanced"in form.dataset)&&(form.addEventListener("submit",(function(){var visibleError=$(".form-control-feedback:visible");visibleError.length&&visibleError[0].focus()})),form.dataset.boostFormErrorsEnhanced=1)}}}}));
define("theme_boost/form-display-errors",["jquery","core_form/events"],(function($,FormEvent){let focusedAlready=!1;return{enhance:function(elementid){var element=document.getElementById(elementid);if(element){element.addEventListener(FormEvent.eventTypes.formFieldValidationFailed,(e=>{const msg=e.detail.message;e.preventDefault();var parent=$(element).closest(".fitem"),feedback=parent.find(".form-control-feedback");const feedbackId=feedback.attr("id");let describedBy=$(element).attr("aria-describedby");void 0===describedBy&&(describedBy="");let describedByIds=[];describedBy.length&&(describedByIds=describedBy.split(" "));const feedbackIndex=describedByIds.indexOf(feedbackId);"TEXTAREA"==$(element).prop("tagName")&&parent.find("[contenteditable]").length>0&&(element=parent.find("[contenteditable]")),""!==msg?(parent.addClass("has-danger"),parent.data("client-validation-error",!0),$(element).addClass("is-invalid"),-1===feedbackIndex&&(describedByIds.push(feedbackId),$(element).attr("aria-describedby",describedByIds.join(" "))),$(element).attr("aria-invalid",!0),feedback.html(msg),feedback.show(),focusedAlready||(element.scrollIntoView({behavior:"smooth",block:"center"}),focusedAlready=!0,setTimeout((()=>{element.focus({preventScroll:!0}),focusedAlready=!1}),0))):!0===parent.data("client-validation-error")&&(parent.removeClass("has-danger"),parent.data("client-validation-error",!1),$(element).removeClass("is-invalid"),feedbackIndex>-1&&describedByIds.splice(feedbackIndex,1),describedByIds.length?(describedBy=describedByIds.join(" "),$(element).attr("aria-describedby",describedBy)):$(element).removeAttr("aria-describedby"),$(element).attr("aria-invalid",!1),feedback.hide())}));var form=element.closest("form");form&&!("boostFormErrorsEnhanced"in form.dataset)&&(form.addEventListener("submit",(function(){var visibleError=$(".form-control-feedback:visible");visibleError.length&&visibleError[0].focus()})),form.dataset.boostFormErrorsEnhanced=1)}}}}));
//# sourceMappingURL=form-display-errors.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -22,6 +22,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core_form/events'], function($, FormEvent) {
let focusedAlready = false;
return {
/**
* Enhance the supplied element to handle form field errors.
@ -73,14 +74,20 @@ define(['jquery', 'core_form/events'], function($, FormEvent) {
$(element).attr('aria-describedby', describedByIds.join(" "));
}
$(element).attr('aria-invalid', true);
feedback.attr('tabindex', 0);
feedback.html(msg);
feedback.show();
// Only display and focus when the error was not already visible.
// This is so that, when tabbing around the form, you don't get stuck.
if (!feedback.is(':visible')) {
feedback.show();
feedback.focus();
// If we haven't focused anything yet, focus this one.
if (!focusedAlready) {
element.scrollIntoView({behavior: "smooth", block: "center"});
focusedAlready = true;
setTimeout(()=> {
// Actual focus happens later in case we need to do this in response to
// a change event which happens in the middle of changing focus.
element.focus({preventScroll: true});
// Let it focus again next time they submit the form.
focusedAlready = false;
}, 0);
}
} else {

View File

@ -0,0 +1,27 @@
@javascript @theme_boost
Feature: Form errors only display after submit or change in Boost theme
In order to have a more accessible way to display form errors
As anyone
I need to see errors only after I submit the form or change a field
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
Scenario: Form error appears after submit, but not after just tabbing through
When I log in as "admin"
And I navigate to "Courses > Add a new course" in site administration
And I click on "Course full name" "field"
And I press the tab key
Then I should not see "Missing full name"
And I press "Save and display"
And I should see "Missing full name"
And the focused element is "Course full name" "field"
Scenario: Form error appears immediately after change
When I am on the "C1" "course editing" page logged in as "admin"
And I set the field "Course full name" to ""
And I press the tab key
Then I should see "Missing full name"
And the focused element is "Course full name" "field"