Using aria-live
to show form field validation error dynamically. Everything works, except when moving from one field to another using down arrow key/tab the validation error is only get announced once the next file label is selected, and reads that next label name then announces the previous fields validation error.
Code:
{!label ? null : <label htmlFor={`input-${model}`} className={classnames('inputLabel', `${model.toLowerCase()}-label`)}>{label} <i className={ classnames('fa','fa-asterisk', { 'isRequired' : requiredField }, { 'invisible' : !requiredField || !showAsterisk } )} aria-hidden='true'></i></label>}
{!label ? null : <br />}
<OverlayTrigger ref={(input) => { this.refPopOver = input; }} trigger={trigger} placement={popoverPlacement} overlay={popover} shouldUpdatePosition={true}>
<InputComponent model={`.${model}`}
{...extraProps} />
</OverlayTrigger>
<div id='errorRegion' aria-atomic="true" aria-live="assertive">
<Errors
className={classnames('errorText', 'error', model.toLowerCase())}
model={`.${model}`}
wrapper={ErrorWrapper}
show="touched"
messages={validators.messages}
/>
</div>
EDIT: slugolicious- thanks for you update. yes, I am using aria-live for announcing error. It works fine when using tab to go through the focusable elements. But when using browse mode using down arrow the sequence of announcing error and next label gets mixed up, I have also tried you suggestion but still the same result; its announce next label then error message of previous field. adding log of NVDA(v2017.4 & v2018.1) using Firefox (59.0.2 x64) below-
NVDA speech viewer log Second Edit: before the live regions are populated
<form style="position: relative;" autocomplete="off">
<div class="row">
<div class="col-sm-12">
<div class="id-form-errors" aria-live="assertive" aria-atomic="true">
<!-- react-empty: 170 -->
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12" style="margin-bottom: 20px;">
<div style="position: relative;">
<label class="inputLabel firstname-label" for="input-firstName">
<!-- react-text: 175 -->First name
<!-- /react-text -->
<!-- react-text: 176 -->
<!-- /react-text -->
<i class="fa fa-asterisk isRequired" aria-hidden="true"></i>
</label>
<br>
<input name="appForms.identify.firstName" class="field fullWidth firstname-field" id="input-firstName" aria-required="true"
aria-describedby="firstname-popover" type="text" placeholder="First name" value="">
<div id="errorRegion" aria-live="assertive" aria-atomic="true">
<!-- react-empty: 181 -->
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12" style="margin-bottom: 20px;">
<div style="position: relative;">
<label class="inputLabel lastname-label" for="input-lastName">
<!-- react-text: 185 -->Last name
<!-- /react-text -->
<!-- react-text: 186 -->
<!-- /react-text -->
<i class="fa fa-asterisk isRequired" aria-hidden="true"></i>
</label>
<br>
<input name="appForms.identify.lastName" class="field fullWidth lastname-field" id="input-lastName" aria-required="true"
aria-describedby="lastname-popover" type="text" placeholder="Last name" value="">
<div id="errorRegion" aria-live="assertive" aria-atomic="true">
<!-- react-empty: 191 -->
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12">
<button class="submitButton fullWidth disabledButton next-btn" aria-disabled="true" type="submit">Next</button>
</div>
</div>
</form>
HTML After error regions are generated:
<div class="row">
<div class="col-xs-12 col-sm-12" style="margin-bottom: 20px;">
<div style="position: relative;">
<label for="input-firstName" class="inputLabel firstname-label">
<!-- react-text: 226 -->First name
<!-- /react-text -->
<!-- react-text: 227 -->
<!-- /react-text -->
<i class="fa fa-asterisk isRequired" aria-hidden="true"></i>
</label>
<br>
<input type="text" class="field fullWidth firstname-field" placeholder="First name" id="input-firstName" aria-describedby="firstname-popover"
aria-required="true" name="appForms.identify.firstName" value="">
<div id="errorRegion" aria-atomic="true" aria-live="assertive">
<!-- react-empty: 232 -->
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12" style="margin-bottom: 20px;">
<div style="position: relative;">
<label for="input-lastName" class="inputLabel lastname-label">
<!-- react-text: 236 -->Last name
<!-- /react-text -->
<!-- react-text: 237 -->
<!-- /react-text -->
<i class="fa fa-asterisk isRequired" aria-hidden="true"></i>
</label>
<br>
<input type="text" class="field fullWidth lastname-field" placeholder="Last name" id="input-lastName" aria-describedby="lastname-popover"
aria-required="true" name="appForms.identify.lastName" value="">
<div id="errorRegion" aria-atomic="true" aria-live="assertive">
<!-- react-empty: 242 -->
</div>
</div>
</div>
</div>
3rd EDIT- Still waiting for a workable solution. Need help!