Accessibility - lost focus, should I force focus next focusable? - javascript

I am creating big form and would provide button navigation between sections for accessibility.
It means that you could expand/collapse next or previous section by buttons navigation.
However, when you switch section, current section is hidden (and next one is showed) by display CSS property, so just used button is anymore focused as it's not visible.
Take a look on this JSFiddle or code below to understand issue.
HTML:
An anchor
<article>
<header>First box</header>
<main>
This is first box.
<label><input type="radio" class="focusable" />This is input</label>
<button class="next focusable">Next box</button>
</main>
</article>
<article class="box-hidden">
<header>Second box</header>
<main>
This is second box.
<button class="focusable">Extra button</button>
<label><input type="radio" class="focusable" />This is input</label>
<button class="prev focusable">Previous box</button>
<button class="next focusable">Next box</button>
</main>
</article>
<article class="box-hidden">
<header>Third box</header>
<main>
This is third box.
<label><input type="radio" class="focusable" />This is input</label>
<button class="prev focusable">Previous box</button>
</main>
</article>
An anchor
CSS:
.box-hidden main {
display: none;
}
/* Only cosmetic below */
article { background: #ddd; margin: 10px 0; }
header { background: #ccc; }
button:focus { outline: 2px solid blue; }
JQuery:
$( 'body' ).on('click', '.next', function( event ) {
event.preventDefault();
var next = $( this ).closest( 'article' ).next( 'article' );
$( 'article' ).addClass( 'box-hidden' );
$( next ).removeClass( 'box-hidden' );
});
$( 'body' ).on('click', '.prev', function( event ) {
event.preventDefault();
var prev = $( this ).closest( 'article' ).prev( 'article' );
$( 'article' ).addClass( 'box-hidden' );
$( prev ).removeClass( 'box-hidden' );
});
When you use next or previous button, focus is lost and you have to start again from page begin. It can't happen.
My solution is to find closest focusable (it sucks, because I use class due first focusable could be input either another button) in opened section and focus it:
JSFiddle or add to JQuery:
$( next ).find( '.focusable' )[0].focus();
At end of both functions, analogously replace $( next ) to $( prev ) in second one.
So it will look like:
//[...]
$( next ).removeClass( 'box-hidden' );
$( next ).find( '.focusable' )[0].focus();
});
But I am not sure is it right way, isn't it confuse user navigating by focusable elements?
Maybe I should do it another way?
Note: Buttons are appended by JS, so non-JS users just dont't use them.
Thanks in advance for advices!

I believe you have uncovered a usability issue, not an accessibility issue. I would replace the next and previous buttons with expand/collapse toggles for these sections. This would immediately solve your accessibility issue (because these buttons would always be visible) and it would be a UI model that users are familiar with and solve (what I believe to be) a non-standard and confusing interaction model.
Here is your JSfiddle updated for this implementation (you can probably find better icons than I used) http://jsfiddle.net/zwLLrg9d/7/
I also changed this so that there is correct use of sectioning content. Multiple instances of a <header> element are definitely not recommended.

Related

Make li item boxes pop out in order jQuery

