Incrementing a `role="spinbutton"` with Voiceover - javascript

I'm struggling to implement an accessible input with increment/decrement behaviors, using an <input type="text" role="spinbutton" /> element in HTML/JavaScript. But it seems like with VoiceOver there are custom (fake?) input events for incrementing/decrementing which change the input's value in unexpected ways.
How do I make sure a user navigating the page with assistive technology doesn't get bad guidance from VoiceOver while trying to interact with my widget?
For example, using super trimmed-down code like this:
function logIt(...args) {
document.getElementById('output').appendChild(
document.createTextNode(`${args.join(', ')}\n`)
);
}
document.getElementById("myInput").addEventListener('input', (e) => {
debugger;
logIt(e.type, e.data, String(e));
e.target.setAttribute('aria-valuenow', e.target.value);
}, false);
document.getElementById("myInput").addEventListener('keydown', (e) => {
logIt(e.type, e.data, String(e));
}, false);
<input
id="myInput"
type="text"
role="spinbutton"
autocomplete="off"
defaultValue="1"
aria-valuenow="1"
aria-valuemin="0"
aria-valuemax="100"
/>
</div>
<pre id="output"></pre>
... VoiceOver will describe the input as a "stepper" and give instructions on how to increment/decrement using the keyboard. But using those keyboard commands results in some weird math, as seen in this screen cap:
You can also see (from the "logging" in the screen cap) that when the user types input, an InputEvent is triggered with event.type being input - but when the VoiceOver keyboard command for increment/decrement is used, a base-type Event is triggered with event.type again set to input.
And this doesn't seem to be unique to my implementations of role="spinbutton". The jQuery UI spinner doesn't behave well when incremented/decremented using VoiceOver keyboard commands:
I even tried some of the w3c's examples for role="spinbutton":
The font size widget on https://www.w3.org/TR/wai-aria-practices/examples/toolbar/toolbar.html
The date picker on https://www.w3.org/TR/wai-aria-practices/examples/spinbutton/datepicker-spinbuttons.html
... and even though VoiceOver described each of those UI controls as a "stepper" and gave instructions on how to increment/decrement them using the keyboard, those instructions didn't seem to work. Other keyboard behaviors worked - but the ones VoiceOver suggests don't.
What can I do to make sure that role="spinbutton" markup works correctly with VoiceOver's increment/decrement keyboard commands?

I don't believe role="spinbutton" is compatible with VoiceOver as it seems that VoiceOver hijacks the keydown events when using the VoiceOver cursor. So when focusing on an element with role="spinbutton" VoiceOver instructs the user to use "Control-Option DownArrow" or "Control-Option UpArrow" to decrement or increment the value. When those keys are pressed the event does not make it to any JavaScript keyDown event handler so we can't detect that those keys have been pressed and can't implement the actual incrementing or decrementing of the value. So I'm not sure there is any way to use role="spinbutton" and make it work with VoiceOver. The user will be given instructions that don't work and will be confusing.
As a workaround for an application that I'm working on I've implemented the key handling behavior described in the WAI ARIA authoring practices for spinbutton but I have not added role="spinbutton" or the other aria attributes listed. Instead, I've added aria-live="assertive" so that when the value is changed either by keyboard or clicking the increment/decrement buttons the user hears the new value. Additionally, I've added some visually hidden text that instructs the user on how to increment/decrement the value with the keyboard and associated that with the input using aria-describedby.

I just visited w3's spinbutton example, and it seems to be keyboard operable in VoiceOver Mac (OS Version 10.15.1 with Safari). You can inspect the code they have used, and get inspiration there.
However, the w3 spinbutton example does not announce the current value when the stepper receives focus, or the changes as you step up and down. I tried Medium and High verbosity settings with no luck.
This failure to announce the value (either aria-valuetext or aria-valuenow or perhaps both) seems to be a bug on Apple's side, so I just reported it. Good catch.
This could perhaps be hacked-in with an aria-live region, but you might end up with duplicate announcements on other browser/screen reader combinations.

Related

Is there a way to trigger the 'magic caret' feature on ios (web)

I've created a js virtual keyboard that is able to update the value of a textarea. On mobile, you can trigger the 'magic floating caret' by holding down on a textarea or holding any key on the native keyboard. Because my textarea input mode is set to none in order to hide the native keyboard and show my own, I'd like to know if there is a way to trigger that second effect using my own keyboard?
My understanding is that I can trigger an event using execCommand or jQuery's trigger function, but neither are able to do what I'd like.
Thanks for input!
magic cursor article link news18

Backspace doesn't work in number input field KaiOS | Svelte3

