How to prevent VoiceOver from focusing on the content behind a modal - javascript

I have a modal and I don't want voiceover to read the content behind it. Setting aria-modal=true should've been enough but then I saw that VoiceOver does not support this behaviour out of the box like better screen readers like NVDA and JAWS.
https://a11ysupport.io/tech/aria/aria-modal_attribute#support-table-2
And it says that authors can implement this functionality on their own for VoiceOver. I have successfully trapped the keyboard focus inside the modal (using the tab key) with JS but voiceover is going behind the content when I use the arrow keys. How can I achieve this? My modal is structured like this:-
<div
role="dialog"
aria-modal="true"
aria-labelledby="title"
aria-describedby="description"
tabindex="-1"
>
<div class="sticky-header">
<h2 id="title" class="title">
This is a heading
</h2>
</div>
<div class="modal-content">
<p id="description">
This is a paragraph.
</p>
</div>
<div class="sticky-footer">
<button
type="button"
>
Cancel
</button>
<a href="#">
Proceed
</a>
</div>
</div>

am not a good UI export but its a bit suggestion
please try these attributes I hope you'll get better solution.
My solution is:
role="alertdialog" aria-modal="true"

I had this issue as well. With voice over the user can "click" outside and swipe out of the dialog. I believe this is a issue with VoiceOver, and I could not find any solution on the web. It's not the best solution but what I ended up with was to add a boolean to the open/close dialog event. Then use the boolean with aria-hidden
<div [attr.aria-hidden]="IsMenuOpen">content behind menu</div>
<button (click)="openMenu(); isMenuOpen = !isMenuOpen" ></button>

Related

javascript function to minimise boxes - start boxes minimised

Hi guys I am using a template that had some features that I liked. One of these is a table that can be minimised on a button click using the code below.
$('.btn-minimize').click(function(e){
e.preventDefault();
var $target = $(this).parent().parent().next('.box-content');
if($target.is(':visible')) $('i',$(this)).removeClass('chevron-up').addClass('chevron-down');
else
$('i',$(this)).removeClass('chevron-down').addClass('chevron-up');
$target.slideToggle();
});
The only problem is that I have a few of these that I would like to start as minimised as they won't be used often.
I tired using an alert to see what data was held in $target and then maybe use an onload function to minimise them.
All i got was 'object Object' for every box.
Is there anyway to be able to identify certain boxes or if not at least have them all start minimised.
Thanks
HTML for box is
<div class="box black span4" onTablet="span6" onDesktop="span3">
<div class="box-header">
<h2><i class="halflings-icon white list"></i><span class="break"></span>Sectors</h2>
<div class="box-icon">
<i class="halflings-icon white chevron-up"></i>
</div>
</div>
<div class="box-content">
<ul class="dashboard-list metro">
</div>
</div><!--/span-->

Materialize collapsible inside modal doesn't remain open

I'm facing an issue with my collapsible, that make the collapsible-body to open/close several times very fast when I click on a collapsible-header element.
Here is the modal trigger:
<a class="btn modal-trigger" href="#myModal">Trigger</a>
Here is my modal structure: (note the use of ng-repeat, not sure if it might be linked)
<div id="myModal" class="modal">
<div class="modal-content" >
<ul class="collapsible" data-collapsible='accordion' watch>
<li>
<div class="collapsible-header">FOO</div>
<div class="collapsible-body">foo</div>
</li>
<li>
<div class="collapsible-header">BAR</div>
<div class="collapsible-body">bar</div>
</li>
</ul>
</div>
</div>
The script ending my HTML:
<script>
$(document).ready(function(){
$('.modal-trigger').leanModal({
ready: function(){
$('.collapsible').collapsible()
}
});
});
</script>
I've been browsing around without finding any related issue. Any help will be much appreciated (do not hesitate to ask for clarification).
Thanks Allan for your answer, Although it is not related to the height:
The modal automatically vertical-expands itselfs when item is opening.
Setting a large min-height doesn't solve my issue.

