I'm creating a multiple choice question exercise and am having issues with keyboard accessibility. Basically, the user is not able to cycle through the list of radio buttons through the keyboard. When the "focus" cursor is over a radio button and the user pressed the arrow key to move onto the next radio button a keyboard trap occurs. Instead of simply focusing it, the radio button is selected instead and thus the answer is displayed. How can I stop radio buttons being selected when going through them with the keyboard?
HTML markup:
<div id="contentWrapper">
<p class="instructions">Click on the correct answer.</p>
<ol start="49">
<!-- Start of multiple choice question -->
<li class="multipleChoice gradedQuestion">
<p class="question">If you receive a request for an extension from a trader, you should:</p>
<input type="hidden" name="questionNumber" value="49">
<ul>
<li>
<div class="answerOption"><label for="question49A">Refer to IP 13; if the original requirements are still being met, approve the extension.</label></div>
<div class="inputAndIdContainer"><input type="radio" name="question49" value="0" id="question49A"> A.</div>
</li>
<li>
<div class="answerOption"><label for="question49B">Refer to IP 20; if the original requirements are still being met, approve the extension.</label></div>
<div class="inputAndIdContainer"><input type="radio" name="question49" value="0" id="question49B"> B.</div>
</li>
<li>
<div class="answerOption"><label for="question49C">Refer to FW1; if the original requirements are still being met, approve the extension.</label></div>
<div class="inputAndIdContainer"><input type="radio" name="question49" value="1" id="question49C"> C.</div>
</li>
</ul>
<div class="feedback">
<div class="answeredCorrectly">Correct</div>
<div class="answeredIncorrectly">Incorrect</div>
<div class="answer">
<strong>Answer:</strong> C - Refer to FW1.
</div>
</div>
</li>
<!-- End of multiple choice question -->
Short answer is you can't, and this isn't a keyboard trap. That is the nature of a radio.
If they are grouped together (name attribute), you tab into it; by pressing space you select the first item, by using the arrow keys it selects the next item. You should write your JS to watch for focus to enter the group and then leave. Once left, show <div id="feedback"> or make a button to show it.
Edit Regarding your other post, you probably need to add a .focus() function that is similar to .click().
That's the way they should work, take a look at this document!
Basically it's this:
On IE, when a radio button group is reached via tabbing, the initially selected button is focused on, and the dotted rectangle indicates this. You can use arrow keys to move between the buttons inside the group; both "down" and "right" arrow move forward inside the group, and both "up" and "left" arrow move backward. And upon moving to a button, that button gets checked (and the button in the group that was checked gets unchecked).
On Netscape, things are different. When a set of radio buttons is reached via tabbing, the first button receives focus. You can move forward inside the group by tabbing. Moving to a button that way does not change the setting. Use the space bar or Enter key to check a button.
I solved this problem by blurring the input after it's been clicked.
At least with this way if you are navigating using tab/space/arrow keys it will not mess with the user. If they click it's very unlikely they will be using arrow keys to select the next option.
Jquery:
$('.quiz input:radio').click(function(){ $(this).blur()})
Related
I have a form group that has several form controls within it, including a toggle switch. The toggle switch changes a boolean value in the model to true or false. Dependent upon the value, there is an *ngIf that handles if form controls are displayed or not. This all currently works fine, however I have a requirement to actually basically clone the entire form group, which I have achieved. However, the toggle switch only works on the first form group, and none of the rest. And actually, if I click the toggle on the others it actually toggles just the first one on and off...what am I missing here?
Here is how it looks, I actually clicked the 2nd toggle switch:
The model has this value:
advancedOptions: boolean;
The template is like so:
<div class="advancedOptions">
<div class="service-group jbh-toggle">
Advanced Options:
<label class="toggleLabel inline-block" for="inbond-freight">Hide</label>
<input class="jbh-toggle-checkbox ng-untouched ng-valid ng-dirty" #advancedOptions id="handlingUnitAdvancedOptionsToggle" type="checkbox"
(change)="handlingUnitAdvancedOptionsToggle(advancedOptions.checked)">
<label class="jbh-toggle-label" for="handlingUnitAdvancedOptionsToggle">
<span class="jbh-toggle-inner" id="span-toggleInner3"></span>
<span class="jbh-toggle-switch" id="span-toggleSwitch3"></span>
</label>
<label class="toggleLabel inline-block" for="handlingUnitAdvancedOptionsToggle">Show</label>
</div>
</div>
The *ngIf is simply:
<div *ngIf="advancedOptions"></div>
All the other controls work fine in the duplicated form group, except for the toggle switch.
You can use your formcontrol value of toggle switch like when it's value is true then you can show/hide like below
form.controls.default_checkbox.value != 1
I have something like this control:
I need to track focus on any element inside this control. If I focus input or If I focus (click) calendar icon, I want to know that focus performed.
My idea is to add click listener on wrapper of input + calendar trigger. It is some div.
Out of the box I can't add focus listener to the div. To achieve this I need to add tabindex=0 to this div. This method will work, but it has one minus.
For example, I have form with many controls. Example code is below:
<div class="container">
<input onfocus="onFocus()" />
<div tabindex="0" onfocus="onFocus()">some div</div>
<div tabindex="0" onfocus="onFocus(event.target)">
<input onfocus="onFocus()" />
</div>
<input onfocus="onFocus()" />
</div>
When I focus first input and start looping through TAB key I want this behavior: focus calendar icon, focus next input, focus next calendar icon etc. But with tabindex=0 I break this behaviour. You can check it in this pen. You can see this broken behaviour after some div block.
Well, I have another option to add listener specifically for input and calendar icon (or any other icon). The problem is I have dynamic amount of icons on each field. And I have to add focus listener for each. Much simpler for me (and another developers) is the way when I have only one focus listener on the top (as I think).
Is it somehow possible to add ability to add focus listener to the div without breaking focus loop (like I shown on the codepen example).
Use element.addEventListener('focusin', handler). focus and blur don't bubble, focusin and focusout do.
document.querySelector('.container')
.addEventListener('focusin', function(event) {
console.log(event.target)
})
<div class="container">
<input name="a" />
<div contenteditable="true">some div</div>
<div>
<input name="b" />
</div>
<input name="c"/>
</div>
I am using Angular.js for the following project. Using a template document, the
application renders paragraphs using user-input in a fill-in-the-blanks style.
So there are fields that the user must fill, let’s call them Blanks. Those
fields, inside the paragraphs, are highlighted so the user knows they can
interact with them. They can be of type date, email, text or
radio select. When they are clicked, I want to display, next to the
paragraph, a little panel containing a description of or instructions on how to
fill the field followed by the form element.
I would like to use a readable format for the HTML templates so I can mix
regular text with Blanks. I was thinking of using attributes on div elements
to specify the description of the element and the placeholder or the default option.
Here is how I started :
<div class="chapter" title="Colours">
<div class="article" title="Blue">
Blue is a special colour because it gives me particular emotions. First
of all, I feel
<a href=""
class="blank"
ng-click="selectQuestion()"
doc-question="How does blue make you feel?"
doc-type="text"
doc-placeholder="like there is a wind in my ear."
doc-data="colour.blue.feeling"
>[[colour.blue.feeling]]</a>.
Second of all, blue reminds me of
<a href=""
class="blank"
ng-click="selectQuestion()"
doc-question="Pick the thing blue reminds you of"
doc-placeholder="the sky".
doc-choices="the sky, the sea, the ocean"
doc-type="radio"
doc-data="colour.blue.memory"
>[[colour.blue.memory]]</a>
like the first time I experienced the colour which was on
<a href=""
class="blank"
ng-click="selectQuestion()"
doc-question="Select a day"
doc-placeholder="01/01/2015"
doc-type="date"
doc-data="colour.blue.date"
>[[colour.blue.date]]</a>.
</div>
</div>
Then there would be a hidden, automatically generated form which binds the
input elements to the data inside the anchor elements with class 'blank' :
<form>
<div>
<h2>How does blue make you feel?</h2>
<input type="text" ng-model="colour.blue.feeling">
</div>
<div>
<h2>Select a day</h2>
<input type="text" ng-model="colour.blue.date">
</div>
<div>
<h2>Pick the thing blue reminds you off</h2>
<input type="radio" ng-model="colour.blue.memory" name="colour.blue.memory" value="the sky" >the sky<br>
<input type="radio" ng-model="colour.blue.memory" name="colour.blue.memory" value="the sea" checked>the sea<br>
<input type="radio" ng-model="colour.blue.memory" name="colour.blue.memory" value="the ocean"> the ocean
</div>
</form>
Does this problem have a name?
Is my approach reasonable?
How can I programmatically create the form and bind the fields to it (of
course, I am not expecting code here, unless you can show me something similar).
To display only the part of the form that is of interest, with jQuery,
I would hide all the divs in the form then detach the form and re-attach it to the
div that is the Blank’s parent. Then I would show the div containing the relevant
input(s) by selecting it using a distinctive attribute, invoke jQuery’s show()
and it is done. How would I accomplish this using Angular?
Thank you very much for your help.
I have a web form that has 2 radio buttons, depending on which one is clicked it displays a hidden element
This works fine in all browsers except for IE6, which, after I click on the radio button, I have to click again (anywhere on the window) and then the element is displayed...has anyone had behavior like this before?
I tried to not use jQuery and do straight getElementById() but I get the same behavior...
Javascript
function showHidden(divid) {
$('#'+divid).css( {'display':'inline'} );
}
HTML
<input type=radio name=borp value=1 onChange='showHidden("brandchecks")' > Brand
<input type=radio name=borp value=2 onChange='showHidden("productchecks")' > Product
<div id='brandchecks' style='display:none;'>
Blah
</div>
<div id='productchecks' style='display:none;'>
Blah
</div>
I thought I remember something about IE firing the onChange event after the focus was lost. This behavior would match what you have seen (ie clicking somewhere else to active your code)
Try to change the onChange in onClick for better results.
Note: To be able to click on the text accompanying the radio buttons you could use the <label> tag, this results in a more user-friendly page.
<input type="radio" value="1" id="baby">
I'd like to keep this code like that.
However, can I apply a CSS to it so that the "1" is not displayed to the user?
Edit: For some reason, it is being displayed, I don't know why.
I do have a CSS attached to it though.
The value of "1" is not displayed to the user at all, it's hidden and only has meaning when the form posts. You need to add a <label> tag or just raw text near the radio button to display the value you want the user to see.
For radio buttons, the value attributed is never rendered by the user agent (unless it does something rather weird). Typically, if you need a radio button with a label, you explicitly specify one, ideally using the <label> tag.
The "1" should not display for the user.. it's just a value..
Normally, you'd declare a radio input like so:
<label><input type="radio" value="1" id="baby"> Baby </label>
This will make "Baby" the label for the radio button, this will also make clicking on the Baby text activate the radio button, which is what accessibility rules would require..