'data-invalid': '',
'aria-invalid': true
});
+
+ if ($formError.filter(':visible').length) {
+ this.addA11yErrorDescribe($el, $formError);
+ }
}
/**
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) {
}).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
'data-invalid': null,
'aria-invalid': null
});
+
+ if ($el.data('abide-describedby')) {
+ $el.removeAttr('aria-describedby').removeData('abide-describedby');
+ }
}
/**
$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, {});
$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, {});