I have javascript which ends up looking like this:
<input type="text" name="from" size="12" id="from" maxlength="12" value="" placeholder="dd-Mon-yyyy" class="hasDatepicker">
<img class="ui-datepicker-trigger" src="/img/calendar_icon_20x20.png" alt="" title="select start date" role="button" tabindex="0">
<input type="text" name="thru" size="12" id="thru" maxlength="12" value="" placeholder="dd-Mon-yyyy" dd-mon-yyyy'="" class="hasDatepicker">
<img class="ui-datepicker-trigger" src="/img/calendar_icon_20x20.png" alt="" title="select end date" role="button" tabindex="0">
but when tabbing through the page in Firefox, it skips from one <input> over the <img> and to the next <input>. It works perfectly in Chrome, Safari and Opera (all are current versions).
Any ideas?
As you've discovered, TabIndex is not implemented in a standard way. But, it is safe to say that it is only relevant on focusable elements. Image elements can't receive the focus.
From MDN:
The tabindex global attribute is an integer indicating if the element
can take input focus (is focusable), if it should participate to
sequential keyboard navigation, and if so, at what position. It can
take several values...
And, when you investigate HTML Global Attributes, you find the documentation telling us:
Global attributes are attributes common to all HTML elements; they can
be used on all elements, though the attributes may have no effect on
some elements.
Typically, tabindex is used on form elements (textboxes, checkboxes, radio buttons, buttons, etc.) to aid in the ability to navigate data entry.
Related
I am reworking on a code of an old developer and I'm trying to do a form for reservation.
I've looked across the whole code the only thing called reservation is the name and the id of the form.
Form who's is in style : display:none ...
So two question in one : First of all what the heck is supposed to do
document.reservation.submit(); Is it suppose to get the form by his name ?
Shouldn't it be something like document.getElementById('reservation').submit() instead ?
And my second question is : How the form can be sent if all the value are set to display:none I tough it couldn't work and if you want to hide them you shall use hidden property...
I need a bit of help on this guys pls :)
Form for beter comprehension :
<form name='reservation' action='http://xxxx/reservationFormAction.to' method="POST" id="reservation">
<input type="hidden" id="productLive" name="product" value="{$product.info.code}"/>
<input type="hidden" name="complementaryParameters" value=""/>
<input type="text" name="depCityCode" id="depCityCode" style="display:none" />
<input type="text" name="dateDep" id="dateDep" style="display:none" />
<input type="text" name="nightDuration" id="nightDuration" style="display:none" />
<input type="text" name="dayDuration" id="dayDuration" style="display:none" />
<input type="text" name="provider" value="{$product.tourOperator.code}" style="display:none" />
<input type="text" id="toProduct" name="toCode" value="{$product.info.toProductCode}" style="display:none" />
<input type="text" name="catalogCode" value="{$product.info.code}" style="display:none" />
{if $ecall}
<input type="text" name="reservationProfileChannelCode" value="ECALL" style="display:none" />
{else}
<input type="text" name="reservationProfileChannelCode" value="ADV" style="display:none" />
{/if}
<input type="text" name="nbAdults" id="nbAdults" style="display:none" />
<input type="text" name="nbChildren" id="nbChildren" style="display:none" />
<input type="text" name="nbBabies" id="nbBabies" style="display:none" />
<input type="text" name="productUrl" id="productUrl" style="display:none" value="http://www.xxxx.com/{$product.slug}_{$product.info.code}.html" />
<input type="text" name="homeUrl" id="homeUrl" style="display:none" value="http://www.xxxx.com" />
<span id="ageChild" style="display:none"></span>
<div class="update-search clearfix">
document.reservation gets the HTMLFormElement for the form with the name reservation. Then calling submit submits the form (without triggering the submit event).
So why not document.getElementById? That would also work, but document.reservation works because the document object gets various properties created on it automagically, including properties referring to forms by their name. This is covered in ยง3.1.3 of the HTML5 spec *(you have to scroll down a fair bit):
The Document interface supports named properties. The supported property names at any moment consist of the values of the name content attributes of all the applet, exposed embed, form, iframe, img, and exposed object elements in the Document that have non-empty name content attributes, and the values of the id content attributes of all the applet and exposed object elements in the Document that have non-empty id content attributes, and the values of the id content attributes of all the img elements in the Document that have both non-empty name content attributes and non-empty id content attributes.
The value of those properties is the element the name or id came from.
The window object also gets properties for every element with an id, as described here:
The supported property names at any moment consist of the following, in tree order, ignoring later duplicates:
the browsing context name of any child browsing context of the active document whose name is not the empty string,
the value of the name content attribute for all a, applet, area, embed, form, frameset, img, and object elements in the active document that have a non-empty name content attribute, and
the value of the id content attribute of any HTML element in the active document with a non-empty id content attribute.
Where again the value of those properties is the element the name or id came from.
In both cases, this is the HTML5 specification standardizing the previously-widespread-but-nonstandard practice most browsers had, which is widely used on pages in the wild.
How the form can be sent if all the value are set to display:none I tough it couldn't work and if you want to hide them you shall use hidden property...
It's best to ask one question per question.
The CSS display property has no effect at all on whether form fields are submitted; you're probably thinking of the field's disabled state: Disabled form fields are indeed left out of the form on submission.
the display none or hidden info will always be sent even that you can't see.... Usually we pass some info that the user doesn't need to know, like USER_ID=20 .....---- and the
document.reservation.submit
------- it submits the form with name="reservation"
For the following code, I'm able to type in any text in the input fields when I'm using firefox. However, the same does not hold true in IE11.
<li class="gridster-form"
aria-labeledby="Gridster Layout Form"
alt="Tile Display Input column Input Row">
<span class="dropdown-text">
Col <input type="text" value='tiledata.col' ng-model="tiledata.col" size="1" class="input-col ng-pristine ng-untouched ng-valid">
Row <input type="text" value='tiledata.row' ng-model="tiledata.row" size="1" class="input-row ng-pristine ng-untouched ng-valid">
<i class= "fa fa-arrows"></i>
</span>
</li>
How can I change this?
You have a structure like this: <a href...><input ... /></a>
This is NOT VALID
Since it is not valid, browsers are at liberty to try and make sense of what you meant. Firefox is giving the input elements priority and letting you use them. Internet Explorer is giving the link priority and not letting you use the child inputs.
Neither browser is correct as there is no correct answer.
Fix your HTML.
So, for example, here's a script:
<!-- Random content above this comment -->
<input type="text" tabindex="1" />
<input type="text" tabindex="2" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<!-- Nothing underneath this comment -->
So, when the user presses tab and goes through the six textboxes, reaches the last one and then presses tab, it would go to the content above the first comment, right? Well, how do I make it start from tabindex="1" again?
Unfortunately, you can't do that without javascript. You can listen to a TAB (and make sure it's not SHIFT+TAB) key press on your last element and manually set the focus to your first element inside the handler. However, binding this logic to keyboard events (i.e. specific input method) is not universal and may not work when using:
A mobile browser
Some other entertainment device (smart tv, gaming console, etc. - they typically use a D-Pad for jumping between focusable elements)
An accessibility service
I suggest a more universal approach which is agnostic of how the focus is changed.
The idea is that you surround your form elements (where you want to create a "tabindex loop") with special "focus guard" elements that are focusable too (they have a tabindex assigned). Here is your modified HTML:
<p>Some sample content here...</p>
<p>Like, another <input type="text" value="input" /> element or a <button>button</button>...</p>
<!-- Random content above this comment -->
<!-- Special "focus guard" elements around your
if you manually set tabindex for your form elements, you should set tabindex for the focus guards as well -->
<div class="focusguard" id="focusguard-1" tabindex="1"></div>
<input id="firstInput" type="text" tabindex="2" class="autofocus" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<input id="lastInput" type="text" tabindex="7" />
<!-- focus guard in the end of the form -->
<div class="focusguard" id="focusguard-2" tabindex="8"></div>
<!-- Nothing underneath this comment -->
Now you just listen to focus events on those guard elements and manually change focus to the appropriate field (jQuery used for the sake of simplicity):
$('#focusguard-2').on('focus', function() {
// "last" focus guard got focus: set focus to the first field
$('#firstInput').focus();
});
$('#focusguard-1').on('focus', function() {
// "first" focus guard got focus: set focus to the last field
$('#lastInput').focus();
});
As you see, I also made sure that we snap back to the last input when the focus moves backwards from the first input (e.g. SHIFT+TAB on the first input). Live example
Note that the focus guards are assigned a tabindex value too to make sure they are focused immediately before/after your input fields. If you don't manually set tabindex to your inputs, then both focus guards can just have tabindex="0" assigned.
Of course you can make this all work in a dynamic environment as well, when your form is generated dynamically. Just figure out your focusable elements (less trivial task) and surround them with the same focus guards.
Hope that helps, let me know if you have any issues.
UPDATE
As nbro pointed out, the above implementation has the unwanted effect of selecting the last element if one hits TAB after the page loads (as this would focus the first focusable element which is #focusguard-1, and that would trigger focusing the last input. To mitigate that, you can specify which element you want initially focused and focus it with another little piece of JavaScript:
$(function() { // can replace the onload function with any other even like showing of a dialog
$('.autofocus').focus();
})
With this, just set the autofocus class on whatever element you want, and it'll be focused on page load (or any other event you listen to).
Here my solution where you no need any other elements. As you can see elements will be looping inside <form> elements.
$('form').each(function(){
var list = $(this).find('*[tabindex]').sort(function(a,b){ return a.tabIndex < b.tabIndex ? -1 : 1; }),
first = list.first();
list.last().on('keydown', function(e){
if( e.keyCode === 9 ) {
first.focus();
return false;
}
});
});
Here is my solution, considering the first input has the "autofocus" attribute set:
Add this after your form element (with HTML5 it can be any tag):
<div tabindex="6" onFocus="document.querySelector('[autofocus]').focus()"></div>
Yes, after tabbing through the inputs it will jump on suitable elements that do not have a tab order specified. But also, after tabbing all "tabbable" elements, the focus will jump "outside" your page content, onto the browser's UI elements (tabs, menus, bookmarks, etc)
I think the easiest way is to handle the keyup event on the last input and intercept TAB usage (and SHIFT+TAB for that matter)
I wd suggest you to increase your tabindex ie. >100
and also give the tabIndex to your "content" container div
please note that your content container must have tabindex less than input boxes for ex.99 .
when you press tab on last input box manually set focus on your content div using javascript (you can use keypress handlers for tab key)
document.getElementById("content").focus();
you must giv tabindex to your "content" to set focus to it.
now if you press tab focus will automatically shift to first input box.
hope this will help.
Thank you
When I'm trying to disable dynamically, it's not disabled..
document.getElementById('selectId').disabled=true
document.getElementById('selectId').disabled=true. should be:
document.getElementById('selectId').disabled=true;
Some extra info because of the error in my first answer:
The disabled attribute can accept any value.
As long as this attribute is present, the element will be disabled regardless of its value.
<input type="text" value="This is disabled" disabled>
<input type="text" value="This is disabled" disabled="disabled">
<input type="text" value="This is disabled" disabled="true">
<input type="text" value="This is disabled" disabled="false">
<input type="text" value="This is not disabled">
Although in scripting, it is different.
document.formname.elementname.disabled = true; //disabled
document.formname.elementname.disabled = false; //enabled
The same is true for these attributes:
checked (radio button and checkbox)
selected (option)
nowrap (td)
As noted in this documentation for struts, the "disabled" attribute of a select element is of type "String", I would at least try putting .disable="disabled;" in your code and seeing if that works.
The other solution I've found to a Struts vs. HTML problem was here. The solution was to use the attribute theme='simple' in the element tag(your tag or one of it's containers in this case). That let HTML do its functions over Struts trying to do its functions when it comes to display. I suggest this answer because you may be having a behind-the-scenes issue where Struts doesn't like the HTML "disabled" attribute you are trying to use and it doesn't fire properly. So try adding theme='simple' (or some other theme) and see if anything changes.
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?