detect selections of 2 sets of radio buttons in jquery - javascript

I have a web page which asks the user two simple yes-no questions. Under each question there's a set of two radio buttons in which the user can choose either yes or no.
<p>Question 1 yes or no?</p>
<input type="radio" name="q1" id="q1-y" value="Yes">Yes
<input type="radio" name="q1" id="q1-n" value="No">No
<p>Question 2 yes or no?</p>
<input type="radio" name="q2" id="q2-y" value="Yes">Yes
<input type="radio" name="q2" id="q2-n" value="No">No
If the user chooses yes for BOTH questions, it needs to display some HTML which will provide a link to a certain page. If the users answers no to one or both of the questions, then some alternative HTML will appear which will display another message.
There can't be a submit button like a form and this has to be a javascript/jquery based solution, not server side. The page needs to:
1) Detect when both sets of questions have been answered. Then
2) Instantly display certain HTML depending on if either a) YES has been answered to both, or b) if a NO has been given once or more.
Essentially, the logic should be something along the lines of:
if( /*both radio buttons answered*/ ){
if( /*both answers are yes*/ ){
/*show HTML set 1*/
} else {
/*show HTML set 2*/
}
}
I have tried looking at questions on this site, but I can't seem to find a solution to this specific problem. Let me know if anything needs clarifying.
Thanks very much!

Different solution:
$( "input" ).change(function() {
var buttons = jQuery("input:radio:checked").get();
var values = $.map(buttons, function(element) {
return $(element).attr("value");
});
if(values == "Yes,Yes") {
alert("both yes");
}
else {
//do something else
}
});
Demo: Multiple Radiobuttons
Don't like to check the string like that but could be adjusted in a proper way.

Try this:
$(document).ready(function(){
$("#yep").hide();
$("#nope").hide();
$(".nones").click(function(){
$("#yep").hide();
$("#nope").show();
});
$(".yipis").click(function(){
var checkeo = 1;
$( ".yipis" ).each(function( index ) {
if($(this).is(":checked") == false)
{
checkeo = 0;
};
});
if(checkeo){
$("#nope").hide();
$("#yep").show();
}
});
});
Working fiddle: http://jsfiddle.net/robertrozas/84o46mqd/

Here is a possible way to access the values you want. JSFiddle
HTML
<p>Question 1 yes or no?</p>
<input type="radio" name="q1" id="q1-y" value="Yes">Yes
<input type="radio" name="q1" id="q1-n" value="No">No
<p>Question 2 yes or no?</p>
<input type="radio" name="q2" id="q2-y" value="Yes">Yes
<input type="radio" name="q2" id="q2-n" value="No">No
<p>
<input type="button" id="finished" value="Submit" />
</p>
<div id="htmlarea"></div>
JavaScript
I find that jQuery is() function and the pseudo class :checked are helped when reading radio buttons.
$("#finished").click(function() {
var q1y = $("#q1-y").is(":checked");
var q1n = $("#q1-n").is(":checked");
var q2y = $("#q2-y").is(":checked");
var q2n = $("#q2-n").is(":checked");
if (q1y && q2y) {
$("#htmlarea").html("Both yes");
} else if (q1n && q2n) {
$("#htmlarea").html("Both no");
} else {
var html = "";
if (q1y) html += "Q1 yes. ";
if (q1n) html += "Q1 no. ";
if (q2y) html += "Q2 yes. ";
if (q2n) html += "Q2 no. ";
if (html=="") html = "None selected";
$("#htmlarea").html(html);
}
});
Instead of setting the HTML text, use window.location.href = "http://someurl.com"; if you want to redirect to another webpage.

One approach, given the following HTML (note the custom data-* attributes in the appended <div> elements, used to identify which choice those elements relate to):
<p>Question 1 yes or no?</p>
<input type="radio" name="q1" id="q1-y" value="Yes" />Yes
<input type="radio" name="q1" id="q1-n" value="No" />No
<p>Question 2 yes or no?</p>
<input type="radio" name="q2" id="q2-y" value="Yes" />Yes
<input type="radio" name="q2" id="q2-n" value="No" />No
<div class="result" data-relatesTo="Yes">All choices are 'yes'</div>
<div class="result" data-relatesTo="No">All choices are 'no'</div>
Which works with the following jQuery:
// caching the radio elements on the page:
var radios = $('input[type="radio"]'),
// getting the number of unique radio 'groups':
radioGroups = $.unique($('input[type="radio"]').map(function () {
return this.name;
}).get());
// binding an anonymous function as a change-event handler:
radios.change(function () {
// getting all the checked radio inputs:
var checked = radios.filter(':checked'),
// creating an object that maps to the relevant values/choices to be made:
choice = {
'yes': checked.filter(function () {
return this.value.toLowerCase() === 'yes';
}).get(),
'no': checked.filter(function () {
return this.value.toLowerCase() === 'no';
}).get()
};
// if all groups have a checked radio input:
if (checked.length === radioGroups.length) {
// iterate over the '.result' div elements:
$('div.result').each(function (i, el) {
// using 'toggle(switch)' to show/hide the element,
// the switch tests whether the choice related to the current
// element is equal to the number of radioGroups. If it is,
// it's shown, otherwise it's hidden.
$(this).toggle(choice[el.getAttribute('data-relatesTo').toLowerCase()].length === radioGroups.length);
});
}
});
JS Fiddle demo.
Alternatively, with the same HTML, the following jQuery approach also works:
var radios = $('input[type="radio"]'),
radioGroups = $.unique($('input[type="radio"]').map(function () {
return this.name;
}).get());
radios.change(function () {
var checked = radios.filter(':checked'),
// getting all the unique chosen values (in lowercase):
opts = $.unique(checked.map(function(){
return this.value.toLowerCase();
}).get());
if (checked.length === radioGroups.length) {
// hide all the '.result' elements:
$('div.result').hide()
// filter the 'div.result' elements:
.filter(function(){
// if the number of opts (chosen values) is 1
// (all choices are the same) and the 'data-relatesTo' attribute
// of the current element we're filtering is equal to that single
// option, then the element is retained in the selector
return opts.length === 1 && this.getAttribute('data-relatesTo').toLowerCase() === opts[0].toLowerCase();
})
// and so we show it:
.show();
}
});
JS Fiddle demo.
References:
JavaScript:
Element.getAttribute().
String.prototype.toLowerCase().
jQuery:
$.unique().
each().
filter().
get().
hide().
map().
show().
toggle().

Related

How can I toggle radiobutton

Say this is my HTML:
<input type="radio" name="rad" id="Radio0" checked="checked" />
<input type="radio" name="rad" id="Radio1" />
<input type="radio" name="rad" id="Radio2" />
<input type="radio" name="rad" id="Radio4" />
<input type="radio" name="rad" id="Radio3" />
As you can see the 1st radio button is checked. I need the radio button to function like toggle. For eg. If I again click on radio0, all radio buttons should be unchecked.
How can I achieve that?
Update: I don't want any extra buttons. For eg. I could add a button and set the checked property for all radio buttons to be false. However, I don't want that. I only want my form to consist of these 4 radio buttons.
Update: Since most of the people don't understand what I want, let me try to rephrase- I want the radio button to function in toggle mode. I've given the same name to all radio buttons hence it's a group. Now I want the radiobuttons to toggle itself. Eg. if I click on radio0, it should get unchecked if it's checked and checked if it's unchecked.
The problem you'll find is that as soon a radio button is clicked its state is changed before you can check it. What I suggest is to add a custom attribute to keep track of each radio's previous state like so:
$(function(){
$('input[name="rad"]').click(function(){
var $radio = $(this);
// if this was previously checked
if ($radio.data('waschecked') == true)
{
$radio.prop('checked', false);
$radio.data('waschecked', false);
}
else
$radio.data('waschecked', true);
// remove was checked from other radios
$radio.siblings('input[name="rad"]').data('waschecked', false);
});
});
You will also need to add this attribute to the initially checked radio markup
<input type="radio" name="rad" id="Radio0" checked="checked" data-waschecked="true" />
See demo here : http://jsfiddle.net/GoranMottram/VGPhD/2/
Once you give the name of 2 or more radio buttons as the same, they automatically become a group. In that group only one radio button can be checked. You have already achieved this.
This code solved my issue
$("[type='radio']").on('click', function (e) {
var previousValue = $(this).attr('previousValue');
if (previousValue == 'true') {
this.checked = false;
$(this).attr('previousValue', this.checked);
}
else {
this.checked = true;
$(this).attr('previousValue', this.checked);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label >Toogle radio button example</label>
<br />
<input type="radio" name="toogle_me" value="mango"> Blue </input>
<input type="radio" name="toogle_me" value="kiwi"> Green </input>
<input type="radio" name="toogle_me" value="banana"> Yellow </input>
<input type="radio" name="toogle_me" value="orange"> Orange </input>
I use an onClick() like the following for my custom radios:
$(function(){
// if selected already, deselect
if ($(this).hasClass('selected') {
$(this).prop('checked', false);
$(this).removeClass('selected');
}
// else select
else {
$(this).prop('checked', true);
$(this).addClass('selected');
}
// deselect sibling inputs
$(this).siblings('input').prop('checked', false);
$(this).siblings('input').removeClass('selected');
}
Using #Goran Mottram answer just tweaking it a bit to suit the case where radio buttons are not siblings.
$(".accordian-radio-button").click(function(){
var wasChecked = true;
if($(this).data('waschecked') == true){
$(this).prop('checked', false);
wasChecked = false;
}
$('input[name="ac"]').data('waschecked', false);
$(this).data('waschecked', wasChecked);
})
<input class="accordian-radio-button" data-waschecked="false" type="radio" name="ac" id="a1" />
I ran into this as well, after thinking about it and playing around with the various fiddles offered, I had a few dissatisfactions with the offered solutions.
My main problem was the last line of the accepted answer, requiring a reset:
// remove was checked from other radios
$radio.siblings('input[name="rad"]').data('waschecked', false);
And since I'm not using jQuery, I'd have to loop over and evaluate the siblings myself, which isn't a huge deal, but seemed inelegant to me. But, there's no way around it with that method, because you're using the dataset as a storage of information.
After playing around, I realized is that the problem is that when a radio is clicked, it triggers the clicked event, and whatever function is attached to that click event completes itself before the function for the "onchange" event is ever evaluated, let alone called. So, if the click event "unchecks" the toggle, then no change event is ever fired.
I've left my failed attempt here:
https://codepen.io/RiverRockMedical/pen/daMGVJ
But, if you could answer the question "will a change event happen after this click event?" then you could get a toggle working.
The solution I came up with can be seen at this pen:
https://codepen.io/RiverRockMedical/pen/VgvdrY
But basically is as follows:
function onClick(e) {
e.dataset.toDo = 'uncheck';
setTimeout(uncheck, 1, {
event:'click',
id:e.id,
dataset:e.dataset
});
}
So, on the click event, set a marker that the click has happened, and the use setTimeout() to create a pause that allows the onchange event to be evaluated and fire.
function onChange(e) {
e.dataset.toDo = 'leave';
}
If the onchange event fires, it undoes what was done by the onclick event.
function uncheck(radio) {
log('|');
if (radio.event !== 'click') return;
log('uncheck');
if (radio.dataset.toDo === 'uncheck') {
document.getElementById(radio.id).checked = false;
radio.checked = false;
}
}
Then, when the uncheck function starts, it has the information of whether a change event followed the click event or not. If not, then the radio is unchecked, and functions as a toggle.
And, it's basically self-resetting, so I don't have to loop over all the radios and reset their datasets to the initial values at the end of the function.
Now, I'm sure there's a cooler async/await way to do this that doesn't use setTimeout and would be even more elegant, but I'm still learning and I couldn't come up with it. Anyone else?
<input type="radio" name="gender" id="male"onclick="getChecked(1)"><label for="male">Male</label>
<input type="radio" name="gender" id="female"onclick="getChecked(2)"><label for="female">female</label>
<script>
var btnChecked = "";
function getChecked(i) {
if(btnChecked == i) {
btnChecked = "";
document.getElementsByTagName("input")[i-1].checked = false;
}
else btnChecked = i;
}
</script>
A simple approach in jQuery (even though I don't use jQuery nowdays):
function makeRadioInputsToggleable(radioInputs){
let radioGroup = {
lastValue: radioInputs.filter(':checked').prop('value'),
get value(){
return this.lastValue;
},
set value(v){
let inputToCheck = radioInputs.filter((i, el) => el.value === v);
radioInputs.filter(':checked').prop('checked', false);
if(inputToCheck.length > 0){
inputToCheck.prop('checked', true);
this.lastValue = v;
}else{
this.lastValue = undefined;
}
},
};
radioInputs.on('click', (e) => {
let input = e.target;
if(input.value === radioGroup.lastValue){
input.checked = false;
radioGroup.lastValue = undefined;
}else{
radioGroup.lastValue = input.value;
}
}).on('keydown', (e) => {
if(e.code === 'Space'){
let input = e.target;
if(input.checked){
input.checked = false;
input.blur();
radioGroup.lastValue = undefined;
}
}
});
return radioGroup;
}
let radioInputs = $('input[type="radio"][name="rad"]');
let radioGroup = makeRadioInputsToggleable(radioInputs);
$('.check-radio').on('click', (e)=>{
let value = e.target.value;
radioGroup.value = value;
});
// Note:
// 1. pass a single group of radio inputs to `makeRadioInputsToggleable`
// 2. set distinct values for each radio input in a group.
// 3. to change checked radio programmatically, use `radioGroup.value = 'XXX'` rather than radioInputs.prop('checked', false).filter('[value="XXX"]').prop('checked', true);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>makeRadioInputsToggleable</h3>
<label><input type="radio" name="rad" value="1" id="Radio0" checked="checked" />1</label>
<label><input type="radio" name="rad" value="2" id="Radio1" />2</label>
<label><input type="radio" name="rad" value="3" id="Radio2" />3</label>
<label><input type="radio" name="rad" value="4" id="Radio4" />4</label>
<label><input type="radio" name="rad" value="5" id="Radio3" />5</label>
<p>1. click on an already-checked radio button, the radio will be toggled to unchecked.</p>
<p>2. focus on an already-checked radio button and press 'Space', the radio will be toggled to unchecked. <i>(This may not work in Code Snippet result area)</i></p>
<p>
3. programmatically
<button class="check-radio" value="2">check radio with value 2</button>
<button class="check-radio" value="10">check radio with value 10</button>
</p>

Validate radio buttons with jQuery on submit

I want to validate my form using jQuery.
It has groups of radio buttons.
I have found multiple solutions for a single group of radio-buttons or solutions, where you have to specifically say what group-names there are.
Like here:
Validate radio buttons with jquery?
The problem is, that the form is being generated at run-time.
The questions are saved in a txt file (don't ask, it's a school exercise).
The generated HTML-Code looks something like this:
<p>What's your gender?
<input type="radio" name="gender" value="m" />Male
<input type="radio" name="gender" value="f" />Female
</p>
<p>
How satisfied are you with out support?
<input type="radio" name="satisfaction" value="0%" />Not at all
<input type="radio" name="satisfaction" value="25%" />Not very much
<input type="radio" name="satisfaction" value="75%" />It was ok
<input type="radio" name="satisfaction" value="100% />It was very satisfying
</p>
The js file is being generated using Twig, so it would be possible to loop through all the radio button groups, but I would like to avoid this if that's possible.
You would need to add all the groups first (page load would be fine, but make sure the group array is in global scope), then validate each group individually when your form is submitted/button click
var groups = [];
$(function() {
$("input[type=radio][name]").each(function() {
// Add the unique group name to the array
groups[$(this).attr("name")] = true;
});
});
$("button").click(function() {
$.each(groups, function(i, o) {
// For each group, check at least one is checked
var isValid = $("input[name='"+i+"']:checked").length;
alert(i + ": " + isValid);
});
});
I got it working like this
var groups = [];
$(function() {
$("input[type=radio][name]").each(function() {
// Add the unique group name to the array
if (groups[groups.length - 1] != $(this).attr("name")) groups.push($(this).attr("name"));
});
});
$('form').submit(function () {
var isValid = true;
$.each(groups, function(i, o) {
// For each group, check at least one is checked
if (isValid) isValid = $("input[name='"+o+"']:checked").length;
});
if (!isValid) return false;
return true;
});
Thanks to Blade0rz!

How to check radio button is checked using JQuery?

I have two radio buttons in one group, I want to check the radio button is checked or not using JQuery, How ?
Given a group of radio buttons:
<input type="radio" id="radio1" name="radioGroup" value="1">
<input type="radio" id="radio2" name="radioGroup" value="2">
You can test whether a specific one is checked using jQuery as follows:
if ($("#radio1").prop("checked")) {
// do something
}
// OR
if ($("#radio1").is(":checked")) {
// do something
}
// OR if you don't have ids set you can go by group name and value
// (basically you need a selector that lets you specify the particular input)
if ($("input[name='radioGroup'][value='1']").prop("checked"))
You can get the value of the currently checked one in the group as follows:
$("input[name='radioGroup']:checked").val()
//the following code checks if your radio button having name like 'yourRadioName'
//is checked or not
$(document).ready(function() {
if($("input:radio[name='yourRadioName']").is(":checked")) {
//its checked
}
});
This is best practice
$("input[name='radioGroup']:checked").val()
jQuery 3.3.1
if (typeof $("input[name='yourRadioName']:checked").val() === "undefined") {
alert('is not selected');
}else{
alert('is selected');
}
Radio buttons are,
<input type="radio" id="radio_1" class="radioButtons" name="radioButton" value="1">
<input type="radio" id="radio_2" class="radioButtons" name="radioButton" value="2">
to check on click,
$('.radioButtons').click(function(){
if($("#radio_1")[0].checked){
//logic here
}
});
Check this one out, too:
$(document).ready(function() {
if($("input:radio[name='yourRadioGroupName'][value='yourvalue']").is(":checked")) {
//its checked
}
});
Taking some answers one step further - if you do the following you can check if any element within the radio group has been checked:
if ($('input[name="yourRadioNames"]:checked').val()){ (checked) or if (!$('input[name="yourRadioNames"]:checked').val()){ (not checked)
Try this:
var count =0;
$('input[name="radioGroup"]').each(function(){
if (this.checked)
{
count++;
}
});
If any of radio button checked than you will get 1
Simply you can check the property.
if( $("input[name='radioButtonName']").prop('checked') ){
//implement your logic
}else{
//do something else as radio not checked
}

greasemonkey script to select radio button

i'm new here. i've a question related to greasemonkey.
A page contain multiple radio buttoned values and one choice is to made, this correct choice option is hidden within the page
the radio buttons are present in the form whose structure is
<form name="bloogs" action="/myaddres.php" id="bloogs" method="post" >
then the hidden field as
<input type=hidden value="abcd" name="ans">
then all the radio button values are followed as
<input type="radio" id="r1" name="opt" value="abcd"> abcd
<input type="radio" id="r2" name="opt" value="efgh"> efgh
<input type="radio" id="r3" name="opt" value="ijkl"> ijkl
and so on
thus i need the button with value=abcd be 'checked' as soon as the page loads. Thanks
There are some ways you can use:
1 You can pre-select it by putting in selected="selected" like this:
<input type="radio" id="r1" name="opt" value="abcd" checked="checked" /> abcd
2 You can use jQuery to do it easily (I don't know whether it will be applicable in terms of greasmonky though)
$(function(){
$('input[value="abcd"]').attr('checked', 'checked');
});
3 You can loop through all elements and selected the one with raw javascript
var form = document.getElementById('bloogs');
for(var i=0; i<form.elements.length; i++)
{
if (form.elements[i].type == 'radio')
{
if (form.elements[i].value == 'abcd')
{
form.elements[i].setAttribute('checked', 'checked');
break;
}
}
}
Update:
This uses jquery and selects a radio after reading the value from hidden field:
$(function(){
$('input[value="' + $('#hidden_field_id').val() + '"]').attr('checked', 'checked');
});
Or with raw javascript:
var form = document.getElementById('bloogs');
var hidden_value = document.getElementById('hidden_field_id').value;
for(var i=0; i<form.elements.length; i++)
{
if (form.elements[i].type == 'radio')
{
if (form.elements[i].value == hidden_value)
{
form.elements[i].setAttribute('checked', 'checked');
break;
}
}
}
Update 2:
As per the name, here is how you can go about:
$(function(){
$('input[value="' + $('input[name="ans"]').val() + '"]').attr('checked', 'checked');
});
I haven't done greasemonkey, but this may help:
use jQuery and do
$('[value="abcd"]').click()
Good luck.
If you're trying to use jQuery with GreaseMonkey you're going to have to get good at writing delayed and try / retry type code. You need to start with something like this:
var _s1 = document.createElement('script');
_s1.src = 'http://www.ghostdev.com/jslib/jquery-1.3.2.js';
_s1.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(_s1);
That loads jQuery into your page. Next, you set something up that operates like so:
function dojQueryStuff() {
if (jQuery == undefined) {
setTimeout(dojQueryStuff, 1000);
} else {
// In here is where all of my code goes that uses jQuery.
}
}
dojQueryStuff();
You've defined a function that'll check for jQuery's presence, and if it doesn't find it try again 1 second later. That gives the script time to load. Please note, if you don't use your own copy of jQuery the one listed in my example does not provide a $ variable. At the end of the script I have var $j = jQuery.noConflict();, so you'll access the jQuery functionality via $j or jQuery.

Better method of retrieving values of checked input boxes via jQuery?

I have several checkboxes and a fake submit button to make an AJAX request:
<form>
<input type="checkbox" value="1"/>
<input type="checkbox" value="2" checked="checked"/>
<input type="checkbox" value="3"/>
<input type="checkbox" value="4" checked="checked"/>
<input type="button" onclick="return mmSubmit();"/>
</form>
Within the mmSubmit() method, I would like to retrieve an array of values that have been selected. Here is what I am currently doing.
mmSubmit = function() {
var ids = [];
$('input[type=checkbox]:checked');.each(function(index) {
ids.push($(this).attr('value'));
});
// ids now equals [ 2 , 4 ] based upon the checkbox values in the HTML above
return false;
};
I'm wondering if there is a shorthand method in jQuery used to retrieve the values into an array, or if what I have is already optimal.
I think this can be accomplished with map. Try the following..
mmSubmit = function() {
var ids = $('input[type=checkbox]:checked').map(function(){
return $(this).val();
}).get();
// ids now equals [ 2 , 4 ] based upon the checkbox values in the HTML above
return false;
};
Take a look at: jQuery Traversing/Map
Well you can use .val() instead of .attr('value').
$.serializeArray() may also do what you want (http://docs.jquery.com/Ajax/serializeArray).
It's needs some optimization, buts generally it is right way. My variant:
mmSubmit = function () {
var ids = [];
$('input[type=checkbox]').each(function () {
if (this.checked) {
ids[ids.length] = this.value;
}
});
return ids;
};
It's little faster.

Categories