I'm looking for a smarter way to reuse functions with a similar purpose. For example I would want to change different radio buttons that toggle a hide class on different divs.
JSFiddle Link
How would you mathe JQuery to a reusable function,
<form>
<label>Enable One</label>
<input type="radio" name="one" value="yes" checked class="eOne">Yes
<input type="radio" name="one" value="no" class="enBg">No</form>
<form>
<label>Enable Two</label>
<input type="radio" name="two" value="yes" checked class="eTwo">Yes
<input type="radio" name="two" value="no" class="enBrand">No</form>
<form>
<label>Enable Three</label>
<input type="radio" name="three" value="yes" checked class="eThree">Yes
<input type="radio" name="three" value="no" class="enS">No</form>
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
div {
width: 100px;
height: 100px;
}
.one {
background: red;
}
.two {
background: green;
}
.three {
background: blue;
}
.hide {
display: none;
}
$(".eOne").change(function () {
$('.one').toggleClass("hide");
});
$(".eTwo").change(function () {
$('.two').toggleClass("hide");
});
$(".eThree").change(function () {
$('.three').toggleClass("hide");
});
Also, for some reason, in the demo (but not in my live version) the change function doesn't toggle the class unless I click no and then yes.
use classes for your html:
<form>
<label>Enable One</label>
<input type="radio" name="one" value="yes" class="one" checked />Yes
<input type="radio" name="one" value="no" class="one" />No
</form>
<form>
<label>Enable Two</label>
<input type="radio" name="two" value="yes" class="two" checked />Yes
<input type="radio" name="two" value="no" class="two" />No
</form>
<div class="one"></div>
<div class="two"></div>
write functions for your javascript:
/*
* Bind a change event handler to a radio-input
* #param cls - selector string to input AND to-change div
*/
function bindChangeHandler(cls) {
$('input.' + cls).change(function () {
var element = $(this),// get Input element
name = element.val(), // get Input element name
is_checked = element.prop('checked'); // get state of radio box
// return if a deselect triggered the event (may be unnecessary)
if (!is_checked) return;
// change class of div-box according to checked radio-box
if (name == 'yes') {
$('div.' + cls).removeClass('hide');
} else {
$('div.' + cls).addClass('hide');
}
});
}
$(document).ready(function(){
bindChangeHandler('one');
bindChangeHandler('two');
});
HTML
<form>
<label>Enable One</label>
<input type="radio" name="one" value="yes" class="eOne" checked>Yes
<input type="radio" name="one" value="no" class="enBg">No
<br /><label>Enable Two</label>
<input type="radio" name="two" value="yes" checked class="eTwo">Yes
<input type="radio" name="two" value="no" class="enBrand">No
<br /><label>Enable Three</label>
<input type="radio" name="three" value="yes" checked class="eThree">Yes
<input type="radio" name="three" value="no" class="enS">No
</form>
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
I haven't changed any of your CSS but changed your Javascript code. Have a look at this.There is no need to use the class .hideclass as we have already an inbuilt method for this. the toggle() method. if you want it to hide as soon as you click the radio button then just change all the toggle() to toggle(50). This change will hide the div boxes in just 50 milli seconds.
$("input[name='one']").change(function(){
$(".one").toggle();//add a number in toggle method to have a small animation effect :)
});
$("input[name='two']").change(function(){
$(".two").toggle();
});
$("input[name='three']").change(function(){
$(".three").toggle();
});
I have also updated the code on js fiddle. May be this is helpful for you :)
I like cbergmiller's answer. Here is the same rewritten with a callback allowing a more general use:
function hide(cls, name) {
// change class of div-box according to checked radio-box
if (name == 'yes') {
$('div.' + cls).removeClass('hide');
} else {
$('div.' + cls).addClass('hide');
}
}
/*
* Bind a change event handler to a radio-input
* #param cls - selector string to input AND to-change div
*/
function bindChangeHandler(cls, callback) {
$('input.' + cls).change(function () {
var element = $(this),// get Input element
name = element.val(); // get Input element name
callback(cls, name);
});
}
$(document).ready(function(){
bindChangeHandler('one', hide);
bindChangeHandler('two', hide);
});
Related
I'm using 2 groups of radio buttons lets call it 1.1 1.2 and 2.1 2.1 (one radio button of the second group is always checked, depending on which one of the first group is checked, the other one is hidden).
I can't understand why I need to make a double click on the radio button to uncheck it when both radio buttons are checked. I want to click just one time to "uncheck" it.
function show() {
swich();
}
function swich() {
$('input[type="radio"]').change(function(){
$('[data-group="' + $(this).data('group') + '"]').prop('checked', this.checked);
});
}
var checkedradio = false;
var radioState = [];
$("input[type=radio]").on('click', function(e) {
if (radioState[this.name] === this) {
this.checked = false;
radioState[this.name] = null;
} else {
radioState[this.name] = this;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input data-group="A" id="radio1" required type="radio" value="Yes" name="group1">
<input data-group="B" id="radio2" required type="radio" value="No" name="group1">
<div id="someId1">
<input data-group="A" id="radio3" type="radio" name="group2" value="Yes" onclick="show()">
</div>
<div id="someId2">
<input data-group="B" id="radio4" type="radio" name="group2" value="No" onclick="show()">
</div>
CAVEAT
We do not recommend you take this approach as it breaks the standard UX for radio buttons.
Your issue is because you re-use checkedradio for both checks.
So:
click group A.1 - sets checkedradio = A.1
click group A.1 again, works ok and unchecks
click group A.1 - sets checkedradio = A.1
click group B.1 - sets checkedradio = B.1
click group A.1 (checked) - it's not A.1, so doesn't appear to work, set checkedradio = A.1
click group A.1 2nd time, works ok
You need a different variable for each group.
As multiple variables become very messy very quickly (and lots of DRY), you can use an array:
var radioState = [];
$(":radio").on('click', function(e) {
//console.log(radioState[this.name])
if (radioState[this.name] === this) {
this.checked = false;
radioState[this.name] = null;
} else {
radioState[this.name] = this;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input required type="radio" value="Yes" name="group1">
<input required type="radio" value="No" name="group1">
<hr/>
<input type="radio" name="group2" value="Yes">
<input type="radio" name="group2" value="No">
Code based on this answer expanded to use an array.
I was able to achieve the desired result based on this code.
function show() {
swich();
}
function swich() {
$('input[type="radio"]').change(function(){
$('[data-group="' + $(this).data('group') + '"]').prop('checked', this.checked);
});
}
function toggleRadio(event)
{
if(event.target.type === 'radio' && event.target.checked === true)
{
setTimeout(()=>{ event.target.checked = false; },0);
}
}
document.addEventListener('mouseup', toggleRadio);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input data-group="A" id="radio1" required type="radio" value="Yes" name="group1">
<input data-group="B" id="radio2" required type="radio" value="No" name="group1">
<div id="someId1">
<input data-group="A" id="radio3" type="radio" name="group2" value="Yes" onclick="show(this)">
</div>
<div id="someId2">
<input data-group="B" id="radio4" type="radio" name="group2" value="No" onclick="show(this)">
</div>
I have a radio button that is checked by default. What I am trying to accomplish is just to toggle it on/off with a click and simple logic but I do not understand what I'm doing wrong.
Here is my HTML:
<input type="radio" id="member" name="member" value="member" checked>
<label for="member" >Member Reported</label>
And here is my jQuery:
$('#member').click((e) => {
console.log('click')
if($('#member').is(':checked')) {
$('#member').prop('checked',false)
}
})
This works great, but I noticed that it's not changing the DOM once clicked, and furthermore, when I try to add the prop to true (like below), it's not checking back on the GUI.
Here's the DOM:
$('#member').click((e) => {
console.log('click')
if($('#member').is(':checked')) {
$('#member').prop('checked',false)
} else if (!$('#member').is(':checked')) {
$('#member').prop('checked',true)
}
})
How about this? Is this what you are willing?
$('#member + label').click((e) => {
console.log($('#member')[0].checked);
if($('#member')[0].checked) {
$('#member')[0].checked = false;
} else{
$('#member')[0].checked = true;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" id="member" name="member" value="member" checked >
<label for="" >Member Reported</label>
As long checked exist in element, it will stay checked. You will have to remove it via jquery to make it work.
You can check functioning here.
<input type="radio" checked>
<br>
<input type="radio" checked="true">
<br>
<input type="radio" checked="false">
<br>
<input type="radio">
I think that's the way it should be.
$('.radios').click((e) => {
$('.radios').each(function (i) {
$(this).removeAttr('checked')
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" id="member" class="radios" name="member" value="member" >
<label for="member" >Member Reported</label><br/>
<input type="radio" id="member2" class="radios" name="member" value="member" >
<label for="member2" >Member Reported2</label><br/>
<input type="radio" id="member3" class="radios" name="member" value="member" checked>
<label for="member3" >Member Reported3</label><br/>
I Need to create two forms with radio buttons as following bellow and then, when change checked, I need to change automatically in the second form (jquery or javacript):
<form id="form-a" name="form-a">
<input type="radio" name="name-a" id="id-a" value="Yes" checked="checked" />
<input type="radio" name="name-b" id="id-b" value="No" />
</form>
<form id="form-b" name="form-b">
<input type="radio" name="name-c" id="id-c" value="Yes" checked="checked" />
<input type="radio" name="name-d" id="id-d" value="No" />
</form>
Just change the name attribute values on the radio buttons to group them and then just add an event listener to listen for changes.
Here is an example.
var radioBtns = document.querySelectorAll("input[type=radio]");
function radioChangeHndl(evt) {
radioBtns.forEach(function(radioBtn) {
radioBtn.checked = '';
if(radioBtn.value === this.value) {
radioBtn.checked = 'true'
}
}.bind(this))
}
radioBtns.forEach(function(radioBtn) {
radioBtn.addEventListener('change', radioChangeHndl);
});
<form id="form-a" name="form-a">
<input type="radio" name="name-a" id="id-a" value="Yes" checked="checked" />
<input type="radio" name="name-b" id="id-b" value="No" />
</form>
<form id="form-b" name="form-b">
<input type="radio" name="name-c" id="id-c" value="Yes" checked="checked" />
<input type="radio" name="name-d" id="id-d" value="No" />
</form>
EDIT: Changed the HTML and JS. Know you just have to add the classes to the Radiobuttons. Tsted with Firefox, Chrome and IE 11. Maybe its not working because jquery is not loaded? If you Add jquery in the Javascript-Part, its working.
My solution is working in both ways. Click on form-a and form-b
HTML:
I changed the button names for grouping. JQuery selector is the classname i added.
<body onload="bodyLoad()">
<form id="form-a" name="form-a">
<input type="radio" class="radioA" name="name-a" id="id-a" value="Yes" checked="checked" />
<input type="radio" class="radioB" name="name-b" id="id-b" value="No" />
</form>
<form id="form-b" name="form-b">
<input type="radio" class="radioA" name="name-c" id="id-c" value="Yes" checked="checked" />
<input type="radio" class="radioB" name="name-d" id="id-d" value="No" />
</form>
JS:
I decided to use click event.
function bodyLoad () {
$("input:radio").click(function() {
var myClass = $(this).attr("class");
$("input:radio").prop('checked',false);
$("." + myClass).prop('checked',true);
});}
I'm working on a project in which I have to toggle the visibility of a <div>.
I've got the following code:
<input type="radio" name="type" value="1"> Personal
<input type="radio" name="type" value="2"> Business
<div class="business-fields">
<input type="text" name="company-name">
<input type="text" name="vat-number">
</div>
I would like to togle the business-fields div. So, if none of the radio buttons, or the 'personal' radio button is selected: The div should be hidden. If the 'business' radio button is selected, I want it to show.
Currently, I am using this code:
$("input[name='type']").click(function() {
var status = $(this).val();
if (status == 2) {
$(".business-fields").show();
} else {
$(".business-fields").hide();
}
});
However, I was wondering if I can do this using the .toggle() function.
I usually tend not to use JS if possible, therefore here comes a HTML+CSS way approach.
.bussines-type .business-fields {
display: none;
}
.bussines-type input[value="2"]:checked ~ .business-fields {
display: block;
}
<div class="bussines-type">
<input id="bt1" type="radio" name="type" value="1">
<label for="bt1"> Personal</label>
<input id="bt2" type="radio" name="type" value="2">
<label for="bt2"> Business</label>
<div class="business-fields">
<input type="text" placeholder="Company name" name="company-name">
<input type="text" placeholder="Vat number" name="vat-number">
</div>
</div>
The ~ stands for any siblings, that are after the element we defined before the ~ sign.
I'd suggest using the change event, and supplying a Boolean switch to the toggle() method, which will show the jQuery collection of elements if the switch evaluates to true, and hide them if it evaluates to false:
// select the relevant <input> elements, and using on() to bind a change event-handler:
$('input[name="type"]').on('change', function() {
// this, in the anonymous function, refers to the changed-<input>:
// select the element(s) you want to show/hide:
$('.business-fields')
// pass a Boolean to the method, if the numeric-value of the changed-<input>
// is exactly equal to 2 and that <input> is checked, the .business-fields
// will be shown:
.toggle(+this.value === 2 && this.checked);
// trigger the change event, to show/hide the .business-fields element(s) on
// page-load:
}).change();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>
<input type="radio" name="type" value="1">Personal</label>
<label>
<input type="radio" name="type" value="2">Business</label>
<div class="business-fields">
<input type="text" name="company-name">
<input type="text" name="vat-number">
</div>
Incidentally, note I've also wrapped the associated text, to indicate the radio-button's purpose, inside of a <label> element to directly associate that text with the <input>, so clicking the text checks the <input> automatically.
References:
change().
on().
toggle().
JS Fiddle
Try this one
<input type="radio" name="type" value="1" checked ="true"> Personal
<input type="radio" name="type" value="2"> Business
<div class="business-fields">
<input type="text" name="company-name">
<input type="text" name="vat-number">
</div>
.business-fields{
display: none;
}
$("input[name='type']").change(function() {
$(".business-fields").toggle();
});
You may use like this:
$("input[name='type']").change(function() {
var status = $(this).val();
if (status != 2) {
$(".business-fields").hide();
} else {
$(".business-fields").show();
}
});
.show and .hide are pretty slow.
https://twitter.com/paul_irish/status/564443848613847040
It's better to toggle a css class on and off with javascript. Set the css of the class to {visibility: hidden} or {display: none}
use the below code
<script>
$(function(){
$(":radio[value=1]").click(function(){
var isVisible = $( ".business-fields" ).is( ":visible" );
if(isVisible==true)
$('.business-fields').toggle();
});
$(":radio[value=2]").click(function(){
var isVisible = $( ".business-fields" ).is( ":visible" );
if(isVisible==false)
$('.business-fields').toggle();
});
});
</script>
AND HTML is-
<input name="type" type="radio" value="1" >Personal
<input type="radio" name="type" value="2" checked="checked"> Business
<div class="business-fields">
<input type="text" name="company-name">
<input type="text" name="vat-number">
</div>
Possibly a more elegant solution, It's a bit more readable in my opinion, and and as #Ollie_W points out it might be more performant that toggle (show/hide).
$('input[name="type"]').on('change', function(event) {
var radioButton = $(event.currentTarget),
isBusiness = radioButton.val() === 'business' && radioButton.prop('checked');
$('.business-fields').toggleClass('hidden', !isBusiness);
}).change();
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>
<input type="radio" name="type" value="personal">Personal</label>
<label>
<input type="radio" name="type" value="business">Business</label>
<div class="business-fields hidden">
<input type="text" name="company-name">
<input type="text" name="vat-number">
</div>
Html Code: -
<input type="radio" name="radio" id="radio" value="1" onclick="validate()"> For Yourself</input> </p></br>
<p>
<input type="radio" name="radio" id="radio" value="2" onclick="validate()"> For Users</input>
</p>
And JavaScript Code : -
function validate()
{
var btn_value=document.getElementById("radio").value;
if(btn_value==true)
{
alert(btn_value);
}
}
Now, whenever I am trying to print the value of radio button. It is always printing value as 1.
So, Now I don't understand what exactly am I missing here...
Thanx in advance for your help.
Elements ID should be unique. I modified your HTML and JS part and check below
Try this
HTML
<p>
<input type="radio" name="radio" id="radio1" value="1" onclick="validate(this)"> For Yourself</input> </p></br>
<p>
<input type="radio" name="radio" id="radio2" value="2" onclick="validate(this)"> For Users</input>
</p>
JavaScrpit
function validate(obj)
{
var btn_value=obj.value;
if(btn_value==true)
{
alert(btn_value);
}
}
first of all never use a DOMID twice in your html!
remove them.... only use dublicated names!
<input type="radio" name="radio" value="1" onclick="validate()"> For Yourself</input> </p></br>
<p>
<input type="radio" name="radio" value="2" onclick="validate()"> For Users</input>
</p>
with the js check every element with the name attribute!
function validate() {
var elements = document.getElementsByName("radio");
for(var n = 0; n < elements.length; n++) {
if(elements[n].checked === true) {
alert(elements[n].value);
}
}
}
if you use your validate method ONLY in the onclick you can pass the domelement in the validate methode like this:
<input type="radio" name="radio" value="1" onclick="validate(this)"> For Yourself</input> </p>
and your js:
function validate(domElement) {
if(domElement.checked === true) {
alert(elements[n].value);
}
}
try this
<input type="radio" name="radio" id="radio" value="1" onclick="validate(this)"> For Yourself</input> </p></br>
<p>
<input type="radio" name="radio" id="radio" value="2" onclick="validate(this)"> For Users</input>
</p>
function validate(ele)
{
alert(ele.value);
}
IDs MUST be unique, it's a mistake to give it the same id.
You can give the IDs a running number (- radio1,radio2 etc) and loop through them to check which one was selected.