I've run into this weird problem while developing an app for KaiOS using Svelte3. When the input field is set to type number the backspace doesn't work. At all.
<input
bind:this={ref}
bind:value
type="number" />
When it's set to "text" it works perfectly fine. Backspace removes characters as it's pressed. Backspace in this case is the "Call End" button on KaiOS devices. I don't know if this is a KaiOS problem or a Svelte3 problem.
I'm not very skilled in WebDev technologies, so I don't know what else to try. Some additional info that might point towards something.
I have one listener globally
window.addEventListener("keydown", onKeyDown, true);
Which is attached in my KeyListener that I use to control my app navigation through selectable elements. This also doesn't fire when the backspace is pressed while an input field has focus. Things I have tried.
Assign functions to onkeydown, onkeyup, onkeypressed (none of them fire the backspace call)
Removed the event listener that I mention above, changes nothing.
Assign the functions in a non-svelte way as pure JS inline functions.
On KaiOS only onkeydown fires, incase that might give any of web dev JS experts a hint. I don't know what else to do. Any suggestions would be appreciated.
We have no idea why this works but setting the input type to "tel" makes the backspace key fire and the input field to act as normal while still allowing numbers only.
To handle events on window you can use <svelte:window>. For example:
<svelte:window on:keypress={handleKeypress}/>
But if all you want to do is monitor keypresses on an input you can do it on the <input> directly with <input on:keypress={...}/>.
Here's an example of handling keypress on an input: https://svelte.dev/repl/bfd93b0799c142979eefa1f2558bfb96?version=3.20.1

Prevent voice input on a web page?

I have html input[type=text] element.
I want user NOT TO use voice input / voice typing (actually I need to prevent voice input provided by Android/iOS on-screen keyboard) on my input element or entire document at all.
// Tryed hard to find any answers, but it looks like no one else got the problem.
// I've already put other preventive attribs on the input so it looks exactly:
<input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
And yes, I understand this feature is up to mobile's keyboard, not browser.
Anyway, please suggest any workarounds.
Update: The interface exactly needs user to type words with their hands. There are no accessibility issues due to interface's purpose.
This is simply not possible because of sandboxing. It's also an awful idea because it ruins accessibility.
You could try using Javascript to only listen to keydown events, but this depends on the voice-to-text program not emulating key presses, and also removes the ability to copy-and-paste.
You could have an on-screen keyboard which requires users to click the buttons instead of using their own keyboard, But you won't be able to override the native keyboard without accessing the phone's API, which is usually only exposed to native apps.
You're really playing with fire in terms of UX with either of those solutions, though. Is there any reason you can't allow voice-to-text, or are you trying to reduce errors?

Safari on iOS, is there any event before virtual keyboard pop up?

I'm developing a iOS browser application(html + javascript), and there's something wrong with the fixed-bottom(from twitter bootstrap) feature when virtual keyboard is pop up, so I want to disable it before virtual keyboard is pop up. Is there any event can do that ?
I've tried focus event when focusing an input field, but it's too late, the fixed bottom element will be already affect by virtual keyboard, Any solution ?
Have you tried on checking mousedown / touchstart which occurs before the focus? Just check whether the event.target.nodeName.toLowerCase() is "input" or "textarea" when it's dispatched.
I've also created https://github.com/zvona/Servant.js, which is an initial version of advanced keyboard handling. It supports "keyboardshow" but not "beforekeyboardshow". I'll check whether it can be implemented and to help in your case.
.
In Objective C you would register for one of the keyboard notifications. The one you would need is called UIKeyboardWillShowNotification. I don't know what literal string that translates to. I'd have to write a bit of code in order to figure out the string literal.
I don't know if you can register for notifications in Javascript.
Please check onresize event of body element in your html.
if you are using jquery you can use this plugin.

HTML select onchange accessibility concerns

We have a request to use a select element's onchange to trigger a move to a new page.
In the past, web accessibility literature I've read has generally advised against doing this. This was on the grounds that it breaks user expectation, and browsers (particularly IE < 6) fired the change event even when moving through options with the keyboard, making it impossible for keyboard-only users to make a selection.
IE6+ and all other more modern browsers I have tested fire the select onchange when an option is actually selected by mouse or enter key. Analytics for the application in question show that earlier IE browsers are essentially eradicated (< 0.01%)
Given that our users will be able to operate these select elements properly with a keyboard only, should this feature still be considered an impediment to accessibility? This behavior seems so common nowadays that I wonder also if it really still does break user expectation in a meaningful way?
EDIT: IE behaves differently if the select is focused with the mouse or keyboard. When focused with the mouse, keyboarding through options does not fire onchange but when tabbing to focus it via keyboard, the onchange does fire when arrowing through.
Using the onchange event of the select element to navigate between pages can definitely pose an accessibility problem for keyboard-only users.
There is at least one method of creating accessible select elements with onchange handlers and it has been on the interwebs since 2004!
Direct link to the Accessible Select code.
I agree with you that this type of functionality is very common. However, most sites use links instead of a <select> to achieve the effect (if I'm not mistaken). I.E. it's the standard (pun intended).

Categories