I have a footer list:
<footer id="footer">
<ul>
<li>
<h2> x </h2>
<h3> xx </h3>
<p>xxx</p>
<p> xxxx </p>
</li>
<li>
<h2> x </h2>
<h3> xx </h3>
<p>xx </p>
<p> xx </p>
</li>
<li>
<h2> x </h2>
<h3> xx </h3>
<p>xx</p>
<p> xxx</p>
</li>
</ul>
</footer>
that pops out on click to two separate links, like so:
$(document).ready(function() {
$( "#add" ).click(function() {
$( "#footer" ).toggle( "fast" );
});
});
$(document).ready(function() {
$( "ul li:eq(3)" ).click(function() {
$( "#footer" ).toggle( "fast" );
});
});
I would like these ul boxes, after their current popout link is clicked, to either fill with content one after the other in order, or have the boxes themselves pop out one at a time. Input wherever I can do better is helpful as well; I'm a rookie. Bonus: how to have the boxes revert in order when those two links in question are clicked again to close? Thanks all.
edit: the two links that pop out the footer are here, the contact link and the phone image:
<section id="side">
<nav class="sidebar"><img class="logo" src="images/logo.png"></img>
<ul>
<li> About </li>
<li> Providers </li>
<li> Quality </li>
<li> Contact </li>
</ul>
<img id="add" src="images/phoner.png"></img>
</nav>
</section>
Something like this maybe?
$(document).ready(function() {
var $footer = $("#footer").hide(),
$footerItems = $footer.find("ul li").hide(),
footerState = 0;
$("#add, .sidebar ul li").click(function (e) {
e.preventDefault();
footerState = !footerState;
var method = footerState ? 'show' : 'hide';
if(footerState) $footer.show();
$footerItems.get().reduce(function (p, li) {
return p.then(function() {
return $(li)[method]('slow').promise();
});
}, $.when()).then(function() {
if(!footerState) $footer.hide();
});
});
});
DEMO
https://jsfiddle.net/m173gxvg/3/
Something like this? If yes, here are the modifications:
Remove the display:none from the footer css
Add the display:none to the footer ul li css
Modify the javascript code
Here's the js to use after the click:
toggleTimer=500;
$( "#footer" ).find("ul").find("li").each(function() {
jQuery(this).toggle(toggleTimer);
toggleTimer=toggleTimer+500;
});
I think you want to click on each one and then show the next one, is that right?
Then you can use the .next() jquery property to assign the click listener to toggle the next element.
$(document).ready(function() {
//start with all LI hidden
$('#footer').find('li').hide();
//add click listener to the id='add' element to toggle the first LI
$( "#add" ).click(function() {
//if none are visible, show the first one, else hide them all
if ($('#footer').find('li').first().css('display') == 'none' ) {
//show the fist LI
$( "#footer" ).find('li').first().toggle( "fast" );
} else {
//hide them all
$('#footer').find('li').hide();
}
});
//add listener to each LI to toggle the NEXT one
$('#footer').find('li').click(function(){
$(this).next().toggle("fast");
});
});
... after your comment...
OR You can show the FIRST hidden one on each click like this:
$(document).ready(function() {
//start with all LI hidden
$('#footer').find('li').hide();
//add click listener to the id='add' element to toggle the first LI
$( "#add" ).click(
function() {
//if NO LI are hidden, hide them all, else show one at a time
if ( $('#footer').find('li:hidden').size()==0 ) {
//hide them all
$('#footer').find('li').hide();
} else {
//show the first hidden LI
$('#footer').find('li:hidden').first().show('fast');
}
}
);
});
Is that what you're looking for?

Divs hiding and showing in a sequential order

