Controling tabbing focus within popup javascript widget context - javascript

I'm working on a lightbox style javascript plugin that pops up an image with next+previous buttons and a close button. I want to make it so that tabbing will only jump between the three presented buttons in the popup, not go through the three of them and then continue on the page content in the background.
Does anyone have any suggestions on the best way to do this, currently I'm thinking that the best way is to make an array of tabbable elements when the popup appears and just capture tabs to iterate through that array setting focus on each one and preventing default tab behaviour.
Anyone know if there are any best practices regarding this?

A possible solution seems to be setting the tabindex property of the elements you don't want to be tabbable to -1.
<div>
<input type="button" value="tabbable one" />
<input type="button" value="tabbable two" />
</div>
<div>
<input type="button" value="not tabbable" tabindex="-1"/>
<input type="button" value="also not tabbable" tabindex="-1"/>
</div>
Although I did not find this in any documentation so far it seems to work in all tested browsers (FF 3.5, IE 6 & 7, Opera 9.64).
Another approach would be to blur() when an unwanted element gets the focus:
<div>
<input type="button" value="tabbable one" />
<input type="button" value="tabbable two" />
</div>
<div>
<input type="button" value="not tabbable" onfocus="blur()"/>
<input type="button" value="also not tabbable" onfocus="blur()"/>
</div>
The disadvantage of this approach is that as soon as you hit an "untabbable" element, no element will be selected and the next tab will start at the very first element. This is especially tricky when tabbing backwards, which is not possible anymore. The solution to this would be to actively focus the correct following element:
<div>
<input id="firstTabbable" type="button" value="tabbable one" />
<input type="button" value="tabbable two" />
<input id="lastTabbable" type="button" value="tabbable three" />
</div>
<div>
<input type="button" value="not tabbable" onfocus="blur(); $('firstTabbable').focus();"/>
<input type="button" value="also not tabbable" onfocus="blur(); $('lastTabbable').focus();"/>
</div>
However, in my opinion this is a bit too complicated.

I tried doing the following when showing the popup window, it seems to work in Firefox 3. It may be enough to get you started:
$('#nonpopup a').attr('disabled','true');
$('#nonpopup input').attr('disabled','true');
The JQuery selector finds all the A and input elements that are in the div with id nonpopup and sets the html attribute disabled to true. If you are not using JQuery you will need some other way to find all these elements but it may be as simple as document.getElementsByTagName().
What this accomplishes is preventing the browser from tabbing to those elements. The tab order still leaves the page and goes all through the browser chrome, such as the URL bar.

Related

What event should I use?

My requirement is I have a textbox and after that I have button on the keypress of the tab from the textbox it should go to the button on next tab but am unable do it can anyone help me in solving this issue? My platform is asp.net mvc.
Using tabindex you can set the order of elements that receive focus by pressing the tab.
<!--Press tab on test1 to go to button-->
<input tabindex="1" id="test1" />
<input tabindex="3" id="test2" />
<button tabindex="2">MyButton</button>

Magento Theme adds product 2x to cart in IE (Javascript)

