Accessibility for dropdown component - javascript

I am implementing accessibility for dropdown component, the special feature of my dropdown is it populates values in options menu only while opening dropdown,meaning it on the fly compiles the template and attaches to the dropdown box.
Dropdown HTML:
<div id="dropdown" ng-click="openDropdown()">
<div id="selectedValue" role="listbox" tabindex="0" aria-label="{{selectedVal}}" aria-owns="dropDownMenu">{{selectedVal}}</div>
</div>
DropDown Menu template(which gets compiled and polpulated after clicking dropdown above) :
<div id="dropDownMenu">
<li ng-click="selectItem()" role="option">item1</li>
<li ng-click="selectItem()" role="option">item2</li>
</div>
I am facing two problems
As my #dropdownMenu gets generated on click of #dropdown(dynamic template generation) jaws do not have access to #dropdownMenu when focus comes to #selectedValue so it doesn't announce the number of options etc as in case of a typical selectbox.
I am giving aria-label="{{selectedVal}}" for #selectedValue so on click of arrow keys javascript takes care of updating selectedVal even though #dropdownMenu is not open ,but changed value of selectedVal is not announced by jaws 16.0 ,it only announces it only first time as user tabs into it .Noted that this works fine in jaws 14.0 .
Looking forward for some solutions....

Adding aria-live=polite should fix this.
Is there a reason you're not using a standard select box and populating the option elements with your dynamic content? That would remove the need to update an aria property with the current option, as screenreaders will find it themselves. Also aria-label should be the name of the selectbox (or its purpose) not its selected option. If you were using a HTML select with options you could then remove the tabindex and aria-live as well, since native form inputs have full keyboard and screenreader support by default.

You should probably wait until the element is rendered and appeared in the DOM and only then set the focus to the first submenu item by using a native function .focus(). That will do the job.
But... Make sure that if the request takes too long and the user has already left somewhere else doing something else on the page, that in this case you don't steal his focus to get him back to the dropdown menu otherwise he might be annoyed.
Also instead of tabindex=0 for interactive elements (wherever you use ng-click) I would recommend that you use the actual native elements such as <a> or <button>. That way you ensure that the elements will be focusable both by keyboard but also visually, and react to ALL keyboard keys which the users are used to use and thus expect it to react such as SPACE or ENTER without needing you to implement it manually.

Related

using aria for expandable items

