]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
feat: automatically add [aria-describedby] and [for] attributes in Abide
authorNicolas Coden <nicolas@ncoden.fr>
Tue, 16 Jan 2018 22:20:43 +0000 (23:20 +0100)
committerNicolas Coden <nicolas@ncoden.fr>
Tue, 16 Jan 2018 22:20:43 +0000 (23:20 +0100)
docs/pages/abide.md
js/foundation.abide.js

index a5523625e56c69226853e6e3d96d91fa76646402..ff0768af1f6f2d31d30dfc6855802cf57d47d958 100644 (file)
@@ -141,18 +141,18 @@ When the Form Errors cannot be placed next to its field, like in an Input Group,
 
 ```html_example
 <form data-abide novalidate>
-  <div data-abide-error class="sr-only" aria-live="assertive">
+  <div data-abide-error class="sr-only">
     There are some errors in your form.
   </div>
 
-  <label>
+  <div>
     Amount
     <div class="input-group">
       <span class="input-group-label">$</span>
-      <input class="input-group-field" id="example3Input" type="number" required pattern="number" aria-describedby="example3Error"/>
+      <input class="input-group-field" id="example3Input" type="number" required pattern="number"/>
     </div>
-    <span class="form-error" id="example3Error" data-form-error-for="example3Input">Amount is required.</span>
-  </label>
+    <label class="form-error" data-form-error-for="example3Input">Amount is required.</label>
+  </div>
 
   <button class="button" type="submit" value="Submit">Submit</button>
 </form>
index 74d572e888ec87ca7d060e8c78a74af254af981d..1b6b924e458205f8a61add0e30f62eee7494caea 100644 (file)
@@ -2,6 +2,7 @@
 
 import $ from 'jquery';
 import { Plugin } from './foundation.plugin';
+import { GetYoDigits } from './foundation.util.core';
 
 /**
  * Abide module.
@@ -32,6 +33,11 @@ class Abide extends Plugin {
   _init() {
     this.$inputs = this.$element.find('input, textarea, select');
 
+    // Add a11y attributes to all fields
+    this.$inputs.each((i, input) => {
+      this.addA11yAttributes($(input));
+    });
+
     this._events();
   }
 
@@ -198,6 +204,46 @@ class Abide extends Plugin {
     });
   }
 
+  /**
+   * Adds [for] attributes to all form error targetting $el,
+   * and [aria-describedby] attribute to $el toward the first form error.
+   * @param {Object} $el - jQuery object
+   */
+  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);
+    }
+
+    if ($labels.filter('[for]').length < $labels.length) {
+      // Get the input ID or create one
+      let elemId = $el.attr('id');
+      if (typeof elemId === 'undefined') {
+        elemId = GetYoDigits(6, 'abide-input');
+        $el.attr('id', elemId);
+      };
+
+      // For each label targeting $el, set [for] if it is not set.
+      $labels.each((i, label) => {
+        const $label = $(label);
+        if (typeof $label.attr('for') === 'undefined')
+          $label.attr('for', elemId);
+      });
+    }
+  }
+
   /**
    * Remove CSS error classes etc from an entire radio button group
    * @param {String} groupName - A string that specifies the name of a radio button group