How can I enable disabled radio buttons? - javascript

The following code works great in IE, but not in FF or Safari. I can't for the life of me work out why. The code is supposed to disable radio buttons if you select the "Disable 2 radio buttons" option. It should enable the radio buttons if you select the "Enable both radio buttons" option. These both work...
However, if you don't use your mouse to move between the 2 options ("Enable..." and "Disable...") then the radio buttons do not appear to be disabled or enabled correctly, until you click anywhere else on the page (not on the radio buttons themselves).
If anyone has time/is curious/feeling helpful, please paste the code below into an html page and load it up in a browser. It works great in IE, but the problem manifests itself in FF (3 in my case) and Safari, all on Windows XP.
function SetLocationOptions() {
var frmTemp = document.frm;
var selTemp = frmTemp.user;
if (selTemp.selectedIndex >= 0) {
var myOpt = selTemp.options[selTemp.selectedIndex];
if (myOpt.attributes[0].nodeValue == '1') {
frmTemp.transfer_to[0].disabled = true;
frmTemp.transfer_to[1].disabled = true;
frmTemp.transfer_to[2].checked = true;
} else {
frmTemp.transfer_to[0].disabled = false;
frmTemp.transfer_to[1].disabled = false;
}
}
}
<form name="frm" action="coopfunds_transfer_request.asp" method="post">
<select name="user" onchange="javascript: SetLocationOptions()">
<option value="" />Choose One
<option value="58" user_is_tsm="0" />Enable both radio buttons
<option value="157" user_is_tsm="1" />Disable 2 radio buttons
</select>
<br /><br />
<input type="radio" name="transfer_to" value="fund_amount1" />Premium
<input type="radio" name="transfer_to" value="fund_amount2" />Other
<input type="radio" name="transfer_to" value="both" CHECKED />Both
<br /><br />
<input type="button" class="buttonStyle" value="Submit Request" />
</form>

To get FF to mimic IE's behavior when using the keyboard, you can use the keyup event on the select box. In your example (I am not a fan of attaching event handlers this way, but that's another topic), it would be like this:
<select name="user" id="selUser" onchange="javascript:SetLocationOptions()" onkeyup="javascript:SetLocationOptions()">

Well, IE has a somewhat non-standard object model; what you're doing shouldn't work but you're getting away with it because IE is being nice to you. In Firefox and Safari, document.frm in your code evaluates to undefined.
You need to be using id values on your form elements and use document.getElementById('whatever') to return a reference to them instead of referring to non-existent properties of the document object.
So this works a bit better and may do what you're after:
Line 27: <form name="frm" id="f" ...
Line 6: var frmTemp = document.getElementById('f');
But you might want to check out this excellent book if you want to learn more about the right way of going about things: DOM Scripting by Jeremy Keith
Also while we're on the subject, Bulletproof Ajax by the same author is also deserving of a place on your bookshelf as is JavaScript: The Good Parts by Doug Crockford

Why not grab one of the AJAX scripting libraries, they abstract away a lot of the cross browser DOM scripting black magic and make life a hell of a lot easier.

Related

accessibility - grouped checkboxes where one checkbox has a related textarea

I have a feedback form where I am asking users for a reason for cancellation, something like this:
label {
display: block
}
button {
display: block;
}
<form>
<fieldset>
<legend> Reason for cancellation? </legend>
<label>
<input type="checkbox"> Reason 1 </input>
</label>
<label>
<input type="checkbox"> Reason 2 </input>
</label>
<label>
<input type="checkbox"> Reason 3 </input>
</label>
<label>
<input type="checkbox"> Reason 4 </input>
</label>
<label>
<input type="checkbox"> Other </input>
</label>
<textarea aria-label="other reason"></textarea>
<button> Submit </button>
</fieldset>
</form>
The textarea is related to the Other checkbox, i.e, it only gets activated if the user selects the Other option, otherwise it remains disabled
How do I represent that association in markup?
Should I group the checkbox and the textarea using another fieldset? I am not sure if this is semantically correct, and also in general this is discouraged.
https://accessibility.blog.gov.uk/2016/07/22/using-the-fieldset-and-legend-elements/#:~:text=It%20is%20possible%20to%20nest,fields%20belong%20within%20which%20fieldset.
Should I use something like aria-controls or aria-owns?
Would it be enough to just mention Other (Please fill the reason below) in the checkbox label, so that when the label is announced, the user can get to know that there is a textarea just after the checkbox which can be reached by tab
It might also be ok to change the UX to always allow the user to optionally fill in the text area for any of the selected reasons , so the text area can be part of the same fieldset and can be enabled all the time
NOTE:
I have seen some examples, specifically Google Forms, and Search Engine Journal.
Google forms solves this issue by placing the textbox next to the checkbox, the textbox is always enabled, and as soon as you focus on the textbox, the checkbox gets automatically checked.
Search Engine Journal, does not explicitly associate the controls, but they do mention it in the checkbox label, to fill in the reason below.
Answer on using ARIA
You can use aria-controls, it seems like a good fit for your case.
it looks more appropriate than aria-owns, see this question about difference between aria-own and aria-controls.
However, screen reader support is quite inconsistent, and even if it is supported, it's at the end quite rarely known and used by screen reader users.
Therefore, in addition, it's always good to add a precision in clear text like you suggest e.g. "Other reason (please explain below)". Adding that indication in the label of the checkbox is a good choice.
This added precision will anyway never by harmful to anyone, so you have no reason not to do it.
Answer on the UX design
If you have added the precision "please explain below", there's really no problem in enabling the textarea depending on the checkbox.
Simply, make sure that the textarea come after the enabling checkbox in tab order, so to ensure that the user won't miss it and won't need to go back and forth to fill it in.
Unless you have a weird design, it should normally already be the case.
The other alternative, checking the checkbox automatically when entering a reason is equally no problem, but you need to be more carful on when you do it:
Don't check the checkbox on focusing the textarea, otherwise keyboard only users will trigger it when they don't want to, and even normal users may click on the textarea and then change their mind
Don't check the checkbox on entering a character in the textarea. It's probably a bad idea because I may start typing something, and finally clear everything and change my mind
What about checkign the checkbox when the textarea loses the focus while being non-empty ?
You may, optionally, show a snackbar or something like that with aria-live=polite, telling that the checkbox as been checked automatically because you ahve entered something.
This kind of bonus indication on things modified automatically would be quite useful in more complex forms, but for your case as it is presented here, it's totally superfluous because the relationship is obvious.
You could just hide the textarea by default and let it show up with a small javascript to toggle a class to set display to block.
<body>
<form>
<fieldset>
<legend> Reason for cancellation? </legend>
<label>
<input type="checkbox"> Reason 1 </input>
</label>
<label>
<input type="checkbox"> Reason 2 </input>
</label>
<label>
<input type="checkbox"> Reason 3 </input>
</label>
<label>
<input type="checkbox"> Reason 4 </input>
</label>
<label>
<input type="checkbox" class="otherCheckbox"> Other </input>
</label>
<textarea aria-label="other reason" class="otherTextarea"></textarea>
<button> Submit </button>
</fieldset>
</form>
</body>
<script>
let otherCheckbox = document.querySelector(".otherCheckbox")
let otherTextarea = document.querySelector(".otherTextarea")
otherCheckbox.addEventListener("change", e => {
otherTextarea.classList.toggle("show")
})
</script>
Added to css:
.otherTextarea {
display: none;
}
.show {
display: block;
}

Inject Javascript to select all radio buttons with specified value

Slightly odd question, but I'm trying to find a way (if possible) to select all radio buttons that have the same value. We regularly get hundreds of spam accounts signing up on our website, and it would be easier to set all radio buttons to "Reject" and double-check to make sure there's no legitimate ones, as opposed to constantly clicking on a radio button. (Lazy is my middle name, yes.)
Is this possible? If so, how? I haven't got access to the actual web pages to code in a button to do just this yet, but it's something I'm looking at long term. Right now though, I need something quick and dirty to do what I want it to do. I'm using Chrome, and can use Greasemonkey if that's required.
The value to select by is "reject".
A snippet of code that's being used. If it's of any consequence, our forum is running Xenforo:
<li>
<label for="ctrl_users16667action_reject">
<input type="radio" name="users[16667][action]" value="reject" class="Disabler" id="ctrl_users16667action_reject">
Reject and delete with rejection reason:
</label>
<ul id="ctrl_users16667action_reject_Disabler" class="disablerList">
<li>
<input type="text" name="users[16667][reject_reason]" value="" size="45" placeholder="Optional" class="textCtrl" id="ctrl_users16667reject_reason">
</li>
</ul>
</li>
You're looking for a bookmarklet or a GreaseMonkey (or TamperMonkey or similar) script.
Re bookmarklets, you can use the javascript: pseuedo-protocol to run script on the page you're looking at from your bookmarks manager. Just make the URL in your bookmark:
javascript:(function() { /* ...your code here ...*/ })();
Because it has to be URI-encoded, you can find "bookmarklet generators" out there to handle that part for you.
Alternately, there are GreaseMonkey, TamperMonkey, and similar add-ons/extensions for browsers.
Then it's a trivial matter of selecting the relevant radio buttons:
$('input[type=radio][value="reject"]').prop('checked', true);
So if jQuery is already loaded on the page in question, you could use this as a bookmarklet:
javascript:(function(){$('input[type=radio][value="reject"]').prop('checked',true);})();
Use :radio to get radio buttons, then for filtering use attribute equals selector
var $ele = $(':radio[value="reject"]')
or filter()
var $ele = $(':radio').filter(function(){ return this.value == 'reject'; });
FYI : It's a jQuery solution and it only works if you are loaded jQuery library in the page.
Try this it will work
$("input:radio[value=reject]")
you have to give unique name to all radio buttons then you can select multiple radio buttons using javascript
you have to give same class to radio button
<input type="radio" name="radio[]" class="my_class" value="1" />
<input type="radio" name="radio[]" class="my_class" value="1" />
<input type="radio" name="radio[]" class="my_class" value="0" />
$(".my_class").each(function(){
if($(this).val() == "1"){
$(this).attr('checked','checked);
}
});
Thanks

Can't enable html input fields in safari

Fiddle here. Starting with html elements in the below given structure, safari for some strange reason could not enable all input elements. It just enables the first one only. Might be some bug?
<fieldset disabled><div>
<div><fieldset disabled>
<input type="text" disabled>
</fieldset></div>
<div><fieldset disabled>
<input type="text" disabled>
</fieldset></div>
</div></fieldset>
Javascript here:
$('fieldset').prop('disabled',false);
$("input").prop('disabled',false);
To make Safari correctly enable all inputs you should enable all fieldset from the inside out, so the nested ones first:
const fieldsets = document.getElementsByTagName('fieldset');
Array.from(fieldsets).reverse().forEach(fieldset => fieldset.disabled = false);
Complete codepen with some an extra use case with fieldsets.
This was tested on Safari 13.0. This is definitely a bug and I will report it to Apple.

using checkbox as radio button

I am looking for a way for users to select one of the two options (strength or weakness) for a list of qualities.
for eg:
strength weakness not applicable
1. Communication
2. Punctuality
...
Radio button lets me select either a strength or weakness. However, I want the user to check only those qualities that apply and if a user accidentally selects a quality there is no way to undo the selection for a radio button unless there is a third radio button called not applicable or have the user re-enter the page. I was wondering if there is a way to be able to get the flexibility of a checkbox (check / uncheck) in addition to disabling or enabling the other checkbox when one of them is checked or unchecked instead of using three radio buttons.
I don't think I have seen this behavior before so wondering if there is a more elegant way of doing this. I am open to other ideas to get the same functionality. Using a checkbox as radio button was just a thought.
thanks much.
Solution based on javascript
function SetSel(elem)
{
var elems = document.getElementsByTagName("input");
var currentState = elem.checked;
var elemsLength = elems.length;
for(i=0; i<elemsLength; i++)
{
if(elems[i].type === "checkbox")
{
elems[i].checked = false;
}
}
elem.checked = currentState;
}​
<input type="checkbox" class="chkclass" onclick="SetSel(this);" />
<input type="checkbox" class="chkclass" onclick="SetSel(this);" />
<input type="checkbox" class="chkclass" onclick="SetSel(this);" />
<input type="checkbox" class="chkclass" onclick="SetSel(this);" />
Working Demo
Solution based on jQuery
$(function(){
$("input:checkbox.chkclass").click(function(){
$("input:checkbox.chkclass").not($(this)).removeAttr("checked");
$(this).attr("checked", $(this).attr("checked"));
});
});​
<input type="checkbox" class="chkclass" />
<input type="checkbox" class="chkclass" />
<input type="checkbox" class="chkclass" />
<input type="checkbox" class="chkclass" />
Working Demo
You should not use checkboxes as radio buttons (or vice-versa): this is inconsistent with the user's mental model, so it confuses people.
This is a problem with no ideal solution, but your initial suggestion of having a "not applicable" option as part of a group of 3 radio buttons is fairly common. If you pre-select the "not applicable" option by default and perhaps de-emphasize it visually (eg. gray it out) then from the user's point of view it will be almost as if there are only 2 options, but they can recover if they accidentally select one and want to "unselect" it.
this is correct form, "checked" is a proprietary and not attribute
$(function(){
$("input:checkbox.chkclass").each(function(){
$(this).change(function(){
$("input:checkbox.chkclass").not($(this)).prop("checked",false);
$(this).prop("checked", $(this).prop("checked"));
});
});
});

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