I have a expandable div element which is expanded when user clicks.
How can i make it accessible through screen readers.
Below is my code
HTML
<div class="expandable" (click)="expandItem()" attr.aria-expanded="isCollapsed">
Some content to show on expand
</div>
JS:
expandItem() {
this.isCollapsed = true
}
variable isCollapsed is set to false initially.
I might be showing my javascript ignorance but I haven't seen (click)="expandItem()" or attr.aria-expanded="isCollapsed" before. I have seen onclick="expandeItem()" and aria-expanded="false". But I'll ignore that aspect for now.
First off, your <div> has no semantic meaning so you'll need several ARIA attributes to fix that. But before you do that, consider the "First Rule of ARIA Use", which is essentially to not use ARIA. Use native semantic HTML elements as your first choice if possible.
I'd need more information on your scenario but consider using a real <button> instead of a <div>. It sounds like you might have a "disclosure widget".
If a real <button> is not used, then your <div> will need:
tabindex="0" (to allow keyboard focus to move to it)
a click handler (for mouse users)
a keyboard handler (for keyboard users to use space and enter to select it)
a role="button" so a screen reader announces the proper semantics
(I'm assuming your <div> has a label)
In addition to that, then you need to resolve your aria-expanded issue. In the onclick of the button (or div), just toggle the value of aria-expanded. Since that attribute is a "state" (instead of a "property"), changing its value will be announced automatically by screen readers.

Material ui select move the scroll to top if all items are selected

I use material ui select and I noticed that when I select all items, close the select and reopen it again, the position of the scroll is moved to the end, is there any way to keep it at top?
current behavior:
expected behavior:
I looked for all options presented in the api but no one of them helped, my idea is to get the DOM element directly and apply element.scrollTo=0
This issue is that material-ui's autoFocus goes to the last item by default. I couldn't get it to work differently unfornately (it seems torevolves around playing with tabIndex in the Paper element of the list). However what you can do is disable the focus all together:
<Select ... MenuProps={{autoFocus: false}} >
...
</Select>
The pitfall of this approach is that whenever you open the menu, it'll always focus on the 1st item of the list, even though only the last item was selected.
example: https://codesandbox.io/s/material-demo-yv5vg

How can I manipulate HTML elements which are added during the runtime?

The code im working on first makes a call to the database. Through this call, it is determined wether there are available workstations in the office or not.
If there are available workstations, "option" elements are added to a "select" element. This is achieved via jquery:
$('#idofselectelement').html(data)
Where "data" represents the markup to be inserted into the "select" element.
Now, my problem is that I'm trying to implement some code which checks wether your "favorite workstation" is available in the selected timeframe and then automatically preselects the respective workstation from the dropdownmenu in the "select" element. Everything is working so far, except for the selection of the workstation from the dropdown menu :/
The part of
I'm rather new to programming with javascript and the HTML DOM, so I'm not sure whether the fact that the options im trying to chose from are added during the runtime?
The code I've tried to manipulate the dropdown menu with is like this:
$('#idofselectelement').val(favoriteworkstation);
However, as I said, this doesn't work.
I've also already tried to output (console.log) the select element's length property right after the code which adds the markup with the available options has run.
But according to the output Im getting, the length is zero Oo
However, the dropdownmenu is definitely being created AND I can indeed manipulate it, but unfortunately not in the way I want to.
If I add an onclick event which sets the value of the respective select element, then the value in the select field indeed changes to the value specified in the event handler.
So I wonder why I can't have the favorite workstation preselected after the timeframe was chosen...
EDIT:
For further insight into the problem, I'm adding a bit more code here.
This is what the HTML Select element looks like BEFORE anything is added during the runtime:
<label for="#sitz">Sitz Nr.</label>
<select type="text" class="form-control" id="sitz" name="sitz" value="">
the markup which is added during the runtime
<option>workstationvalue</option>
<option>workstationvalue</option>
//and so on, depending on the situation...
This is a timing issue.
The js trying to find the element is faster than the actual add of the element to DOM.
Can you describe what you want to do? You might be able to do that before adding the element to DOM.
Editing before adding to DOM is possible if you convert your String to an jQuery object
var $jqueryObject = $(data);
$jqueryObject.find('.classYouSearch').val(value);
$('.whereToAd').html($jqueryObject);

chrome.contextMenus exclude type

Is there a way to exclude one of the type of contextMenu if they overlapping?
example:
I have two context items, editable and selection.
In situation when both of those types match, (selection inside editable)
Chrome gives sub-menu for both actions.
I would like to have only one.
How can I prioritize or exclude one of those types in this specific situation?
If the menu item types are identical (i.e. same type, type, etc.), then you can declare the context menu and specify multiple contexts. Then the menu item will show up if any of the contexts match.
You've however stated that you really need separate context menu declarations:
Menu item with title "Make note" for the "selection" context.
Menu item with title "Insert note" for the "editable" context.
Menu item with title "Make note" when both contexts apply, e.g. when text is selected in an input field (so without the "Insert note" menu item).
The contextMenus API does not directly support this use case. So the next best alternative is to remove the context menu for the "editable" before the context menu appears in the third situation (and restore the context menu when the third situation is no longer relevant).
In your situation, I would use selectionchange to detect when the user (de)selects text. Upon selecting text, check whether an input field is in the selection (to do so you can combine the Selection, Range and/or DOM (traversal) APIs). If you find an input field, remove your desired context menu item.
Regardless of whether you find a menu item, add listeners for key and/or mouse events to detect whether the user's pointer is on an input field.
Here is an example that uses selectionchange (https://stackoverflow.com/a/13673942/938089) and another one for Showing context menu buttons only when right-clicked on classes that start with “Story”.

Javascript unfocus select menu

I have a big page, with full of (server side) generated information organized into "chapters". To allow an easier overview for the user I put a little element with CSS fixed position to the top right corner of the page.
<div class="selector">Goto section within the table: <select
id="chapterselector"
onChange="goto_section('chapterselector')">%SELECTOR%</select>
</div>
The text "%SELECTOR%" is replaced by the server side component to the correct option elements.
function goto_section ( element ) {
element = document.getElementById(element);
window.location = '#Chapter_' + element.value;
}
This is the JavaScript part for now. This works nicely. However one little issue remains:
Users (including me) can use the select menu to jump inside the document, but then often cursor arrow keys would be used to navigate to scroll the page. The problem: after using the select menu, it has the focus, so cursor keys now "scrolls" the possible choices inside the select menu. What I want: after using the select menu, I want it to lose the focus automatically, so cursor keys scrolls the page.
How can I do this? Thanks for any suggestion.
element.blur()
try that after setting the location

Categories

Resources