I am creating a checkout page and I am structuring it so it is three steps.
Shipping info
Payment
Order confirmation
I am wanting to create this so they sequentially display with only one displaying one at a time. What I have created so far is using the toggle method approach and it somewhat does what I want with making the divs show and hide, but I am wanting this in a more sequential manner, meaning they can't get to step two without completing step 1.
The toggle approach is also an issue in the regards that if I hit button 2, I have hit that button again for it to go away.
Also with toggle approach I created, the shippinginfocontainer (Shipping Info), it never goes away. It always displays. I tried adding display: none to the CSS portion of it, but then it never displays.
The toggle approach is working and is not broken. I am looking for other solutions to possibly add to this to gain the desired effect of making this sequential and not having to "untoggle" a div.
Also I am unable to get the 1st div container (shipping info) to disappear when going to a different div.
$( '#button1' ).click(function() {
$( '.shippinginfocontainer. ).toggle( "slow" );
});
$( '#button2' ).click(function() {
$('.paymentinfocontainer' ).toggle( "slow" );
});
$( '#button3' ).click(function() {
$( '.confirmationinfocontainer' ).toggle( "slow" );
});
The jsfiddle still doesn't display how I created it. It is only my second time using it...sorry. I just thought it would be an easier way to read the code.
Fiddle
Edited...
Here is my code
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#hide1").click(function(){
$("#p1").show();
$("#p2").hide();
$("#p3").hide();
});
$("#hide2").click(function(){
$("#p1").hide();
$("#p2").show();
$("#p3").hide();
});
$("#hide3").click(function(){
$("#p1").hide();
$("#p2").hide();
$("#p3").show();
});
});
</script>
</head>
<body>
<p id="p1">Hey there, its me urs truly p1.</p>
<p id="p2">Hey there, its me urs truly p2.</p>
<p id="p3">Hey there, its me urs truly p3.</p>
<button id="hide1">Button1</button>
<button id="hide2">Button2</button>
<button id="hide3">Button3</button>
</body>
</html>
i have updated your code on jsfiddle kindly check it.
$(function(){
$( '#button1' ).click(function() {
$( '.shippinginfocontainer' ).toggle( "slow" );
});
$( '#button2' ).click(function() {
$('.paymentinfocontainer' ).toggle( "slow" );
});
$( '#button3' ).click(function() {
$( '.confirmationinfocontainer' ).toggle( "slow" );
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="spancenter"><p>Easy three step ordering process</p></span>
<ul class="checkoutmenu">
<button class="checkoutbutton" id="button1">1. Shipping Information</button>
<button class="checkoutbutton" id="button2">2. Payment Information</button>
<button class="checkoutbutton" id="button3">3. Order Confirmation</button>
</ul>
<div class="shippinginfocontainer">HELLO DUMMY</div>
<div class="paymentinfocontainer">HELLO DUMMY</div>
<div class="confirmationinfocontainer">HELLO DUMMY</div>
Regards
Try this code ::
$('#button1').click(function(){
$(".paymentinfocontainer, .confirmationinfocontainer").hide("slow");
$(".shippinginfocontainer").show("slow");
});
$('#button2').click(function(){
$(".shippinginfocontainer, .confirmationinfocontainer").hide("slow");
$(".paymentinfocontainer").show("slow");
});
$('#button3').click(function(){
$(".paymentinfocontainer, .shippinginfocontainer").hide("slow");
$(".confirmationinfocontainer").show("slow");
});
CHECK FIDDLE HERE
OR
Try it also : Tested working successfully
<button class="checkoutbutton" onclick="showhide('shippinginfocontainer');" id="button1">1. Shipping Information</button>
<button onclick="showhide('paymentinfocontainer');" class="checkoutbutton" id="button2">2. Payment Information</button>
<button onclick="showhide('confirmationinfocontainer');" class="checkoutbutton" id="button3">3. Order Confirmation</button>
function showhide(show) {
var y = ['shippinginfocontainer','paymentinfocontainer','confirmationinfocontainer'];
y.splice( $.inArray(show, y), 1 );
for(var i=0;i<=y.length;i++) {
$("."+y[i]).hide("slow");
}
$("."+show).show("slow");
}

jquery hide not working for same div class after ajax call?

1.This is my code here i have a div class inner which is dynamically loaded using ajax call
and after ajax call if i click the hide button it is not working.
But its working perfectly before ajax request.
so in order to overcome i just add a outer div and hide that div this time it works..
I don't know why?
$( "#inner" ).replaceWith( data ); /*and*/ $( "#inner" ).hide(); //not working
$( "#inner" ).replaceWith( data ); /*and*/ $( "#outer" ).hide(); //working
Why we cant use the same div class ?
<html>
<div id="outer">
<div id="inner">
<br /> <br /> <br />
<div> <input type="button" value="signup" onclick="changeval();"/>
</div>
<br /> <br />
</div>
</div>
<input type="button" value="hide" onclick="onhide();"/>
<script language="javascript">
function changeval(context)
{
var typeval="sdsf";
var url="sdfsdf";
$.ajax({
type:'POST',
url:'htp://sscs/registration',
data:'&typeval='+typeval+'&url='+url,
success:function(data) {
$( "#inner" ).replaceWith( data );
}
});
}
function onhide()
{
$( "#inner" ).hide();
}
</script>
Use .html()
$("#inner").html(data);
instead of .replaceWith() as
Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed.
DEMO of replaceWith, Here you can see div with second class is replace with input content.
It doesn't work because you replace the <div id="inner">.
Including the div and its ID. <div id="outer"> remains so your other hide works, it still finds that div.
Use like this:
$( "#inner" ).replaceWith( function(){
return $(this).data();
} );
After your ajax call the #inner-div does not exist anymore. You are replacing it with the response from your ajax request .
You could use $("#inner").html(data); to keep the div and then hide it once you received the response.

Simply function to separte buttons

I have very basic problem, actually it's look Here. I want to separate two buttons.
jQuery
$( "span" ).click(function() {
$( "p" ).toggle( "slow" );
});
HTML
<span>↓ Hobby </span>
<p class="contentDiv" >Such interesting text, eh?</p>
<br> <br>
<span>↓ Sport </span>
<p class="contentDiv" >Such interesting text, eh?</p>
I was trying by getElementById but it doesn't work.
I'm beginner, be patient.
When you are using $('p') you are selecting all p elements, you need to specify like this
$( "span" ).click(function() {
$(this).next().toggle();
});
Try this.
$( "span" ).click(function() {
$(this).closest('p').toggle();
});

How to detect content change event on a div

I am trying to make an editor everything working fine till now, but now I need to make a handler which could detect any change made in a div or any content edited in the div
<?php $row="testing content" ?>
<!-- my editor section-->
<div id="editor">
<div id="options">
<span><a id="iimg">Insert Image from gallery</a></span>
<span>Upload image to gallery</span>
<span><a id="iheading">Heading</a></span>
</div>
<div id="product_descriptioncontent" contenteditable="true"><?php echo $row; ?>
</div><!-- viewable editor -->
<input type="hidden" name="textareacontent" value="" id="textareacontent" >
<!-- hidden field to submit values -->
</div>
<!-- end of editor section -->
<div id="imc"></div> <!-- image gallery loading section -->
<script>
$(document).ready(function(){
$('#iheading').click(function(){
$('#product_descriptioncontent').append('<h1>Heading</h1>');
});
$('#iimg').click(function(){
$('#imc').load('imagegallery.php',function(){
$('#gallery img').on('click',function(){
$('#product_descriptioncontent').append('<img src="http://localhost/sites/site_pics/otherpic/1.png"><br> ');
});
});
});
$('#product_descriptioncontent').change(function(){
alert("pppp");// how to capture this event
});
});
</script>
I have placed a bit of my code at jsfiddle http://jsfiddle.net/bipin000/UJvxM/1/
thanks for your precious time
Try adding a handler for DOMCharacterDataModified. Might be a cleaner solution.
Do you like this? http://jsfiddle.net/Ralt/hyPQC/
document.getElementById( 't' ).onkeypress = function( e ) {
var evt = e || window.event
alert( String.fromCharCode( evt.which ) )
}​
It's not waiting for a change event, it's kind of pointless.
Instead, it's listening to the onkeypress event. Everytime a user changes the content of this div (by adding a character to it), it triggers the event.
You can also see how to get the character clicked (using String.fromCharCode( evt.which )).
PS: a full jQuery solution for your specific case would be this:
$( '#product_descriptioncontent' ).on( 'keypress', function() {
$( '#your-hidden-input' ).val( $( this ).text() )
// Or
$( '#your-hidden-div' ).text( $( this ).text() )
} )
You can bind a custom event to the div and trigger that event upon change
Demo in Stack Snippets and jsFiddle:
$(function() {
$('#wrapper').bind("contentchange", function() {
console.log("Captured content change event");
});
$("#btn").click(function() {
$('#wrapper').html("new value").trigger("contentchange");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="wrapper"></div>
<input type="button" id="btn" value="click here">

Categories