From cc90212382e73da80d24a56ac54fd4fa0b35de51 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 23 Sep 2025 17:27:24 -0300 Subject: [PATCH 1/4] Stop adding aria-invalid directly to radio button and checkbox inputs --- classes/models/FrmFieldFormHtml.php | 5 +++++ classes/models/fields/FrmFieldCheckbox.php | 4 ++++ classes/models/fields/FrmFieldRadio.php | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/classes/models/FrmFieldFormHtml.php b/classes/models/FrmFieldFormHtml.php index 98634b3431..e9dc690408 100644 --- a/classes/models/FrmFieldFormHtml.php +++ b/classes/models/FrmFieldFormHtml.php @@ -526,6 +526,11 @@ private function add_multiple_input_attributes() { $attributes['aria-required'] = 'true'; } + // Add 'aria-invalid' attribute to the group if there are errors. + if ( isset( $this->pass_args['errors'][ 'field' . $this->field_id ] ) ) { + $attributes['aria-invalid'] = 'true'; + } + // Concatenate attributes into a string, and replace the role="group" in the HTML with the attributes string. $html_attributes = FrmAppHelper::array_to_html_params( $attributes ); $this->html = str_replace( ' role="group"', $html_attributes, $this->html ); diff --git a/classes/models/fields/FrmFieldCheckbox.php b/classes/models/fields/FrmFieldCheckbox.php index 41bc9dc51f..311195da5a 100644 --- a/classes/models/fields/FrmFieldCheckbox.php +++ b/classes/models/fields/FrmFieldCheckbox.php @@ -108,4 +108,8 @@ protected function show_readonly_hidden() { protected function prepare_import_value( $value, $atts ) { return $this->get_multi_opts_for_import( $value ); } + + public function set_aria_invalid_error( &$shortcode_atts, $args ) { + unset( $shortcode_atts['aria-invalid'] ); + } } diff --git a/classes/models/fields/FrmFieldRadio.php b/classes/models/fields/FrmFieldRadio.php index b21d30f5d9..24229e8b0e 100644 --- a/classes/models/fields/FrmFieldRadio.php +++ b/classes/models/fields/FrmFieldRadio.php @@ -109,4 +109,8 @@ protected function include_front_form_file() { protected function show_readonly_hidden() { return true; } + + public function set_aria_invalid_error( &$shortcode_atts, $args ) { + unset( $shortcode_atts['aria-invalid'] ); + } } From fe9955b63498abf8a0457125cdc49c458d504e52 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 23 Sep 2025 17:29:19 -0300 Subject: [PATCH 2/4] Add comments --- classes/models/fields/FrmFieldCheckbox.php | 9 +++++++++ classes/models/fields/FrmFieldRadio.php | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/classes/models/fields/FrmFieldCheckbox.php b/classes/models/fields/FrmFieldCheckbox.php index 311195da5a..7b1f2819ec 100644 --- a/classes/models/fields/FrmFieldCheckbox.php +++ b/classes/models/fields/FrmFieldCheckbox.php @@ -109,6 +109,15 @@ protected function prepare_import_value( $value, $atts ) { return $this->get_multi_opts_for_import( $value ); } + /** + * Unset aria-invalid for checkboxes because it's not valid for checkboxes. + * Instead aria-invalid is added to the checkbox group parent element. + * + * @since x.x + * + * @param array $shortcode_atts + * @param array $args + */ public function set_aria_invalid_error( &$shortcode_atts, $args ) { unset( $shortcode_atts['aria-invalid'] ); } diff --git a/classes/models/fields/FrmFieldRadio.php b/classes/models/fields/FrmFieldRadio.php index 24229e8b0e..d8d62e57f6 100644 --- a/classes/models/fields/FrmFieldRadio.php +++ b/classes/models/fields/FrmFieldRadio.php @@ -110,6 +110,15 @@ protected function show_readonly_hidden() { return true; } + /** + * Unset aria-invalid for radio buttons because it's not valid for radio buttons. + * Instead aria-invalid is added to the radiogroup parent element. + * + * @since x.x + * + * @param array $shortcode_atts + * @param array $args + */ public function set_aria_invalid_error( &$shortcode_atts, $args ) { unset( $shortcode_atts['aria-invalid'] ); } From fe333e2d0c5b47c7fb83535503b6557225ac6a62 Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 23 Sep 2025 17:38:00 -0300 Subject: [PATCH 3/4] Also set it when validating JS --- js/formidable.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/js/formidable.js b/js/formidable.js index 451232fdf9..244e4f5e42 100644 --- a/js/formidable.js +++ b/js/formidable.js @@ -1147,7 +1147,12 @@ function frmFrontFormJS() { input.attr( 'aria-describedby', describedBy ); } - input.attr( 'aria-invalid', true ); + + if ( [ 'radio', 'checkbox' ].includes( input.attr( 'type' ) ) ) { + input.closest( '[role="radiogroup"], [role="group"]' ).attr( 'aria-invalid', true ); + } else { + input.attr( 'aria-invalid', true ); + } jQuery( document ).trigger( 'frmAddFieldError', [ $fieldCont, key, jsErrors ] ); } @@ -1186,8 +1191,13 @@ function frmFrontFormJS() { fieldContainer.classList.remove( 'frm_blank_field', 'has-error' ); } + if ( 'true' === input.attr( 'aria-invalid' ) ) { + input.attr( 'aria-invalid', false ); + } else { + input.closest( '[role="radiogroup"], [role="group"]' ).attr( 'aria-invalid', false ); + } + errorMessage.remove(); - input.attr( 'aria-invalid', false ); input.removeAttr( 'aria-describedby' ); if ( typeof describedBy !== 'undefined' ) { From 1603355243ac26a4cc21375a437e848f76c0f97f Mon Sep 17 00:00:00 2001 From: Mike Letellier Date: Tue, 23 Sep 2025 17:39:07 -0300 Subject: [PATCH 4/4] Add a type check --- js/formidable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/formidable.js b/js/formidable.js index 244e4f5e42..df085fc7eb 100644 --- a/js/formidable.js +++ b/js/formidable.js @@ -1193,7 +1193,7 @@ function frmFrontFormJS() { if ( 'true' === input.attr( 'aria-invalid' ) ) { input.attr( 'aria-invalid', false ); - } else { + } else if ( [ 'radio', 'checkbox' ].includes( input.attr( 'type' ) ) ) { input.closest( '[role="radiogroup"], [role="group"]' ).attr( 'aria-invalid', false ); }