```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>
import $ from 'jquery';
import { Plugin } from './foundation.plugin';
+import { GetYoDigits } from './foundation.util.core';
/**
* Abide module.
_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();
}
});
}
+ /**
+ * 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