Results 1 to 3 of 3

Thread: ARIA-enabled ComboBox

  1. #1
    Ext JS Premium Member
    Join Date
    Mar 2007
    Vote Rating

    Default ARIA-enabled ComboBox

    I'm using Ext 2.2.1 and need an ARIA-enabled Ext.form.ComboBox. Where I primarily see the current ComboBox fall short of meeting the ARIA requirements is that it doesn't read the contents of the list items when using screen readers, such as JAWS. I am not an ARIA expert (been looking at it for about a day now), but I took a shot at enabling this. Let me know if you have any comments or better ideas on implementing this.

    First, I started with the ARIA class that you can find in the Ext examples:

    Ext.a11y.ARIA = Ext.apply(new Ext.util.Observable(), function() {
        return {
            setRole : function(el, role) {
                el = Ext.getDom(el);
                if(el) {
                    el.setAttribute('role', role.toString());
            setProperty : function(el, key, value) {
                el = Ext.getDom(el);
                if(el) {
                    el.setAttribute(key.toString(), value.toString());
    var ARIA = Ext.a11y.ARIA;
    Then I augmented ComboBox as follows:

     * Adds accessibility to the Ext.form.ComboBox by adding ARIA tags.
     * The wrapper around the input field is used as the main 'combobox' widget.
     * The following was copied from the "WAI-ARIA Best Practices" at: 
     * The items in the list have been numbered by me and will be used in the code
     * below to reference the item being addressed.
     *    ---- Copied from "WAI-ARIA Best Practices" -----------------
     *    A combo box is a combination of text field, which may be editable, a drop
     *    button to choose an item to place in the combo box, and a displayable list
     *    of items all wrapped in the form of a single widget. Like text fields a
     *    combobox should be labeled to determine the essence of the widget. Keyboard
     *    focus within the widget must be managed by the widget. Comboboxes are used
     *    extensively in graphical user interfaces and the design pattern for the widget
     *    should be semantically correct.
     *      1. The container element that wraps the combobox must have a role
     *         of "combobox."
     *      2. The first element within the combobox should be an input text field and
     *         is responsible for managing the keyboard focus between the textfield and
     *         the list as well as displaying the list. The textfield should be in the
     *         tab order. If create a textfield without using a standard HTML textfield
     *         form control then you must ensure that it is in the tab order.
     *      3. If the textfield is not editable it must have have aria-readonly="true."
     *      4. The next element should be an html <button> or another html element with
     *         a role of "button".  This button should be in the tab order and be
     *         responsible for opening the list.
     *      5. The next element constitute with a role="list" representing the drop down
     *         list and it should managed the keyboard navigation between each list item
     *         and back to the textfield if necessary.
     *      6. Each item in the list should have a role="listitem". Listitems should not
     *         be in the tab order.
     *      7. You should provide a label which labels the combobox by referencing the
     *         textfield in the combobox. You can use an aria-label to associate this
     *         label with the combobox or you may use the HTML <label> element and its
     *         for attribute to reference the textfield.
     *    ---- End copy ----------------------------------------------
     *    Note that item #7 is not being addressed at this time.  In my implementation,
     *    the label was attached to the input field via a "for" on the label.
    Ext.override(Ext.form.ComboBox, {
    	onRender: Ext.form.ComboBox.prototype.onRender.createSequence(function() {
    		// marks the input field as the combobox, see item #1 above
    		ARIA.setRole(this.wrap, 'combobox');
    		// adding 'textfield' is not technically necessary since "this.el" is an input
    		// field as described in item #2 above
    		ARIA.setRole(this.el, 'textfield');
    		// mark as readonly if not editable, see item #3 above
    		if (!this.editable)
    			ARIA.setProperty(this.el, 'aria-readonly', 'true');
    		// add role of 'button' to the trigger, see item #4 above.
    		// NOTE that I did not add the button to the tab order which is a violation of item #4.
    		// To do so would require additional coding to allow keyboard selection of the button.
    		ARIA.setProperty(this.trigger, 'role', 'button');
    		//ARIA.setProperty(this.trigger, 'tabIndex', '0'); // future?
    			// when the list is collapsed, clear aria-activedescendant so that the input field
    			// becomes the active element again
    			collapse:function() { ARIA.setProperty(this.el, 'aria-activedescendant', '');},
    	initList: Ext.form.ComboBox.prototype.initList.createSequence(function() {
    		// The drop down list is marked up the first time the list is activated
    		if (!this.ariaInit) {
    			// The 'innerList' is marked as an ARIA 'list' and the input field
    			// is marked as the owner of this list.  See item #5 above.
    			ARIA.setProperty(this.innerList, 'role', 'list');
    			// Since the list is not a direct descendant of the combobox, the
    			// 'aria-owns' must be set.
    			ARIA.setProperty(this.el, 'aria-owns',;
    			// Each element in the list is marked as an ARIA 'listitem'.
    			// See item #6 above.'div').each(function(el){
    				ARIA.setProperty(el, 'role', 'listitem');
    			// When the user changes the selection, the selected object is identified
    			// as the active descendant for this ComboBox widget.
    			this.view.on('selectionchange', function(view,selectionsArray) {
    				if (selectionsArray&&selectionsArray.length>0) {
    					ARIA.setProperty(this.el, 'aria-activedescendant', Ext.get(selectionsArray[0]).id);
    			}, this);
    I tested this using Firefox and JAWS 10 and pretty much got the behavior I was going for.

  2. #2
    Sencha User
    Join Date
    Mar 2007
    Haarlem, Netherlands
    Vote Rating


    Hi scottw,

    That looks like a perfectly good solution to me. We are adding ARIA support to other components then just the Tree we did now. Thanks for the time you took to look into this.

  3. #3
    Sencha User
    Join Date
    Mar 2012
    Vote Rating

    Default Using Aria for Combobox.

    I tried using the above code for the combo box I am developing so that JAWS would be able to read it, but I am not able to make JAWS read it.

    This is the combo box code I am using right now.
    pg.qfld_award_type=new Ext.form.ComboBox({fieldLabel:'Award Type',lazyRender: true,name:'extAwardType',store:new{fields:['type','desc'],data:pg.AWARD_TYPES}),displayField:'desc',valueField:'type',typeAhead:false,mode:'local',triggerAction:'all',selectOnFocus:true,emptyText:'All',width:220,editable:false,xtype:'combo'})

    Do you have any live examples using the above code/ similar code ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts