I am trying to make a large form more friendly. There are a number of fields which are used in special cases and these are hidden inside an accordion container with links to expose them if desired.
However (at least in Chrome) if you tab through fields you'll end up with focus on fields that are hidden from view but accessible to keyboard input.
What would be a Good™ way to handle this? Use jQuery to set tabindex based on display != none and then re-set when accordion events occur? Maybe when a field hidden by CSS receives focus the enclosing accordion is opened?
Here is a jsfiddle demonstrating the issue using the html below. Tab goes from visible to accordion link to hidden text input and out to last visible: http://jsfiddle.net/2EfXM/
<p class="file_info">
<label>Visible
<input type="text" name="vis1" id="vis1" class="date" value="" />
</label>
</p>
<div class="accordion" id="accordion2">
<div class="accordion-group">
<div class="accordion-heading"> <a class="accordion-toggle accordion-arrow" data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
Show more fields
</a>
</div>
<div id="collapseOne" class="accordion-body collapse out">
<h5>Source/Use Metadata</h5>
<p class="file_info">
<label>Hidden:
<input type="text" name="default_original_source" id="default_original_source" class="" value="" />
</label>
</p>
</div>
</div>
</div>
<p class="file_info">
<label>Visible
<input type="text" name="vis2" id="vis2" class="date" value="" />
</label>
</p>
An interesting side note: using display:none
then broke jQuery validate in IE 9. It threw errors on the hidden fields:
SCRIPT5007: Unable to get value of the property 'call': object is null or undefined
jquery.validate.js, line 1174 character 5
After some research this was the final solution:
.collapse input {
visibility: hidden;
}
.collapse.in input {
visibility:visible;
}
Your main issue is that the code needs to set a visibility: hidden
(note: originally I had display: none
, but that created form validation issues per the OP's comment below) to the collapsed element. With visibility: hidden
, the tabbing is ignored (because the element no longer has visibility in the document).
The code in your previous fiddle just sets the height: 0
. This modified fiddle adds some CSS to control the visibility
as well:
.collapse input {
visibility: hidden;
}
.collapse.in input {
visibility: visible;
}
It is functioning as you desire.