How do I get voice over focus to my modal?

I am using iphone 6+ and with the voice over (accessibility) option on. I have my exit modal open on a link click and I set my keyboard focus on the modal (with js). This all works fine. However, the voice over focus is not switched to my modal, it is still on the trigger link.
How do I get the voice over focus to the modal?
Here is the modal code
<div class="modal-container" id="{{ modalModel.modalId }}">
<div class="modal-mask" data-ng-click="onMaskClick($event)">
</div>
<div class="modal-body" tabindex="-1" role="dialog" aria-label="{{ modalModel.modalTitle }}">
<div class="modal-body-container">
<h4 class="modal-title heading-4">{{ modalModel.modalTitle }}</h4>
<button type="button" class="modal-close" data-ng-click="closeModal($event)">
<span class="btn-text">close</span>
<span class="icon chrome-blue-x-round"></span>
</button>
<div class="modal-contents">
<div class="modal-contents-wrapper" data-ng-transclude></div>
xxxxxx xxxx
</div>
</div>
</div>
</div>
The modal-body class element has focus when the modal pops up. I am using iOS 9.
I was able to focus the voice over cursor in the modal by putting the keyboard focus on the close button when the modal opens.
It appears if the keyboard focus is not on an element which the keyboard can focus on naturally, then the voice over cursor will not move inside of the modal. Since the close button is a button, this worked
<button type="button" class="modal-close" data-ng-click="closeModal($event)">
<span class="btn-text">close</span>
<span class="icon chrome-blue-x-round"></span>
</button>
You must focus on a focusable item. If you want to set it on something normally not focusable add tabindex=0. There are a couple other quick tricks to make VO read the entire modal. Add aria-labelledby="id_of_title" aria-describedby="id_of_content" don't use the hash '#'.

anchor tag pops up a div instead of a new page

I was wondering how to implement a popup div that had its own address. The example in question is the Chrome Extensions Store: https://chrome.google.com/webstore/category/extensions
If you click a tile on that site, not only will the content pop up in form of a div, but it'll also have its own address. So if I copy the address and paste it onto a new window, it goes to the same popup. Not only that, if you click back button (or backspace), it closes the pop-up div instead of going back to previous page.
If there is no simple way to implement this, I'd like to know what javascript object or something I'd have to learn about to do this.
I'm not sure if this is the right S.E. forum to ask, but I had to ask someone.
You can use bootstrap modal. It's very good
here is the code,
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
I didn't see the link you are talking about but I think they are hack the behavior of the link and instead of going to the clicked url show it'e content on an popup div. in jquery you can do it by something like preventDefault
If you click a tile on that site, not only will the content pop up in
form of a div, but it'll also have its own address. So if I copy the
address and paste it onto a new window, it goes to the same popup.
This is called stateless UI which can easily be achieved with for example router in Angular or Ember.
The idea is that every state in your application has its own address. If for example, your application has an entity user then the url to see a specific user would be
http://example.com/user/12345
Where 12345 is userId
At the same time to open an edit form for this object you might use
http://example.com/user/12345/edit
Irrelevant of when you get to the latter, your application will always open an edit form for user with id=12345
To understand this better you need to get acquainted with some principles of MVC and perhaps examine ui-router tutorial as an example of implementation

bootstrap 3 accordion collapse does not work on iphone

