I want to be able to uncheck a radio button by clicking on it.
So, if a radio button is unchecked, I want to check it, if it is checked, I want to uncheck it.
This does not work:
$('input[type=radio]:checked').click(function(){
$(this).attr('checked', false);
});
I am not able to check a radio button now.
This is not to replace a checkbox, it's to allow a radio group to go back to an unselected state. This was tricky because the radio selection doesn't act like a normal event.
The browser handles radio buttons outside the normal event chain. So, a click handler on a radiobutton with event.preventDefault() or event.stopPropagation() will NOT prevent the radiobutton from being checked. The .removeAttr('checked') must be done in a setTimeout to allow the event to finish, and the browser to check the radiobutton (again), and then the setTimeout will fire.
This also correctly handles the case where a user starts the mousedown but leaves the radiobutton before mouseup.
//$ = jQuery;
$(':radio').mousedown(function(e){
var $self = $(this);
if( $self.is(':checked') ){
var uncheck = function(){
setTimeout(function(){$self.removeAttr('checked');},0);
};
var unbind = function(){
$self.unbind('mouseup',up);
};
var up = function(){
uncheck();
unbind();
};
$self.bind('mouseup',up);
$self.one('mouseout', unbind);
}
});
I hope this helps
try this:
$('input[type=radio]').click(function(){
if (this.previous) {
this.checked = false;
}
this.previous = this.checked;
});
The accepted answer does not work on mobile devices. It relies on setTimeout and bindings that are related to mouse events that just don't fire on tablets/mobile devices.
My solution is to manually track the selected state using the "click" event handler and a custom class state.
handle the click events on the radio input elements
check if the "selected" class exists on the clicked element
if it does, (meaning it has been clicked before), remove the class and uncheck the element, return
if it doesn't, remove the class from all elements of the same name and add it to only the clicked element.
No need to prevent default behaviors. Here is the code in Jquery:
$("input:radio").on("click",function (e) {
var inp=$(this); //cache the selector
if (inp.is(".theone")) { //see if it has the selected class
inp.prop("checked",false).removeClass("theone");
return;
}
$("input:radio[name='"+inp.prop("name")+"'].theone").removeClass("theone");
inp.addClass("theone");
});
http://jsfiddle.net/bhzako65/
I must be missing it but after all these years AFAIK none of the solutions above seem to work or maybe I'm just dumb.
There is absolutely no reason to use a radio button unless there is more than one radio button in the same group. If it's a lone radio button then just use a checkbox. The reason to use a radio button is for selecting one of mutually exclusive options. That means any solution which only looks at individual buttons will fail since clicking a one button will effect the state of the other buttons
In other words since we're using radioboxes the solution needs to work for
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>
Here's one that looks at all the buttons.
This seems to work
document.querySelectorAll(
'input[type=radio][name=foo]').forEach((elem) => {
elem.addEventListener('click', allowUncheck);
// only needed if elem can be pre-checked
elem.previous = elem.checked;
});
function allowUncheck(e) {
if (this.previous) {
this.checked = false;
}
// need to update previous on all elements of this group
// (either that or store the id of the checked element)
document.querySelectorAll(
`input[type=radio][name=${this.name}]`).forEach((elem) => {
elem.previous = elem.checked;
});
}
body { font-size: xx-large; }
label, input {
/* added because a second click to unselect radio often
appears as a double click to select text */
-webkit-user-select: none;
user-select: none;
}
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>
note if elem.previous worries you you could use elem.dataset.previous
Another solution would be to store which button is checked
function makeRadioboxGroupUnCheckable(groupSelector) {
let currentId;
document.querySelectorAll(groupSelector).forEach((elem) => {
elem.addEventListener('click', allowUncheck);
// only needed if can be pre-checked
if (elem.checked) {
currentId = elem.id;
}
});
function allowUncheck(e) {
if (this.id === currentId) {
this.checked = false;
currentId = undefined;
} else {
currentId = this.id;
}
}
}
makeRadioboxGroupUnCheckable('input[type=radio][name=foo]');
body { font-size: xx-large; }
label, input {
/* added because a second click to unselect radio often
appears as a double click to select text */
-webkit-user-select: none;
user-select: none;
}
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>
This is the real solution ...
var check;
$('input[type="radio"]').hover(function() {
check = $(this).is(':checked');
});
$('input[type="radio"]').click(function() {
check = !check;
$(this).attr("checked", check);
});
Try it, it works for me!
Found this somewhere while looking for a solution, do like the simplicity of it...
var checkedradio;
function docheck(thisradio) {
if (checkedradio == thisradio) {
thisradio.checked = false;
checkedradio = null;
}
else {checkedradio = thisradio;}
}
Use with:
<input type='radio' onclick='docheck(this);'>
It does seem to require a double click to deselect when you have multiple radio groups in a form though, but this could by solved by having a function for each group I suppose...
I know this question is old, but I just came across this problem and decided to have a go myself and didn't want to use a modifier button like ctrl.
See fiddle at http://jsfiddle.net/ArktekniK/yhbw469f/
For toggling a radio button by clicking on the radio button itself
$('input[type=radio]').on('mousedown', function(e){
var wasChecked = $(this).prop('checked');
this.turnOff = wasChecked;
$(this).prop('checked', !wasChecked);
});
$('input[type=radio]').on('click', function(e){
$(this).prop('checked', !this.turnOff);
this['turning-off'] = !this.turnOff;
});
For toggling a radio button by clicking on the label or radio button itself
$('label:has(input[type=radio])').on('mousedown', function(e){
var radio = $(this).find('input[type=radio]');
var wasChecked = radio.prop('checked');
radio[0].turnOff = wasChecked;
radio.prop('checked', !wasChecked);
});
$('label:has(input[type=radio])').on('click', function(e){
var radio = $(this).find('input[type=radio]');
radio.prop('checked', !radio[0].turnOff);
radio[0]['turning-off'] = !radio[0].turnOff;
});
Who those who are seeking for a pure JavaScript solution I modified the code from Jase in ATL's answer.
I wrote this code for proposal of use with a CSS styled 3 position switch which provides 4 state of toggling (On, Off, Neutral and Unactivated).
function toggle_radio(ev) {
var radio = ev.target;
var cut_pos = radio.className.indexOf(' switcher-active');
// the switch itself
if (cut_pos !== -1) { // if the button checked it is '.switcher-active'
radio.checked = false; // toggle its state
radio.className = radio.className.slice(0, cut_pos); // remove '.switcher-active'
return true; // work is done. Break the function
}
// the button was inactive before it was clicked. Then it should became '.switcher-active'
radio.className = radio.className + ' switcher-active';
// we need to remove '.switcher-active' if either the left or right radio button was clicked. This part is uggly but I don't bother, because I'm late for barber
var radios = document.getElementsByName(radio.name); // get all these radio siblings as a collection of elements
for (var i=0; i < radios.length; i++) { // iterate through the collection
if (radios[i].className.indexOf('switcher-radio-neutral') !== -1)
continue; // skip the '.switcher-neutral' radio input
radios[i].onclick = function(ev2) {
sib_radios = document.getElementsByName(ev2.target.name); // get a group of radio inputs linked by the name
// get the '.switcher-neutral'
for (var k=0, cut_pos = -1, sib; k < sib_radios.length; k++) {
sib = sib_radios[k];
cut_pos = sib.className.indexOf(' switcher-active');
if (cut_pos !== -1)
sib.className = sib.className.slice(0, cut_pos);
}
}
}
}
var switchers = document.getElementsByClassName('switcher-radio-neutral');
for (var i=0; i < switchers.length; i++) { // bind onclick handlers
switchers[i].onclick = toggle_radio;
}
.switcher {
position: relative;
display: inline-block;
margin: 1px 10px;
height: 20px;
width: 58px;
z-index: 1;
}
.switcher-off {
left: 1px;
width: 33%;
height: 100%;
}
.switcher-neutral {
left: 33%;
width: 33%;
height: 100%;
}
.switcher-on{
right: 1px;
width: 33%;
height: 100%;
}
.switcher-label {
position: absolute;
text-indent: -9999px;
z-index: 2;
}
.switcher input {
visibility: hidden;
position: absolute;
}
.switcher-slider {
height: 100%;
width: 100%;
border-radius: 10px;
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1) inset, 0 0 4px rgba(0, 0, 0, 0.5) inset, 0 2px 2px 1px rgba(0, 0, 0, 0.3) inset;
transition: background-color 0.2s linear 0s;
}
.switcher-slider:after {
transition: left 0.2s linear 0s, right 0.2s linear 0s;
background: linear-gradient(#D0D0D0, #FDFDFD) repeat scroll 0 0 rgba(0, 0, 0, 0);
content: "";
position: absolute;
top: 1px;
border-radius: 50%;
height: calc(100% - 2px);
width: calc(100%/3 - 1px);
box-shadow: 0 0 1px 1px #f4f4f4 inset, 0 0 3px 1px rgba(0, 0, 0, 0.6);
left: 33%;
}
.switcher-radio-on:checked ~ .switcher-slider {
background-color: #81EA89;
}
.switcher-radio-neutral:checked ~ .switcher-slider {
background: #ddd;
}
.switcher-radio-off:checked ~ .switcher-slider {
background-color: #ED8282;
}
.switcher-radio-on:checked ~ .switcher-slider:after {
left: calc(2*(100%/3));
}
.switcher-radio-neutral:checked ~ .switcher-slider:after {
left: calc(1px + 100%/3);
}
.switcher-radio-off:checked ~ .switcher-slider:after {
left: 1px;
}
<form action="">
<input type="radio" name="radio_input" value="1">
<input type="radio" name="radio_input" class="switcher-radio-neutral" value="2">
<input type="radio" name="radio_input" value="3">
</form>
<br><br>
<div class="switcher">
<label class='switcher-label switcher-off' for='off'>off</label>
<input id='off' class='switcher-radio-off' type='radio' name='value' value='off'>
<label class='switcher-label switcher-neutral' for='neutral'>neutral</label>
<input id='neutral' class='switcher-radio-neutral' type='radio' name='value' value='neutral' data-neutral="">
<label class='switcher-label switcher-on' for='on'>on</label>
<input id='on' class='switcher-radio-on' type='radio' name='value' value='on'>
<div class='switcher-slider'></div>
</div>
If there is only one radio button you needs to use checkbox instead.
There is no meaning to having one radio button they works with group.
probably you are looking for checkbox control.
It is better UX to have a default-selected "Select none" explicit option, and not let the user uncheck any radio button.
(List item 9 in this nngroup (neilsen) article:
http://www.nngroup.com/articles/checkboxes-vs-radio-buttons/
As HexInteractive mentioned, radio button is handled outside the normal event chain.
So, following example judges the button state by class name, not by property.
var $self;
$('input[type=radio]').on('click', function() {
$self = $(this);
if ( $self.hasClass('is-checked') ) {
$self.prop('checked', false).removeClass('is-checked');
} else {
$self.addClass('is-checked');
}
});
Based on answer by Stephen - this deals with multiple radio button groups and also you mostly don't need to double click radio buttons. It isn't perfect as if you switch between groups the check for id will necessitate an extra click but works ok.
$("input[type='radio']").on('click', function (e) {
if (this.previous && this.value == previousvalue && this.id == previousid) {
this.checked = false;
}
this.previous = this.checked;
previousvalue = this.value;
previousid = this.id;
});
Yes you can also do this on click checked, again click uncheck.
Here is the logic of this:
$('input[name=check1]').prop('checked',!$('input[name=check1]').prop('checked'));
var checked = {};
$('.desectable-radio').each(function (index) {
checked[index] = this.checked;
$(this).click(function () {
if (checked[index])
this.checked = false;
for (var i in checked) {
checked[i] = false;
}
checked[index] = this.checked;
});
});
Here's a super lightweight script you can add to a page through the console window that allows you to deselect a radio button by holding down Ctrl while clicking it with the mouse.
document.addEventListener('click', function(e){
if (e.ctrlKey == true &&
e.target.tagName == 'INPUT' &&
e.target.type == "radio" &&
e.target.checked == true) {
e.target.checked = false;
}
});
Since it doesn't rely on jQuery, you can easily add it to any page to temporarily allow deselection.
For slightly more info, you can read an article I just wrote on How To Deselect A Radio Button.
Needing a solution to this issue, I settled on replacing the currently active radio button with a ‘cancel’ icon button, like this http://fontawesome.io/icon/ban/
Clicking this icon unchecked the active radio button, which then reappeared, effectively resetting the radio button group. The cancel icon was also removed from the DOM.
Alternatively the user could click another of the radio buttons in the group, which would behave as normal aside from the cancel button, which was then ‘moved’ to replace the new active radio button.
This kept the cancel icon in an intuitive location (i.e. where the user last clicked) and was safer than assuming the user would know to re-click the currently active radio button to deactivate the group.
Worst case if you have a long list of radio buttons, the user just has to click any of them twice to clear the group.
I think this is the shortest way. I tested it on Chrome and MS Edge.
$(document).on('click', 'input:radio', function () {
var check = $(this).attr('checked')
if (check) $(this).removeAttr('checked').prop('checked',false)
else $(this).attr('checked', true).prop('checked',true)
})
This piece of code also works on AJAX loaded contents.
Using prop function with checked as key:
$("input:radio").prop("checked",false);
This should work for desktop and mobile. I tested on Chrome and Firefox.
Based on the highest rated answer, but using newer JQuery and alot simpler implementation using $.one.
$(':radio').on("mousedown touchstart", function (e) {
var mobile = true;
if(e.type.toLowerCase() === 'mousedown'){
mobile = false;
}
var $self = $(this);
if($self.prop('checked')){
var uncheck = function(){
setTimeout(function(){
$self.prop('checked',false);
},10);
};
if(!mobile){
$self.one('mouseup', uncheck);
} else {
$self.one('touchstart', uncheck);
}
}
});
<script type="text/javascript">
$( document ).ready(function() {
$('input[type=radio]').click(function(){
if (this.previous) {
this.checked = false;
document.getElementById("nc").style.display = "block";
this.previous=false;
}
else {
this.previous = this.checked;
document.getElementById("nc").style.display = "none";
}
});
});
</script>
A javascript version featuring deselection via the for label and no double clicks.
The temporary state is attached to a parent div.
Parent.onclick = e => {
rb = e.target;
if (rb.type == "radio") {
if (Parent.rb == rb) {
rb.checked = false;
Parent.rb = null;
} else {
Parent.rb = rb
}
}
}
<div id="Parent">
<input type="radio" name="foo" id="foo1">
<label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2">
<label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3">
<label for="foo3">foo3</label>
</div>
A pure css solution (without javascript)
label > input:checked,
label > input:checked + label {
pointer-events: none;
}
#unselect {
display: none;
}
<input type="radio" name="foo" id="unselect">
<label for="unselect">
<input type="radio" name="foo" id="foo1">
<label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2">
<label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3">
<label for="foo3">foo3</label>
</label>
The radiobuttons are embedded into another radiobutton.
When a radiobutton is selected, it doesn't accepted clicks anymore, instead the underlying radiobutton captures the click.
https://jsfiddle.net/w29rem7q/
original, now obsolete solution
To each radio button a dummy radio button is attached. If a radio button is selected, an invisible dummy will be above the radio button to catch the next click.
input:not([id^=foo]) {
opacity: 0.0;
}
input[id^=foo]:checked {
position: absolute;
}
input[id^=foo]:not(:checked) + input {
display: none;
}
<input type="radio" name="foo" id="foo1">
<input type="radio" name="foo">
<label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2">
<input type="radio" name="foo">
<label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3">
<input type="radio" name="foo">
<label for="foo3">foo3</label>
Likely just for fun, while in practice js will be easier to maintain.
Also deselection via label click, would be more work arounds.
Related
we have implemented a functionality that after clicking on a button, a section appears having input and search button and when the complete section blurs when navigated using tab key, then the original button comes back. We have added onfocusout event to capture child element blur event, but it is getting triggering separately for each element i.e. when user clicks on input, then press tab key, instead of going to button, it hides the section. We want when the complete div goes out of focus then it gets hidden. Is there a way to achieve this? Also, as the code needs to be written in Angular, so won't we able to use jQuery if there might be some solution using it.
function showButton() {
var x = document.getElementById("searchWithButton");
x.classList.add("display-none");
var y = document.getElementById("search");
y.classList.remove("display-none");
}
function showSearchDiv() {
var x = document.getElementById("searchWithButton");
x.classList.remove("display-none");
var y = document.getElementById("search");
y.classList.add("display-none");
var z = document.getElementById("searchInput");
z.focus();
}
.red-border {
border: 2px solid red;
padding: 5px;
}
.display-none {
display: none;
}
<div id="searchWithButton" onfocusout="showButton()" class="red-border display-none">
<input id="searchInput" type="text">
<button>Search</button>
</div>
<button id="search" onclick="showSearchDiv()">Search</button>
What is the desired behavior to hide the searchWithButton? May I suggest any of the following: a click outside, pressing [escape]. Or focusing another element using [tab] (a little patchy)
var x = document.getElementById("searchWithButton");
var y = document.getElementById("search");
var z = document.getElementById("searchInput");
function showButton() {
x.classList.add("display-none");
y.classList.remove("display-none");
}
function showSearchDiv() {
x.classList.remove("display-none");
y.classList.add("display-none");
z.focus();
}
window.addEventListener('keydown', function(ev) {
if (ev.keyCode==27) {
showButton();
}
})
window.addEventListener('mousedown', function(ev) {
if (!ev.target.closest("#searchWithButton")) {
showButton()
}
})
document.querySelectorAll(".get-focus").forEach(function(item) {
item.addEventListener('focus', showButton)
})
.red-border {
border: 2px solid red;
padding: 5px;
}
.display-none {
display: none;
}
before: <input type="text" name="before" class="get-focus">
<br><br>
<div id="searchWithButton" class="red-border display-none">
<input id="searchInput" type="text">
<button>Search</button>
</div>
<button id="search" onclick="showSearchDiv()">Search</button>
<br><br> after: <input type="text" name="after" class="get-focus">
I have a menu which I want to display when the input is focused, so I used the focus and blur event of the input to trigger the function that either shows or hide the menu.
The problem is when I want to add events inside the menu (for example a click event), the blur event of the input is always triggered first so the click event of the menu is never triggered
Here's a sample code to illustrate my problem: https://jsfiddle.net/f7xvg1L9/27/
function hide () {
document.getElementById('box').style.display = 'none';
}
function show () {
document.getElementById('box').style.display = 'block';
}
function select () {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide)
document.getElementById('input').addEventListener('focus', show)
document.getElementById('box').addEventListener('click', select)
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
<p id='select'></p>
(the select() function is never called)
Thanks in advance
You can do a lot of things in CSS instead of Javascript for this.
Here, setup a CSS rule for the selector input:focus + #box, #box:active, which displays the box.
#box:active is there to register the click on the box before it disappears, it won't work without it.
document.getElementById('box').addEventListener('click',() => {
document.getElementById('select').innerHTML = 'selected';
});
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
input:focus + #box, #box:active{
display: block;
}
<input type='text' id='input'/>
<div id='box'>
Test
</div>
<p id='select'></p>
That's an unfortunate side effect.
But it can be solved quite easily by using different events.
Instead of using a focus/blur handler, you can just use click events for all 3 of these, since focussing the input is the same as clicking inside it. And Blurring the input is the same as clicking outside of the input.
So if we show the box onclick of the input, we can then add a different click event to the rest of the document. Inside that click event, we can check if the current click is inside the box or not and act accordingly.
var box = document.getElementById('box');
var input = document.getElementById('input');
var change_text = function() {
box.innerHTML = 'selected';
};
var outside_click = function( event ) {
if ( !box.contains(event.target) ) {
box.style.display = 'none';
document.removeEventListener('click', outside_click);
}
};
var show_box = function( event ) {
event.stopPropagation();
box.style.display = 'block';
document.addEventListener('click', outside_click);
};
box.addEventListener('click', change_text);
input.addEventListener('click', show_box);
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
Edit: But the CSS solution posted above is a way better and easier solution.
Two things you can use:
event.relatedTarget - This is only valid for focus and blur events on only contains a value if the relatedTarget has tabindex=1 or greater.
the useCapture phase of addEventListener which allows you to get at events before most things get to them.
In the example below I use them both, though I really only needed to use the event.relatedTarget since that let me see that the user was clicking on the #box and prevent from closing the box.
function hide (evt) {
if (evt.relatedTarget && evt.relatedTarget.id === 'box') {
document.getElementById('box').style.display = 'none';
document.getElementById('input').focus();
}
else {
document.getElementById('box').style.display = 'none';
}
}
function show (evt) {
document.getElementById('box').style.display = 'block';
}
function select (evt) {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide);
document.getElementById('input').addEventListener('focus', show);
document.getElementById('box').addEventListener('click', select, true);
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type="text" id="input"/>
<div id="box" tabindex="1">
Test
</div>
<p id="select"></p>
I think the most quick and simple way would be to use setTimeout in the hide function.
function hide () {
setTimeout(function(){
document.getElementById('box').style.display = 'none';
}, 300)
}
function show () {
document.getElementById('box').style.display = 'block';
}
function select () {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide)
document.getElementById('input').addEventListener('focus', show)
document.getElementById('box').addEventListener('click', select)
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
<p id='select'></p>
I would like to be able to click on the whole element, rather than just the radio button and text, in order to register the value associated with the radio button.
<div class='btn'>
<input id = '4' class='btn4' type="radio" name='1' value='' >
<label for = '4' class="label4">Question populated from jQuery goes here
</label></div>
When I wrap the input with the label, I lose the text that jQuery puts inside the element.
The function I have to populate the text is...
function populateQuestion(index) {
if (currentQuestion <=9){
$('.q_question').html(questionsArray[index]['question']);
for (var i = 0; i < 8; i++) {
$('.jumbotron').html('');
$('.btn' + (i + 1)).val(questionsArray[index]['choices'][i]).prop('checked', false);
$('.label' + (i + 1)).html(questionsArray[index]['choices'][i]);
}
} else{ quizComplete(correctAnswers)}
}
populateQuestion(currentQuestion);
Interesting little problem. I tried to do it in one line of jQuery, but quickly realized that since the elements that were changing we located inside the container, trying to click them would reset them (effectively making themselves unclickable). The solution was to add an invisible pseudo element on top of the container in CSS so that you couldn't actually click the radio (or label).
$('div.btn').on('click', function() {
$(this).children('input').prop('checked', !$(this).children('input').prop('checked'));
})
.btn {
border: 1px solid red;
padding: 12px;
position: relative;
}
.btn::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='btn'>
<input id='4' class='btn4' type="radio" name='1' value=''>
<label for='4' class="label4">Question populated from jQuery goes here
</label>
</div>
You may register a click event for the outer div and execute whatever code you want to do .
$(function(){
$("div.btn").click(function(e){
e.preventDefault();
alert("clicked");
var _this=$(this);
var radio = _this.find("input[type='radio']");
//Do something now
alert('id:'+radio.attr("id")); //Id of radio button
alert('value:'+radio.val()); //value of radio button
});
});
Here is a working sample.
I have several elements with tabindex attribute. When I click on any area of the page outside of them, they lose focus.
Current Behaviour - In regular desktop applications, if an element is not focusable, clicking on it doesn't move focus from a previous focused element.
But In HTML it's not the case: my focusable elements always lose focus, even if I click on elements with no tabindex.
Required Behaviour - Is it possible to prevent the above behaviour in HTML? I want my elements to lose focus only when I click on other focusable elements like its having in desktop application as I mentioned above.
This is a sort of hack and can be implemented in a better way.
Logic
Create a global variable lastSelectedInput to store id of last visited element.
Add a class to define boundary.
Add a click event on body and if event.path does not contains boundary element, call focus of lastSelectedInput
JSFiddle
Code
(function() {
var lastSelectedInput = "";
function bodyClick(e) {
var inside = false;
for (var i in e.path) {
if (e.path[i].className == "content") inside = true;
}
if (!inside) {
document.getElementById(lastSelectedInput).focus();
}
}
function inputFocus(e) {
lastSelectedInput = e.target.id;
e.stopPropagation()
}
function registerEvents() {
document.getElementsByTagName("body")[0].addEventListener("click", bodyClick);
var inputs = document.getElementsByTagName("input")
for (var i = 0; i < inputs.length; i++) {
inputs[i].onfocus = inputFocus;
}
}
registerEvents();
})();
.content {
margin: 15px;
background: #ddd;
border: 2px solid gray;
border-radius: 4px;
height: 200px;
width: 200px;
padding: 5px;
}
<div>
<div class="content">
<input type="text" id="txt1">
<input type="text" id="txt2">
<input type="text" id="txt3">
<input type="text" id="txt4">
<input type="text" id="txt5">
</div>
</div>
How can I apply toggleClass() to an input="checkbox" when it has been checked? I'm trying to add the class "calcButtonOn" when checked:
jQuery(function() {
var total = 0;
jQuery("input").click(function() {
total = 0;
jQuery("input:checked").not('input[value="reset"]').each(function() {
total += parseFloat(jQuery(this).val());
});
jQuery("#Totalcost").html("Save up to " + total + "%");
});
});
Select all the checkboxes with JQuery and add an event handler on change event:
jQuery("input[type=checkbox]").change(function(){
jQuery(this).toggleClass("calcButtonOn", this.checked);
});
Example JSFiddle
I'd suggest, on the assumption that you want to have the class present when the element is checked, and removed when the element is subsequently unchecked:
jQuery('input[type=checkbox]').on('change', function () {
$(this).toggleClass('active', this.checked);
});
jQuery('input[type=checkbox]').on('change', function () {
$(this).toggleClass('active', this.checked);
});
input {
display: block;
padding: 0.5em;
margin: 0 0 1em 0;
box-shadow: none;
}
input.active {
box-shadow: 0 0 1em 0.25em #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
Should any of your check-boxes be checked on page-load (via the checked attribute, for example) then it's worth further chaining the change() method (without a function callback) in order to fire the event:
jQuery('input[type=checkbox]').on('change', function () {
$(this).toggleClass('active', this.checked);
}).change();
jQuery('input[type=checkbox]').on('change', function () {
$(this).toggleClass('active', this.checked);
}).change();
input {
display: block;
padding: 0.5em;
margin: 0 0 1em 0;
box-shadow: none;
}
input.active {
box-shadow: 0 0 1em 0.25em #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" checked />
<input type="checkbox" />
<input type="checkbox" checked />
<input type="checkbox" />
References:
Attribute-equals ([attribute=value]) selector.
change().
on().
toggleClass();
Use :
$(".Your_Checkbox_Class")each(function(){
if ($(this).is(':checked') ){
$(this).toggleClass("Your_New_Class");
}
});
Explanation : Loop thru all Checkboxes (hope you have given them Class as i gave above ).And then check if its checked , if yes toggle the class.
Edit
Well your question is not 100% clear. But if you want event on click of only one checkbox and toggle only that checkbox , then use
$(".Your_Checkbox_Class").click(function(){
var id = $(this).attr("id");
$("#"+id).toggleClass("Your_New_Class");
})
Explanation : If checkbox gets checked , then toggle class. I assume you have proper classes on DOM load . Like if after Loading DOM , if a checkbox is already ticked (Came from server side), it will already have class for checked_element already.