Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion js/formidable.js
Original file line number Diff line number Diff line change
Expand Up @@ -1507,9 +1507,11 @@ function frmFrontFormJS() {
summary.focus();
return;
}
// No summary in the DOM (js_validate's client-side path never renders one): fall
// through to the first-errored-field focus below.
}

if ( ! config.focusFirstError ) {
if ( ! config.focusFirstError && ! config.focusErrorSummary ) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking, same root cause [Likely, source-traced, not run in a browser]: is_error_summary_active_for_form() is true regardless of js_validate, and should_include_alert_role_on_field_errors() defaults to false whenever the summary is active (FrmAppHelper.php ~4198). On the js_validate path addFieldError() (~1236) therefore builds <div class="frm_error" id=...> with no role="alert", and the summary that was supposed to announce the errors instead is never rendered. Net effect for a screen reader on a js_validate form: the first field gets focus and reads its aria-describedby error, but the other errors are never announced. This PR fixes the focus half of the summary/js_validate mismatch and leaves the announcement half. Worth a follow-up issue (either render the summary on the client path, or have getErrorConfigForForm()'s consumer keep role="alert" when the summary can't render); not required for this fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, out of scope here. Leaving the role=alert/announcement half for a separate follow-up issue.

return;
}

Expand Down
2 changes: 1 addition & 1 deletion js/formidable.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tests/cypress/e2e/Forms/fieldsInFormBuilder-validation.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ describe( 'Fields in the form builder', () => {
cy.get( `[id^="frm_error_field_"]` ).eq( 0 ).should( 'contain', `Text cannot be blank.` );
cy.get( `[id^="frm_error_field_"]` ).eq( 1 ).should( 'not.exist' );
cy.get( `[id^="frm_error_field_"]` ).eq( 2 ).should( 'not.exist' );
// js_validate's client-side path never renders the error summary markup, so focus
// must fall back to the first errored field.
cy.get( '[id^="field_"]' ).filter( 'input, textarea' ).eq( 0 ).should( 'have.focus' );
cy.get( '[id^="field_"]' ).filter( 'input, textarea' ).eq( 1 ).clear();
cy.get( '[id^="field_"]' ).filter( 'input, textarea' ).eq( 2 ).clear();
cy.get( "button[type='submit']" ).should( 'contain', 'Submit' ).click();
Expand Down
Loading