I got an old angular js application and my mission is to fix accessibilty problems. I have a table that includes radio buttons within the cells and I need to navigate between them using the arrow up and down keys.
I already have a method that deals with this issue and its working fine until i test it using screen reader (NVDA)
What happens is for some reason the SR cause the method to be ignored
and causes the table to lose its focus.
the only way that I managed to make it work is by setting the table with role="application".
but from what I have been reading so far it is wrong to use it in this case
This is a sample of one of the cells :
<td class="scheduleLineCell" style="text-align: center;">
<input type="radio"
class="btnRadio ng-valid ng-not-empty ng-touched ng-dirty"
aria-describedby=""
value="126" data-ng-model="selectedIdList[childSchedule.gridIndex]"
data-ng-key-press="scheduleKeyPress"
data-ng-grid-index="0"
xng-focus="isFocusOnStationButton == false &&
isFocusOnMapButton == false && ScheduleLine.Id ==
selectedIdList[search.currentScheduleGridIndex]" name="2096">
</td>
Can you make a working example on here or on JSfiddler?
Off the top of my head I can say this.
You should not put controls in tables or uses tables for design purposes.
a. If you have an enter data row make it from "div"s
b. Remember screen readers repeat table headers a lot!
JAWS and NVDA does mess with a screens JSEvents and get us a example page to help
(AngularJS) Refactor the control back to a component or directive and see if that helps.
a. e.g.
<custom-radio-button ng-value="val" aria-checked="true"></custom-radio-button>
Related
So I have a table with 50 columns and about 4-600 rows and laggy poor performance. There are some computed properties in use. The tables cells are inputs, selects and textareas.
I use the vue-scrolling-table, because I need vertical and horizontal scrolling, and fixed first column. But the performance is really bad.
I also have the same setup, somewhere else is the app, but it doesn't have the same performance issues.
I already tried to use a virtual list, but I could'nt get it working with the vue-scrolling-table/ (the header didn't follow the scrolling, and the vertical scroller was only available if I scroll to the bottom)
I also looked at virtual scroller but it recomanded not to use with inputs and such, since it is replacing the data inside the input, and that would trigger the change event etc.
I have a v-for, that goes through the data, and one v-for inside, for a subset in the columns. (I can't be sure how many columns there will be.)
<template slot="tbody">
<tr v-for="(row,index) in table" :key="index">
<td>
<input v-model="table[index].someItem">
</td>
<td>
<select v-model="listyThing">
<option v-for="item in list">{{item}}<option>
</select>
</td>
...
# I have some computed stuff ,(like 4)
SomeComputedFunction: function() {
return this.table.map((row) => {
return row.some * row.somethingelse
})
}
This should work fine. The data I'm working with is not that big, that it should cause problems. I try to do anything in this, and the cpu spins up to 100% and everything happens with 2s delays.
Also one interesting thing I found, the selects open in like 3 secs. I thought that was curious.
When I used the virtual list the performance was better, but I need some other solution for the table.
Does anyone have an idea what is the difference between this, and my other one which works just fine (more data and more computed properties actually)
So what I think the difference can be is the selects and the v-for rendered columns (about 20 of them rendered this way). Or maybe the textareas?
Thanks in advance!
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.
I've been working on some webapp where i have a table which is filled with some data and to select which data should be displayed i use filters. These filters are <div> elemtens which contain one <div> per filter option like so:
<div id="selectedFilter">
<div>
<input id="selectedFilter1" type="checkbox" name="selectedFilter" multiple="true" value="1" checked="true">
<label for="selectedFilter1" title="Option1">Option1</label>
</div>
<div>
<input id="selectedFilter2" type="checkbox" name="selectedFilter" multiple="true" value="2" checked="true">
<label for="selectedFilter2" title="Option2">Option2</label>
</div>
<div>
The html code for the options (the whole <div> with <label> and <input> ) is generated in my java backend and gets transferred to the site like this:
$.post("filter", result, function(data) {
$("#selectedFilter").html(data);
});
Now my problem:
The amount of filters gets sometimes really high (e.g. 800 rows) and there are two more filters on the page with about the same amount of options. With such a load of data the browser begins to hang and becomes unresponsive.
To fix this i tried using virtual scrolling since this seems to be the most reasonable way to keep the browsercache on a good level. But this clears the checkboxes, if i render the whole div again.
On top of that i need to know which checkboxes are checked even if they are not in the viewport because the filters are influencing each others possible options in a cascading manner (Filter1 influences Filter2 influences Filter3). If one filter changes (something gets selected) the subsequent one (or two) gets cleared and requests new data from the java backend.
Question:
Is there maybe a js-library which supports the virtual scrolling but manages the checkboxes by itself so i can extract just the checked ones? Something like this.
I might try to save which chechbox was selected but i fear that the virtualisation of the scrolling might be very slow if there is a matching of the displayed options whether they are checked or not in every single scroll.
Does anybody have suggestions or experiences?
You are saying you are having 800 filters , do you really think any user gonna see all those 800 or more filters together. The best thing is to categories your filters and then load them on click of category.
Virtual Scrolling is good idea. You need to append filter data as .html() is overriding your previous content.
$("#selectedFilter").append(data);
In an html form, I have a table that I hide or display based on a radio button choice. When the table is hidden and then brought back, one of the style settings is lost. I would like to keep the same layout when the table is displayed.
HTML for the table
<table id="tblAutomated">
<tr>
<td>Are the deposits automated?</td>
<td id="tdAutomated" style="text-align:right"><input type="radio" name="rbAutomated" value="yes">Yes <input type="radio" name="rbAutomated" value="No">No</td>
</tr>
</table>
JS for the radio button just the relevant part
document.getElementById('tblAutomated').style.display='block';
document.getElementById('tdAutomated').style.textAlign='right';
But IE Dev Tools shows an unhandled exception for that second JS line. "Object doesn't support property or method."
So, I tried adding a class to the <td>.
<td id="tdAutomated" class="tblRight">
and I added the text-align style to that class. Then I changed the JS to try two other methods: .hasClass and .addClass. But both of those methods failed, too.
Is there a method that will either set that alignment correctly or allow the class to be added?
EDIT
Here are the images of what I see and what Dev Tools shows is happening in the HTML. Using both methods, I see no reason why the cell shouldn't go back to where it was originally.
I was able to resolve this by putting the table inside a <div> and changing the display for that, instead.
Is it possible to append some HTML to the end of a typeahead? I've tried many different things but none have worked.
What I'm trying to do is have the last result of the typeahead be Search for "< what the user typed into the input >".
Here's what I've tried on JSFiddle: http://jsfiddle.net/MgcDU/8621/
What I expected it to do was append the <li> at the end of the dropdown once it's created, but it doesn't. Why?
HTML:
<input type="text" data-source="["Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Dakota","North Carolina","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"]" data-items="10" data-provide="typeahead" style="margin: 0 auto;" class="span3">
jQuery:
$(".typeahead.dropdown-menu").append('<li data-value="Custom" class="">CUSTOM TEXT</li>');
The dropdown menu is built during the typeahead filtering process. If you inspect it "on load", you will notice it is empty.
Depending on your specific problem you're trying to solve, i can think of two possible solutions.
One solution would be to extend the typeahead plugin and provide a custom "render" function. This would allow you to modify the list rendering process and append additional <li>s as well as anything else you like. This is probably regarded as the "best way".
Another more hacky solution would be to place your custom value in the data source, then provide a custom "matcher" function which runs the original matcher along with an additional clause for your custom value.
Of course solutions are tied to problems and without really knowing the very specifics of what you want to do, i can't recommend which one to use. But those are your two options as far as i can think.