I have multiple radio buttons, each one inside a <span> with margin, so they seem like a button with a radio element inside. how can I check the radio button when I click anywhere inside the <span> parent element of the radio button
UX oriented
<span class="radio-box" id="white-box">
<input type="radio" id="white" name="colour"> White
</span>
<span class="radio-box" id="red-box">
<input type="radio" id="red" name="colour"> Red
</span>
<span class="radio-box" id="blue-box">
<input type="radio" id="blue" name="colour"> Blue
</span>
sorry, very noob at Javascript
thanks :)
This is exactly what label elements are for. Use those, rather than span elements:
<label class="radio-box" id="white-box">
<input type="radio" id="white" name="colour"> White
</label>
<label class="radio-box" id="red-box">
<input type="radio" id="red" name="colour"> Red
</label>
<label class="radio-box" id="blue-box">
<input type="radio" id="blue" name="colour"> Blue
</label>
When the label wraps the input like that, it's associated with that input. (If you couldn't use wrapping, you could use the for attribute to tell the label what the id of its associated input is.)
You could make it work with spans. Targeting just those spans:
$("span > input[type=radio][name=colour]").parent().on("click", function() {
$(this).find("input[type=radio][name=colour]").prop("checked", true);
});
or targeting any input[type=radio] inside a span.radio-box:
$("span.radio-box > input[type=radio]").parent().on("click", function() {
$(this).find("input[type=radio]").prop("checked", true);
});
But again, this is exactly what label is for, so best to use that.
If you want to do this without the <label> tag and without jquery and just vanilla JavaScript then here's a solution.
var radioBoxes = document.querySelectorAll("span.radio-box");
radioBoxes.forEach(function (box) {
var radioButton = box.querySelector("input[type='radio']");
box.addEventListener("click", function () {
radioButton.click();
});
});
Related
The outcome I am after is that when a user sends keyboard focus to a radio button group and navigates to each radio button using the arrow keys, or, clicks a radio button with a pointing device (mouse), the data-attribute value for that radio button is set to an element (h2).
I have got this far , and am now stuck. I am using an ID for the example, however, I would prefer to use a class or the data-set="X".
The code below sets the first data-col value but not the second.
Thanks for any help as I learn so much from Stackoverflow. I need this in vanilla JS and not jQuery, sorry.
<p>
<label for="">The colour is Green
<input type="radio" name="bob" data-col="Green" data-set="Green" id="demo3">
</label>
<label for="">The colour is Blue
<input type="radio" name="bob" data-col="Blue" data-set="Blue" id="demo3">
</label>
</p>
<h2 id="chjkl"></h2>
document.getElementById('demo3').onclick = function changeClk() {
const setCol = document.querySelector('#demo3');
document.getElementById('chjkl').innerHTML = setCol.dataset.col
}
document.getElementById('demo3').onfocus = function changeFoc() {
const setCol = document.querySelector('#demo3');
document.getElementById('chjkl').innerHTML = setCol.dataset.col
}
Use the event.target to get the dataset.
In the example below I change the color of your h2 elements background. Note that I am passing the event into the function and calling the function in the eventListener.
Also rather than having two eventListeners, I add a class to the radio button and then query that using querySelectorAll(). Then run the nodeList through a loop and check the event.target when the eventListener is fired.
An issue with your code is you have more than one element with the same ID. You should not have more than one element with any unique ID. ID must be unique to only one single element.
let radio = document.querySelectorAll('.radio')
let target = document.getElementById('chjkl')
function changeColor(e) {
target.style.backgroundColor = e.target.dataset.col
target.textContent = e.target.dataset.col
}
radio.forEach(btn => {
btn.addEventListener('focus', changeColor)
})
#chjkl {
display: flex;
justify-content: center;
letter-spacing: 1.3rem;
}
<p>
<label for="">The colour is Green
<input type="radio" name="bob" data-col="Green" class="radio">
</label>
<label for="">The colour is Red
<input type="radio" name="bob" data-col="Red" class="radio">
</label>
<label for="">The colour is Blue
<input type="radio" name="bob" data-col="Blue" class="radio">
</label>
<label for="">The colour is Orange
<input type="radio" name="bob" data-col="Orange" class="radio">
</label>
</p>
<h2 id="chjkl"></h2>
Currently, the below HTML code only switches when you click the input (ie. the center switch).
I need the switch to happen when you click the labels (ie. Yes or No).
How to make that happen?
<div>
<span class="frm_off_label frm_switch_opt">No</span>
<label class="frm_switch">
<input type="checkbox" name="2002" id="field_2002" value="Yes" checked="checked"
data-off="No" data-sectionid="2002" data-frmval="Yes" placeholder="Yes">
<span class="frm_slider"></span>
</label>
<span class="frm_on_label frm_switch_opt">Yes</span>
</div>
What are the ways to make the click of Yes or No, do the same thing as clicking the input?
You can achieve this by setting the checked status of input -
HTML
<div>
<span class="frm_off_label frm_switch_opt">No</span>
<label class="frm_switch">
<input type="checkbox" name="2002" id="field_2002" value="Yes" checked="checked"
data-off="No" data-sectionid="2002" data-frmval="Yes" placeholder="Yes">
<span class="frm_slider"></span>
</label>
<span class="frm_on_label frm_switch_opt">Yes</span>
</div>
JS (with jquery)
$('.frm_off_label').on('click', function(){
$(this).next('label').find("input")[0].checked = false;
});
$('.frm_on_label').on('click', function(){
$(this).prev('label').find("input")[0].checked = true;
});
CSS (optioanl)
.frm_switch_opt{
cursor:pointer;
}
You can see it in action on jsfiddle
https://jsfiddle.net/guruling/tegmps9b/27/
You can use label combine with for="element_id" like for="field_2002" attribute to achieve it.
The for attribute specifies which form element a label is bound to.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<label for="field_2002" class="frm_off_label frm_switch_opt">No</label>
<input type="checkbox" name="2002" id="field_2002" value="Yes" checked="checked"
data-off="No" data-sectionid="2002" data-frmval="Yes" placeholder="Yes">
<label for="field_2002" class="frm_on_label frm_switch_opt">Yes</label>
</div>
I am trying to convert the radio buttons in the form to star rating
I am using nintex forms and the way it has DOM structure for the radio button is as below
<table class="controls rating">
<tr>
<td>
<span>
<input type="radio" name="review-rating" id="1" value="1" />
<label for="1">1</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="2" id="2" />
<label for="2">2</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="3" id="3" />
<label for="3">3</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="4" id="4" />
<label for="4">4</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="5" id="5" />
<label for="5">5</label>
</span>
</td>
</tr>
</table>
Now I found a jsfiddle which does what I expected, but the dom structure was different
I made some tweaks and got the radio buttons appear as star, but its not working as expected
Here is the fiddle
I want the star rating on top to work like the star rating in bottom.
P.S: Its ok if the bottom one doesn't work after changes. I just want the star rating to be working for my DOM structure(top one in fiddle)
Try this, I just added the undo
$('.controls.rating')
.addClass('starRating') //in case js is turned off, it fals back to standard radio button
.on('mouseenter', 'label', function(){
DisplayRating($(this)); // when we hover into a label, show the ratings
}
)
.on('mouseleave', function() {
// when we leave the rating div, figure out which one is selected and show the correct rating level
var $this = $(this),
$selectedRating = $this.find('input:checked');
if ($selectedRating.length == 1) {
DisplayRating($selectedRating); // a rating has been selected, show the stars
} else {
$this.find('label').removeClass('on'); // nothing clicked, remove the stars
};
}
);
var DisplayRating = function($el){
// for the passed in element, add the 'on' class to this and all prev labels
// and remove the 'on' class from all next labels. This stops the flicker of removing then adding back
$el.addClass('on');
$el.parent('label').addClass('on');
$el.closest('td').prevAll().find('label').addClass('on');
$el.closest('td').nextAll().find('label').removeClass('on');
};
Edit: I just notice a bug lately so I edited it and fix the bug
JS Fiddle
The problem: your "label" are not next to each other. Convert css and event select to your "td".
https://jsfiddle.net/8cn2mekf/1/
You need to use find to remove the on class on deeper nodes children only works on level one child nodes
https://jsfiddle.net/sanddune/z1sws1w7/
I have a radio button like this on page
<div id="someId">
<label class="radio-inline">
<input name="x" type="radio" onchange="GetSelectedVal();">Yes</label>
<label class="radio-inline">
<input name="x" type="radio" onchange="GetSelectedVal();">No</label>
</div>
On page load I don't want to set any selection so not using checked property. In my JavaScript function, how can I get the value Yes or No based on the user selection at runtime?
function GetSelectedVal() {
console.log($('#someId input:radio.........);
}
I have seen similar questions but unable to find solution of this issue.
Remove onchange inline handler from HTML. Use on to bind events.
:checked will select the checked radio button. closest will select the parent label and text() will get the label associated with the radio button. e.g. Yes
$('[name="x"]').on('change', function () {
alert($('[name="x"]:checked').closest('label').text());
});
DEMO
You can simple pass this in onchange="GetSelectedVal(); like onchange="GetSelectedVal(this);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="someId">
<label class="radio-inline"><input name="x" type="radio" onchange="GetSelectedVal(this);">Yes</label>
<label class="radio-inline"><input name="x" type="radio" onchange="GetSelectedVal(this);">No</label>
</div>
<script>
function GetSelectedVal(ele) {
alert($(ele).closest('label').text());
}
</script>
I would do it a bit different than the accepted answer.
Instead of having events on multiple radio buttons, you can have one on the containing div. Also let just the checked radio trigger the change:
$('#someId').on('change', 'input[name="x"]:checked', function () {
var label = $(this).siblings('span').text();
console.log(label);
});
When I have text next to other elements I prefer wrapping the text in span's:
<div id="someId">
<label class="radio-inline"><input name="x" type="radio"><span>Yes</span></label>
<label class="radio-inline"><input name="x" type="radio"><span>No</span></label>
</div>
A demo: jsfiddle.net/qcxgwe66/
Each of my radio buttons is inside a div, and immediately beside the input (radio) I have some text in a span with the CSS set to display:none. Since I have multiple radio buttons I'm trying set the span to show for ONLY the span beside the radio button that's selected. Thoughts?
Here's what I have currently.
$('input:checked').next().show();
Here's my fiddle for the full quiz I'm trying to build
http://jsfiddle.net/YSSWL/96/
Feel free to critique the rest of my jquery, as I'm likely over complicating something. I don't have a ton of experience with jquery or js (working on it).
Solution Edit: As Chausser pointed out I can use
$('input:checked').parent().find('span').show();
to select the span nearest the parent of the selected input and apply .show();
You can use:
$('input:checked').parent().find('span').show();
I updated your html to use some consistent classes and fixed your reset function as well. For working code check:
http://jsfiddle.net/YSSWL/106/
You can solve this completely with CSS:
.incorrect .incor { display: inline; }
http://jsfiddle.net/YSSWL/105/
Here is a better way to write this I think. A bit more flexible. Sorry I deleted a bunch of your stuff to make it clear what was going on.
JS:
$(document).ready(function () {
$(document).on('click', '#radiochk1', function(){
var checkedRadio = $('input[name="question1"]:checked');
$('.correct, .incorrect').removeClass('correct').removeClass('incorrect');
if(checkedRadio.hasClass('rightAnswer')){
checkedRadio.parent().find('span.answer').addClass('correct');
}else{
checkedRadio.parent().find('span.answer').addClass('incorrect');
}
});
$(document).on('click', '#resetq1', function(){
$('.correct, .incorrect').removeClass('correct').removeClass('incorrect');
$('input[name="question1"]').attr('checked', false);
});
});
HTML:
<form class="ra">
<div class="cor">
<input type="radio" name="question1" class="c1" />A. Choice A<span class="hiddencorr">Correct answer</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i1" />B. <span class="answer">Choice B</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i2 rightAnswer" />C. <span class="answer">Choice C</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i3" />D. <span class="answer">Choice D</span>
</div>
<div class="inc">
<input type="radio" name="question1" class="i4" />E. <span class="answer">Choice E</span>
</div>
</form>
<p class="rationale1"><b>Rationale:</b>
<br />
<br /><span class="rattext">Explanation of what was done wrong.</span>
</p>
<button id="radiochk1" class="checkhide">Check your answer</button>
<button id="resetq1" class="reset">Reset</button>