For this use case, I would add aria-live and aria-atomic attributes, example code:
<select id="foo" aria-live="assertive" aria-atomic="true">
<option value="nw">Northwest</option>
<option value="ne">Northeast</option>
<option value="se">Southeast</option>
<option value="sw">Southwest</option>
</select>
I think assertive is the right value for the aria-live attribute, but polite might be appropriate instead. The aria-atomic attribute is there to tell the browser/AT that region must be presented as a whole when there is a change. You might also consider using aria-disabled: true on the select initially, then switch it to false before you update it with the values associated with the State select.
Edit
OK, I've done some testing using NVDA and IE9 and Firefox 13.01. I don't have JAWS available at the moment, so it'd be great if someone could test the page with JAWS.
VoiceOver as far as I know doesn't have support for aria properties yet Just tested with Chrome + Voiceover on 10.7 (Lion) and Voiceover does indeed appear to have support for aria-live.
Test page available here.
I used a simple script that simulated loading data into the regions select (using an object):
var options = [],
regions = {
'nw': 'Northwest',
'ne': 'Northeast',
'se': 'Southeast',
'sw': 'Southwest'
}
$(document).ready(function() {
$.each(regions, function(key, value) {
options.push('<option value="'+ key +'">'+ value +'</option>');
});
$('.block').on('change, focusout', '.states', function() {
$(this).parent().children('.regions')
.attr({'disabled': false, 'aria-disabled': false})
.html(options.join(''));
});
window.setTimeout(
function() {
$('#speak').text('assertive!');
},
3000
);
});
Some observations after playing with this a bit (I'm certainly no expert when it comes to screen readers, so if I missed something let me know)...
Using the HTML disabled attribute is not advised as you really don't want to load the region data until the state select is focused out and since the associated region select is disabled at the time of the focusout it is skipped when tabbing to the next control (you can hear this in the recordings below.) Strangely, Firefox announces the value of the region select even though it doesn't focus it.
I saw no difference in behavior between polite and assertive, or for that matter in the example without the aria-live attribute. I thought that both FF13 and IE9 had support for aria-live, but from the last but of code ($('#speak')...) it appears that IE9 doesn't?
Perhaps a delay to simulate loading via AJAX would be a good thing to add.
You can listen to the recordings: IE9, Firefox 13