]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
fix(abide): add aria-describedby to the input only if error is visible 12398/head
authorAntti Hukkanen <antti.hukkanen@mainiotech.fi>
Fri, 4 Mar 2022 14:58:49 +0000 (16:58 +0200)
committerAntti Hukkanen <antti.hukkanen@mainiotech.fi>
Mon, 7 Mar 2022 14:56:44 +0000 (16:56 +0200)
js/foundation.abide.js
test/javascript/components/abide.js

index 4e740c9186390518feaef6da2c3b30d3b9760b34..cd1aca3490707333a2bd1bdfe60d1c68ed959f53 100644 (file)
@@ -282,6 +282,10 @@ class Abide extends Plugin {
       'data-invalid': '',
       'aria-invalid': true
     });
+
+    if ($formError.filter(':visible').length) {
+      this.addA11yErrorDescribe($el, $formError);
+    }
   }
 
   /**
@@ -292,19 +296,11 @@ class Abide extends Plugin {
   addA11yAttributes($el) {
     let $errors = this.findFormError($el);
     let $labels = $errors.filter('label');
-    let $error = $errors.first();
     if (!$errors.length) return;
 
-    // Set [aria-describedby] on the input toward the first form error if it is not set
-    if (typeof $el.attr('aria-describedby') === 'undefined') {
-      // Get the first error ID or create one
-      let errorId = $error.attr('id');
-      if (typeof errorId === 'undefined') {
-        errorId = GetYoDigits(6, 'abide-error');
-        $error.attr('id', errorId);
-      }
-
-      $el.attr('aria-describedby', errorId);
+    let $error = $errors.filter(':visible').first();
+    if ($error.length) {
+      this.addA11yErrorDescribe($el, $error);
     }
 
     if ($labels.filter('[for]').length < $labels.length) {
@@ -331,6 +327,20 @@ class Abide extends Plugin {
     }).end();
   }
 
+  addA11yErrorDescribe($el, $error) {
+    if (typeof $el.attr('aria-describedby') !== 'undefined') return;
+
+    // Set [aria-describedby] on the input toward the first form error if it is not set
+    // Get the first error ID or create one
+    let errorId = $error.attr('id');
+    if (typeof errorId === 'undefined') {
+      errorId = GetYoDigits(6, 'abide-error');
+      $error.attr('id', errorId);
+    }
+
+    $el.attr('aria-describedby', errorId).data('abide-describedby', true);
+  }
+
   /**
    * Adds [aria-live] attribute to the given global form error $el.
    * @param {Object} $el - jQuery object to add the attribute to
@@ -419,6 +429,10 @@ class Abide extends Plugin {
       'data-invalid': null,
       'aria-invalid': null
     });
+
+    if ($el.data('abide-describedby')) {
+      $el.removeAttr('aria-describedby').removeData('abide-describedby');
+    }
   }
 
   /**
index 0b61460fec4c40c766d6f7db277c0fab294cde5d..19ea148db168440c0f8d189fa3cb0b21507154d5 100644 (file)
@@ -133,7 +133,7 @@ describe('Abide', function() {
       $html = $(`
         <form data-abide>
           <input type="text" id="test-input">
-          <label class="form-error" id="test-error">Form error</label>
+          <label class="form-error is-visible" id="test-error">Form error</label>
         </form>
       `).appendTo('body');
       plugin = new Foundation.Abide($html, {});
@@ -143,11 +143,47 @@ describe('Abide', function() {
       $html.find('label.form-error').should.have.attr('for', 'test-input');
     });
 
+    it('does not add [aria-describedby] to the field if the form error is hidden', function() {
+      $html = $(`
+        <form data-abide>
+          <label for="test-input">Text field</div>
+          <input type="text" id="test-input">
+          <span class="form-error" id="test-error">Form error</span>
+        </form>
+      `).appendTo('body');
+      plugin = new Foundation.Abide($html, {});
+      plugin.addA11yAttributes($html.find('input'));
+
+      $html.find('input').should.not.have.attr('aria-describedby', 'test-error');
+    });
+
+    it('adds [aria-describedby] to the field if the form error is shown after a validation error', function() {
+      $html = $(`
+        <form data-abide>
+          <label for="test-input">Text field</div>
+          <input type="text" id="test-input" required>
+          <span class="form-error" id="test-error">Form error</span>
+        </form>
+      `).appendTo('body');
+      plugin = new Foundation.Abide($html, {});
+      plugin.addA11yAttributes($html.find('input'));
+      plugin.validateForm();
+
+      $html.find('input').should.have.attr('aria-describedby', 'test-error');
+
+      // Test also that the aria-described attribute is correctly removed after
+      // the error no longer applies and is hidden from the view.
+      $html.find('input').val('text');
+      plugin.validateForm();
+
+      $html.find('input').should.not.have.attr('aria-describedby', 'test-error');
+    });
+
     it('adds attributes and ids when no id is set', function() {
       $html = $(`
         <form data-abide>
           <input type="text">
-          <label class="form-error">Form error</label>
+          <label class="form-error is-visible">Form error</label>
         </form>
       `).appendTo('body');
       plugin = new Foundation.Abide($html, {});