These "accordion submenus" work in chrome and firefox, but not on an iphone.
I have built a site which includes an "offcanvas" navigation menu on smaller screens. The user clicks "the hot dog button", and the navigation menu slides onto the screen from the left... that works great so far.
Some of the navigation elements contain submenus. For those, I used bootstrap's accordion markup. The user clicks an arrow, and the "submenu" expands.
The Problem
I develop using chrome on linux. This mechanism works perfectly in chrome, firefox, and every browser I can get my hands on, as well as on my personal android phone. It also works on responsinator.com. However, since I don't have Safari, nor an iPhone, I have not been able to test this functionality directly on an iphone. I am working on getting an iPhone emulator...
Until then, some other people have looked at this on an iPhone, and I am told the "submenus" do not work at all. When the user clicks the arrow, nothing happens...
Here is an excerpt of a "menu item" containing a "sub-menu": please note I am using the 'data-toggle' and 'data-target' attributes:
<div class="panel panel-default">
<!-- The "Trigger" -->
<div class="panel-heading">
<h4 class="panel-title">
<a href="view.php?cms_nav_id=1" name="about">
About</a>
<a data-toggle="collapse" data-target="#collapse1">
<i class="pull-right icon-chevron-right mobile-nav-icon"></i>
</a>
</h4>
</div>
<!-- Populated submenus: -->
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">
Ohio Improvement Process
</div>
<div class="panel-body">
Organization Beliefs
</div>
</div>
</div><!-- /.panel -->
I really don't know what to try next: Similar questions have ended with "a css conflict" or iphone problems regarding .click(), but I am not using that: I am using data-toggle/data-target. I am considering abandoning the 'data-target' markup in favor of manually invoking an on('click', ... ) event, but I would rather not...
By the way, I call this at the bottom of my page if that's relevant:
<script src="/assets/dist/js/bootstrap.min.js"></script>
Which is 'bootstrap.js v3.0.0' .
Does anyone have any other clues? Any recent direct experience with an issue like this?
Thanks in advance for your help.
So I think I figured this out: my original markup relied solely on the data-target element, but that is apparently not enough. Safari (on iPhone) seems to also need the href attribute (which really should be there on an <a> anyway. So this works:
<a data-toggle="collapse" data-target="#collapse1" href="#collapse1">
<i class="pull-right icon-chevron-right mobile-nav-icon"></i>
</a>
But this does not:
<a data-toggle="collapse" data-target="#collapse1">
<i class="pull-right icon-chevron-right mobile-nav-icon"></i>
</a>
For me, collapse would work on desktop and iphone, but some of my collapses were not working on ipads. It turned out that perfect solution for me was given by #Loris in #Ryan's answer, to add the pointer style to any collapsable trigger (e.g., a div acting as a button). I generalized this to the following CSS:
[data-toggle~="collapse"] {
cursor: pointer;
}
looking at this, I had the same problem, however, when you add a href="#collapse1", it jumps you to the top of the page. I fixed this by wrapping the element in a button and removed the css for buttons. So, your code would be:
<button data-toggle="collapse" data-target="#collapse1">
<i class="pull-right icon-chevron-right mobile-nav-icon"></i>
</button>
Hope this helps.
You can fix this by simply adding this attribute to the div that triggers the dropdown.
cursor: pointer;
This is working for me :
$('.divClassName').on('click touchstart', function () {
$($(this).data('target')).collapse('toggle');
});
To make this work for any element type, such as a div, you can use the following jQuery method (tested ios 8):
<div class="collapse-header" data-target="#collapse_0">
Click this element...
</div>
<div id="collapse_0">
...to collapse this element.
</div>
<script>
$('.collapse-header').on('click', function () {
$($(this).data('target')).collapse('toggle');
});
</script>
for further reference:
I did this in my application:
a[data-toggle="collapse"]{
cursor:pointer;
}
And it fixed the problem.
In the MDN documentation says this:
"Safari Mobile 7.0+ (and likely earlier versions too) suffers from a bug where click events aren't fired on elements that aren't typically interactive (e.g. ) and which also don't have event listeners directly attached to the elements themselves (i.e. event delegation is being used). See this live example for a demonstration. See also Safari's docs on making elements clickable and the definition of 'clickable element'"
References:
https://github.com/twbs/bootstrap/issues/16213
https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
Enabling the animation will cause some problems in IOS devices. Disable it and it will work. That was the case for me.
[isAnimated]="false"

Categories

Resources