2

I am working on a mobile application that has a list of items, each of which contain toggle buttons. When the Accessibility (Voice over) mode is turned on, the focus on these list items is enabled but double-tapping the item does not turn ON/OFF the toggle button.

Here's the code sample that I am using. It reads the content but the on-tap or ng-click methods are not triggered.

The below code focuses on the item but when it is double tapped, the toggle does not turn ON/OFF. Same behavior is observed on iOS and Android. Any ideas?

HTML

<ion-list>
   <ion-toggle role="option" toggle-class="toggle-balanced" ng-repeat=“item in items"  tabindex="-1" ng-model="item.isToggleOn" ng-change=“item.isToggleOn" on-tap=“updateSettings(item)" aria-label=“Item description,,  Double Tap to toggle setting." >
      <div class="pref-item-text-wrap” >Item description</div>
   </ion-toggle>
</ion-list>

In the Controller:

$scope.updateSettings = function (item) { console.log("In update settings"); }

user591410
  • 3,051
  • 5
  • 21
  • 30
  • Could you please provide a codepen or plunker? – Nam Pham Nov 12 '15 at 14:36
  • Here's a codepen.. If you try this on the phone with Voiceover on, double tap doesn't have any effect on the toggle button.. http://codepen.io/anon/pen/VvqeJZ – user591410 Nov 12 '15 at 15:03
  • Have you tried to use `ng-click` or `onclick` instead of `on-tap`. I think voiceover might not be able to trigger a `tap` event... – Adam Nov 13 '15 at 08:48
  • Yes, I tried ng-click, on-tap and onclick but all of them showed same behavior. I was thinking if it has got anything to do with the 'role' value.. ? – user591410 Nov 13 '15 at 12:55

2 Answers2

1

Heres a little hack to get it working.

In you SASS, after importing Ionic, you need to overwrite the pointer-events property of the toggle component:

// accessible toggles 
.item-toggle {
  pointer-events: all;
  .toggle {
    pointer-events: none;
  }
}

Please note that this makes the toggle not react to click events unless you handle that event manually on item level, eg:

<ion-toggle role="checkbox" aria-checked="{{isChecked}}" ng-model="isChecked" ng-click="isChecked=!isChecked">Toggle item</ion-toggle>
krik
  • 539
  • 4
  • 6
0

Events like gestures and keyboard events are intercepted by screen readers. You can use the correct roles to allow the screen reader to pass the appropriate event through to your JavaScript event handlers.

Also, note that when the screen reader is turned on, the gestures change. A single-tap becomes a double-tap on iOS and a double-tap becomes a triple-tap. See http://axslab.com/articles/ios-voiceover-gestures-and-keyboard-commands.php

Similar changes happen on Android.

That being said, you have many things wrong with that little bit of code:

  1. If the tabindex is -1, it will not be focusable for a keyboard-only user and is therefore not accessible by all users. You need to make sure that the tabindex is set to 0
  2. The behavior you are describing is more akin to a checkbox or radio role than it is to an option. You should probably be using the checkbox role.
  3. The parent of an option must be a listbox role as can be clearly seen in the spec http://www.w3.org/TR/wai-aria/roles#option, if you do use listbox in combination with option, you need to set aria-multiselectable to true

In any case, when you implement one of these roles, you must maintain the appropriate aria-* state properties and then you must use a device-independent event handler. You may have to use the ng-click in combination with ngAria to get the required behavior. Make sure that you test with a keyboard only and no screen reader (on Android) and with a keyboard and a screen reader (on iOS and Android) as well as touch and a screen reader (on iOS and Android).

unobf
  • 7,158
  • 1
  • 23
  • 36