I've got a magento install with a custom theme that runs fine in Safari, Firefox and Chrome. In IE explorer all seems to work well too, it's just that when I add a product to cart it will add it 2x instead of just 1x.
I'm looking for someone with sufficient JS experience who would be able to help me with, or solve this problem.
To have a look. sbx.mujjo.com, on the frontpage hover a product thumbnail > click [quickview] > [add to cart].
Thanks!
<form action="http://sbx.mujjo.com/checkout/cart/add/uenc/aHR0cDovL3NieC5tdWpqby5jb20vY2F0YWxvZy9hamF4X3Byb2R1Y3Qvdmlldy9pZC8yNQ,,/product/25/" method="post" class="addcart-form" id="product_addtocart_form">
<fieldset>
<input type="hidden" name="product" value="25">
<input type="hidden" name="related_product" id="related-products-field" value="">
<div class="cell">
<label for="qty">Quantity</label>
<!--<input type="text" class="quantity-text" name="qty" id="qty" maxlength="12" value="1" title="Qty" /> -->
<input type="text" class="quantity-text" name="qty" id="qty" maxlength="12" value="1" title="Qty">
</div>
<button type="button btn-checkout" title="Add to Cart" class="button btn-cart" onclick="productAddToCartForm.submitLight(this)"><span><span>Add to Cart</span></span></button>
</fieldset>
</form>
I believe I know the problem, and it drives me nuts when people do this. As you can see from the code that I added to the question (once it's peer reviewed), it's pretty straight forward.
You have a normal form, with a few fields and a button.
The button has an onclick event productAddToCartForm.submitLight(this), which I assume submits the form.
What IE is doing is firing this javascript event and then reacting to the button being click. The reaction is to submit the form....hence the double up.
You can fix this in one of two ways:
change the onclick event to productAddToCartForm.submitLight(this); return false; which tells the browser to stop any extra processing of the click event
change the button to a href tag - something like
<a href="javascript:void();" onclick="productAddToCartForm.submitLight(this);"`
Edit:
Forgot to mention one thing, this should still work in Safari, Chrome and FF

Tab Ordering for Javascript "Buttons"

I'm trying to create an HTML form (using JSP) which contains Javascript buttons (rather than actual HTML buttons). Everything works great except that I'm unable to tab to the -based Javascript button after the last tabindex.
For example:
<li class="lineItem">
<f:label path="ownerPostalCode">Postal Code<em>*</em> </f:label><br />
<f:input path="ownerPostalCode" type="text" id="ownerPostalCode"
class="required" size="15" maxlength="5" value="" tabindex="16" />
</li>
<li class="lineItem">
<f:label path="ownerPostalCodeFour">+4</f:label><br />
<f:input path="ownerPostalCodeFour" type="text"
id="ownerPostalCodeFour" size="5" maxlength="5" value="" tabindex="17"/>
</li>
<span class="buttonRow">
<span class="clearButton" onclick="resetFields
('registrationForm', 'ownerInfoSection')">Clear Fields</span>
<span id="continueButton" class="greenButton" tabindex="18"
onclick="stepOneToStepTwo()">Continue</span>
</span>
</span>
I understand that tabindex only works with certain input fields (A, AREA, BUTTON, INPUT, OBJECT, SELECT, and TEXTAREA)--as such, the specification of "tabindex='18'" for the #continueButton doesn't work. The desired behavior is that after tabbing to the "ownerPostalCodeFour" field, the user can tab to the #continueButton as one would with a normal button.
Is this at all possible or am I forced to utilize standard HTML buttons to achieve this behavior?
Thanks.
Not sure what browsers you are supporting, but tabindex="0" works in latest webkit/Firefox/IE. From an accessibility standpoint, using spans is less than optimal though. Why not at least use an <a> tag?

Pressing "Return" in a HTML-Form with multiple Submit-Buttons

Let's imagine a HTML-form with with two submit buttons. one of them is positioned in the upper half of the form and does something less important. the other button is the actual submit button, which saves the entered data. this button is positioned at the end of the form. the two buttons will trigger different action-urls.
experienced users like to submit their forms by pressing "enter" or "return" instead of clicking on the according button.
unfortunately, the browser will look for the first submit-button of the current form and use this to execute the form-submit. since in my form the second button is the actual submit-button, i need to tell the browser to use this particular button (or the action-url that is associated with it).
i don't link javascript listeners, which are looking for key pressed or something like that. so i'm looking for a better approach to this problem. however, javascript or jquery solutions (without keypressed-listerner) are welcome.
thank you very much for your help in advance.
change your first button to a <input type="button" />.
You could, theoretically at least, have three submit buttons in your form.
Button two is the existing 'less-important' button (from halfway down the form), button three is the existing 'actual-submit' button from your existing form.
Button one should be hidden (using CSS display:none or visibility: hidden) and should perform exactly the same function as your current 'actual-submit.' I think it'll still be the first button to be found by the browser, regardless of its visibility.
<form method="post" method="whatever.php" enctype="form/multipart">
<fieldset id="first">
<label>...<input />
<label>...<input />
<label>...<input />
<input type="submit" value="submit" style="visibility: hidden;" <!-- or "display: none" --> />
<input class="less_important" type="submit" value="submit" />
</fieldset>
<fieldset id="second">
<label>...<input />
<label>...<input />
<label>...<input />
<input type="submit" value="submit" class="actual_submit" />
</fieldset>
</form>
Edited in response to comments:
I thought hidden buttons were also disabled by default? [md5sum]
A valid point, but I made the mistake of testing only in Firefox (3.5.7, Ubuntu 9.10) before posting, in which the technique worked1, for both. The complete xhtml file is pasted (below) that forms the basis of my testing subsequently to these comments.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>3button form</title>
<link rel="stylesheet" type="text/css" href="css/stylesheet.css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
$('input[type="submit"]').click(
function(e){
alert("button " + $(this).attr("name"));
}
);
}
);
</script>
</head>
<body>
<form method="post" method="whatever.php" enctype="form/multipart">
<fieldset id="first">
<label>...<input />
<label>...<input />
<label>...<input />
<input name="one" type="submit" value="submit" style="display:none;" /><!-- or "display: none" -->
<input name="two" class="less_important" type="submit" value="submit" />
</fieldset>
<fieldset id="second">
<label>...<input />
<label>...<input />
<label>...<input />
<input name="three" type="submit" value="submit" class="actual_submit" />
</fieldset>
</form>
</body>
</html>
display: none should prevent a button from being an active part of the form (included in the result set, and eligible for default-button-ness); visibility: hidden should not. However both of these cases are got wrong by some browsers. The normal way to have an invisible first submit button is to position: absolute; it and move it way off the page (eg. with left: -4000px). This is ugly but reliable. It's also a good idea to change its tabindex so it doesn't interfere in the expected form tabbing order.
There are, at least, two points I have to raise to this comment. In order:
"The normal way..." I was unaware that there was a normal way, and presented this option as a possibility to achieve an aim, in the full knowledge that there were/are almost certainly any number of better ways, particularly given that I don't see a good reason for multiple submit buttons on the same form.
Given the latter sentence of the above point, I'd like to make it clear that I don't advocate doing this. At all. It feels like an ugly, and non-semantic, hack to have more than one submit button, with -in the OP's instance- one button apparently not being a submit button.
The notion of `position: absolute; left: -4000px;` had occurred to me, but it seemed to effect much the same as `visibility: hidden;`, and I have an innate dislike of `position: absolute;` for whatever reason...so I went with the option that was less objectionable to me at the time of writing... =)
I appreciate your comment about the tabindex, though, that was something that I never gave any thought to, at all.
I'm sorry if I sound somewhat snippy, it's late, I'm tired...yadda-yadda; I've been testing in various browsers since my return home and it seems that Firefox 3.5+ gives the same behaviour -reporting 'button one' on both Windows XP and Ubuntu 9.10, all Webkit browsers (Midori, Epiphany, Safari and Chrome) fail and report 'button two.'
So it's definitely a fail-worthy idea to display: none; the submit button. Whereas the visibility:hidden at least works.
By which I mean that hitting 'enter' triggered the form-submit event, or the click event of the first submit button of the form, regardless of whether that first submit was `display: none;` or `visibility: hidden`.
Please be aware that my jQuery skills are limited, so the tests employed (I ran only at a time to try and prevent conflicts occurring in execution, commenting out the one I didn't run at that time, both are presented -one, clearly, commented out) may well be insufficient and non-representative.
What does the first button do? If you just need a button to attached a js listener to, which doesn't submit, use
<button type="button" id="myButton">Text Here</button>
Is it an option to use absolute positioning on your less important submit button and have it appear after your primary submit button in the HTML? So, you can have:
<form>
<p>
Stuff
<input type="submit" value="This is my main submit button" />
<input type="submit" value="This is my secondary submit button" style="position: absolute; left: 0px; top: 0px; />
</p>
</form>
Your secondary submit button will appear first on the screen, but the primary submit button should take precedence when enter is pressed.
<script>
$(function(){
$('#button-new-captcha').click(function(){
$('input[name=button-submit]').prop('name', 'button-new-captcha').click();
});
});
</script>
<div class="buttons">
<a class="btn btn-cancel" href="/login">Cancel</a>
<a class="btn btn-default" href="#" id="button-new-captcha">New Image</a>
<input type="submit" name="button-submit" class="btn btn-default" value="Send Username">
</div>
Another workaround is to create an extra non-functional submit input at the very beginning of the form and hide it using opacity:
<input type="submit" value="" onclick="return false;" style="opacity: 0">
The button will still be rendered on the page, albeit transparent, so you will have to provide some real estate for it. Alternatively you could play with pushing it behind another element using z-index or rendering it outside the page as others have suggested here before.
What you gain with onclick="return false;" is that the form will not be submitted when hitting "Enter" anymore; no page reload, either.

How to focus radio control using Javascript in IE?

Given the code below:
function test() {
document.forms[0].TEST[0].focus();
}
<form>
<input type="button" value="Test" onclick="test()" />
<input type="radio" name="TEST" value="A">A
<input type="radio" name="TEST" value="B">B
</form>
In IE6, clicking the button doesn't focus the control, unless I've already tabbed through the radio at least once, in which case it works. =/
Any idea how I should be focusing the control? The above works perfectly fine in FF of course.
Edit: I found that the control is being focused, except the highlight box around the radio button is not being rendered. (I can hit space to activate the radio button, and also use arrow keys to change the active button). So the question becomes: how can I force the focus highlighting box to render?
Actually it's focussing, you can test it by focusing the second item and after clicking the button click space, you can see the second item selected. This shows the items are getting focus but I think you mean the dashed selection after focus. I don't know how to do that.
There's an option in the Accessibility Advanced Options of Internet Explorer that says something like "Move the system cursor with selection or focus". It might be a solution if you have a way to propagate IE settings.
edit: it doesn't work
You can force any style for the focus' outline
function test() {
document.forms[0].TEST[0].focus();
}
/* if this CSS rule is overrode by another one, then strengthen the selector of this rule to make it more specific (or use "!important") */
input[name=TEST]:focus {
outline: 1px dotted blue;
}
<form>
<input type="button" value="Test" onclick="test()" />
<input type="radio" name="TEST" value="A" />
<input type="radio" name="TEST" value="B" />
</form>

Categories