Difference between revisions of "ARIA Combobox"

From Level Access Web Labs
Jump to navigation Jump to search
Line 1: Line 1:
 +
== Example 1, Based on native <input> ==
 
Note about this example:  
 
Note about this example:  
 
* Bullet's are shown because wiki overrides list-style-type.
 
* Bullet's are shown because wiki overrides list-style-type.
Line 177: Line 178:
 
</body>
 
</body>
 
</html>
 
</html>
 +
 +
== Example 2, &lt;button&gt; using aria-owns ==
 +
Note about this example:
 +
* Example is primarily designed to demonstrate a remediation of a typical &lt;button&gt; bound pop-out section control, e.g. the type of simulated "drop-down" control generated by a UI library such as legacy versions of jQueryUI.
 +
 +
<html>
 +
<head>
 +
<!-- This example by Scott Huey, please direct any internal questions, comments or concerns to him directly. -->
 +
<style>
 +
ul.list.hidden {
 +
height:0px;
 +
width: 0px;
 +
overflow: hidden;
 +
border: none;
 +
}
 +
div.comboParent {
 +
background-color: white;
 +
border: 1px black solid;
 +
width: 12em;
 +
line-height: 1.6em;
 +
position: relative;
 +
}
 +
ul.list {
 +
position: absolute;
 +
top: 1em;
 +
left: 0em;
 +
background-color: white;
 +
border: 1px black solid;
 +
list-style: none;
 +
height: auto;
 +
width: auto;
 +
}
 +
button.combobox {
 +
background-color: white;
 +
width: 10em;
 +
height: 1.5em;
 +
border: none;
 +
position: relative;
 +
left: 0em;
 +
}
 +
span.edit {
 +
position: absolute;
 +
left: -999em;
 +
}
 +
</style>
 +
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
 +
<script type="text/javascript">
 +
function clickCB(e) {
 +
if ($("#cb_List").hasClass("hidden")) {
 +
$("#cb_List").removeClass("hidden");
 +
$(e.target).attr("aria-expanded", "true");
 +
$("#cb_List a").get(0).focus();
 +
}
 +
else {
 +
$("#cb_List").addClass("hidden");
 +
$(e.target).attr("aria-expanded", "false");
 +
$(e.target).get(0).focus();
 +
};
 +
};
 +
function cbSelectValue(e) {
 +
e.preventDefault();
 +
$("#cb_List").find("[aria-selected='true']").attr("aria-selected", "false")
 +
$(e.target).attr("aria-selected", "true");
 +
$("#cb_Content_Placeholder").text($(e.target).text());
 +
$("#cb_Edit").text($(e.target).text());
 +
$("#cb_List").addClass("hidden");
 +
$("#cb_Combobox").attr("aria-expanded", "false");
 +
$("#cb_Combobox").get(0).focus();
 +
};
 +
function cbListKeyUp(e) {
 +
var jSet = $(e.target).closest("ul").find("a"); //Get root node for parent listbox, then drill back down to find option elements.
 +
switch (e.which) {
 +
case 13 :
 +
// Enter - Activate
 +
console.log("Enter");
 +
break;
 +
case 37 :
 +
// Left - Do Nothing
 +
console.log("Left Arrow");
 +
break;
 +
case 38:
 +
// Up - Move to Previous in Set
 +
console.log("Up Arrow");
 +
var indexThis = jSet.index($(e.target));
 +
var indexToBe;
 +
if (indexThis - 1 < 0){ indexToBe = 0 }
 +
else { indexToBe = indexThis - 1 };
 +
jSet.get(indexToBe).focus();
 +
e.preventDefault();
 +
break;
 +
case 39:
 +
// Right - Do Nothing
 +
console.log("Right Arrow");
 +
break;
 +
case 40:
 +
// Down - Move to Next In Set
 +
var indexThis = jSet.index($(e.target));
 +
var indexToBe;
 +
if (indexThis + 1 > jSet.length - 1){ indexToBe = indexThis }
 +
else { indexToBe = indexThis + 1 };
 +
jSet.get(indexToBe).focus();
 +
e.preventDefault();
 +
break;
 +
case 32 :
 +
// Spacebar - Activate
 +
console.log("space");
 +
break;
 +
};
 +
}
 +
</script>
 +
</head>
 +
<body>
 +
<div>
 +
<span class="comboLabel">Select a Browser:</span>
 +
</div>
 +
<div class="comboParent">
 +
<button id="cb_Combobox" role="combobox" aria-label="Select a Browser" aria-expanded="false" aria-owns="cb_Edit cb_List" class="combobox">
 +
<span id="cb_Content_Placeholder" aria-hidden="true">...</span>
 +
</button>
 +
<span id="cb_Edit" role="textbox" aria-readonly="true" class="edit"></span>
 +
<ul id="cb_List" role="listbox" class="list hidden">
 +
<li role="presentation">
 +
<a href="#" role="option" aria-selected="false" tabindex="-1">Firefox</a>
 +
</li>
 +
<li role="presentation">
 +
<a href="#" role="option" aria-selected="false" tabindex="-1">Internet Explorer 11</a>
 +
</li>
 +
<li role="presentation">
 +
<a href="#" role="option" aria-selected="false" tabindex="-1">Safari</a>
 +
</li>
 +
<li role="presentation">
 +
<a href="#" role="option" aria-selected="false" tabindex="-1">Chrome</a>
 +
</li>
 +
</ul>
 +
</div>
 +
<br />
 +
<script>
 +
(function(){
 +
document.getElementById("cb_Combobox").addEventListener("click", clickCB);
 +
$("#cb_List a").each(function(){
 +
this.addEventListener("click", cbSelectValue);
 +
this.addEventListener("keyup", cbListKeyUp);
 +
});
 +
})();
 +
</script>
 +
</body>
 +
</html>
 +
 +
 
[[Category:ARIA]]
 
[[Category:ARIA]]

Revision as of 17:57, 27 March 2017

Example 1, Based on native <input>

Note about this example:

  • Bullet's are shown because wiki overrides list-style-type.
  • This solution uses the autocomplete="list" approach with aria-activedescendant on a listbox.

Challenges this solution overcomes:

  • IE does not render display none referred to be aria-activedescendant. This example make the visible child input as the activedescendant when the combobox is closed.
  • IE appears to create a infinite combobox structure when role combobox applied to input. This solution uses a div with role of combobox.
  • JAWS auto forms mode doesn't work correctly when role of combobox is used on input field -- it sees the box as an edit and turns off forms mode when arrow keys are used. This solution uses a div element instead with a role of combo box.
  • activedescendant doesn't work right in IE unless tabindex="-1" is put on each element. That is done in this example.

Reference: WAI - description, properties, keyboard interaction.
http://www.w3.org/TR/wai-aria-practices-1.1/#combobox

ARIA Combobox

  • iOS
  • Android
  • Windows Phone

Example 2, <button> using aria-owns

Note about this example:

  • Example is primarily designed to demonstrate a remediation of a typical <button> bound pop-out section control, e.g. the type of simulated "drop-down" control generated by a UI library such as legacy versions of jQueryUI.

Select a Browser: