Need help to optimze a code for radio button - javascript

$('input[type="radio"]').change(function(){
if ($('#subscribe').is(':checked')){
$("#subNow").show();
$('#oneTime').hide();
}
if ($('#one-time').is(':checked')){
$('#oneTime').show();
$("#subNow").hide();
}
});
The above code is to show and hide 2 div's on click of 2 radio buttons. I am new to jquery so would like to know is there a better way to write this same functionality.

If you setup the initial state, say #subNow { display: none; }, then just use the .toggle() method, no conditions check what-so-ever...
$('input[type="radio"]').change(function(){
$("#subNow").toggle();
$('#oneTime').toggle();
});
#subNow {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<input type='radio' name='rd' checked />1
<input type='radio' name='rd' />2
<br />
<div id="subNow">subNow</div>
<div id="oneTime">oneTime</div>
Also,
if perhaps they are followed on the markup, why not drop JS and go CSS-only??
input[type="radio"]:nth-child(2):checked ~ #oneTime,
#subNow
{
display: none;
}
input[type="radio"]:nth-child(2):checked ~ #subNow{
display: block;
}
<input type='radio' name='rd' checked />1
<input type='radio' name='rd' />2
<br />
<div id="subNow">subNow</div>
<div id="oneTime">oneTime</div>

This is exactly the way I would do this. The only other option would be to get the value of the radio buttons, but you'd essentially be doing the same thing that you already are.

One way is to use common classes and data attributes
$(".rads").on("change", '[type="radio"]', function (e) {
var show = $(this).data("show");
$(".details").hide().filter(show).show();
});
.details {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="rads">
<input type="radio" id="x" name="rad" data-show=".foo" />
<label for="x">A</label>
<input type="radio" id="y" name="rad" data-show=".bar" />
<label for="y">B</label>
</div>
<div class="foo details">Apple</div>
<div class="bar details">Bacon</div>
There is also pure CSS solutions using the :checked selector.

If you don't have any other states to worry about, you can cut the second if and place a else
$('input[type="radio"]').change(function(){
if ($('#subscribe').is(':checked')){
$("#subNow").show();
$('#oneTime').hide();
}
else{
$('#oneTime').show();
$("#subNow").hide();
}
});
You can also use switch

Related

Fade on Checkbox for Multiple Div Sections

I have a client that wants to have a checkbox that says "Mark as Compete" and once marked it makes the div with content fade. They basically want a step by step list like a recipe where users can check the box when they are done with a step and have it fade out.
I have been able to do so but not in a friendly way that someone who doesn't know code would be comfortable with editing. I am looking for some help simplifying it.
Current Code:
function ShowHideDivOne(chk_one) {
var one = document.getElementById("one");
one.style.opacity = chk_one.checked ? "0.5" : "1";
}
function ShowHideDivTwo(chk_two) {
var two = document.getElementById("two");
two.style.opacity = chk_two.checked ? "0.5" : "1";
}
function ShowHideDivThree(chk_three) {
var three = document.getElementById("three");
three.style.opacity = chk_three.checked ? "0.5" : "1";
}
div {font-wieght:bold;font-size:30px; margin-top:30px;}
<div id="one">One</div>
<input type="checkbox" id="chk_one" onclick="ShowHideDivOne(this)"/>Mark as done
<div id="two">Two</div>
<input type="checkbox" id="chk_two" onclick="ShowHideDivTwo(this)"/>Mark as done
<div id="three">Three</div>
<input type="checkbox" id="chk_three" onclick="ShowHideDivThree(this)"/>Mark as done
Right now if they wanted to add a "Four," I would have to have the ShowHideDivFour(chk_four) function preprogrammed and then they would have to go in and change all of the ids and onclicks in the div and the checkbox.
I am ok with showing them how to edit the id in the div. What I would prefer is to have a JavaScript code that works for an unlimited number of items in their list and they would only have to change the div id. I understand if they would also have to change the checkbox code but it would be preferable if they didn't.
Any help would be much appreciated.
If, somehow, your headers can come after the checkboxes, you can use the CSS sibling + selector to select it:
div {
font-size: 30px;
margin-bottom: 30px;
}
input:checked+div {
opacity: 0.5;
}
<label for="chk_one">Mark as done</label>
<input type="checkbox" id="chk_one" />
<div id="one">One</div>
<label for="chk_two">Mark as done</label>
<input type="checkbox" id="chk_two" />
<div id="two">Two</div>
<label for="chk_three">Mark as done</label>
<input type="checkbox" id="chk_three" />
<div id="three">Three</div>
Here is a complete, CSS-only solution that uses the above and a little CSS flexbox hack to reverse the display order of the header and checkbox, if you're fine with wrappers:
div.wrapper {
display: flex;
/* 👇 display elements in reverse order */
flex-direction: column-reverse;
}
div.item {
font-size: 30px;
margin-top: 30px;
}
input {
width: fit-content;
}
input:checked~div {
opacity: 0.5;
}
<!-- 👇 notice that the checkboxes come BEFORE
the text, but are displayed as if they are after -->
<div class="wrapper">
<label for="chk_one">Mark as done</label>
<input type="checkbox" id="chk_one" />
<div id="one" class="item">One</div>
</div>
<div class="wrapper">
<label for="chk_two">Mark as done</label>
<input type="checkbox" id="chk_two" />
<div id="two" class="item">Two</div>
</div>
<div class="wrapper">
<label for="chk_three">Mark as done</label>
<input type="checkbox" id="chk_three" />
<div id="three" class="item">Three</div>
</div>
Any "normal" solution (not as hacky as this) would only be attainable through JavaScript.
EDIT: if you're OK with using JS, here's something that looks marginally better by using direct element references in inline event listeners:
div {
font-size: 30px;
margin-top: 30px;
}
<div id="one">One</div>
<input type="checkbox" id="chk_one" onclick="one.style.opacity = (one.style.opacity == 0.5 ? 1 : 0.5)" />
<label for="chk_one">Mark as done</label>
<div id="two">Two</div>
<input type="checkbox" id="chk_two" onclick="two.style.opacity = (two.style.opacity == 0.5 ? 1 : 0.5)" />
<label for="chk_two">Mark as done</label>
<div id="three">Three</div>
<input type="checkbox" id="chk_three" onclick="three.style.opacity = (three.style.opacity == 0.5 ? 1 : 0.5)" />
<label for="chk_three">Mark as done</label>
You can simplify the code by adding a class name to the checkbox and adding an event listener to all elements of that class:
document.querySelectorAll('.markChk').forEach(el => {
el.addEventListener('click', function(event) {
var divID = this.parentElement.previousElementSibling;
divID.style.opacity = el.checked ? "0.5" : "1";
});
});
div {font-weight: bold; font-size: 30px; margin-top: 30px;}
<div id="one">One</div>
<label><input type="checkbox" id="chk_one" class="markChk" /> Mark as done </label>
<div id="two">Two</div>
<label><input type="checkbox" id="chk_two" class="markChk" /> Mark as done </label>
<div id="three">Three</div>
<label><input type="checkbox" id="chk_three" class="markChk" /> Mark as done </label>
Notes:
this.parentElement.previousElementSibling traverses from the checkbox to the previous div
notice the <label>, which allows the user to click on the label, not just the checkbox
to further simplify you likely want to generate the div and checkbox list dynamically
jQuery makes it easier than native JS to manipulate the DOM

How to select first radio as default with jquery or javascript

I have a code like this.
My main goal is when I click a radio button I show a content.
However,
I would like the first radio to be selected as default and the div content is shown.
However, now in order to show the first content I have to click the radio button.
How can I achieve that?
BTW I am not dependent on Jquery. the whole think can be even written with native Javascript.
$(':radio').change(function (event) {
var id = $(this).data('id');
$('#' + id).addClass('none').siblings().removeClass('none');
});
.none {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name='thing' value='valuable' data-id="bank" />
<input type="radio" name='thing' value='valuable' data-id="school" />
<hr />
<div id="bank" class="none">Bank</div>
<div id="school" class="none">School</div>
The simplest way to achieve this is to set the checked attribute in the HTML then trigger the change event on that element when the page loads, like this:
$(':radio').change(function(e) {
var id = $(this).data('id');
$('#' + id).addClass('none').siblings().removeClass('none');
}).filter(':checked').trigger('change');
.none {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name='thing' value='valuable' data-id="bank" checked="true" />
<input type="radio" name='thing' value='valuable' data-id="school" />
<hr />
<div id="bank" class="none">Bank</div>
<div id="school" class="none">School</div>
Alternatively, if you didn't want to amend the HTML you can set the first radio to be checked programmatically, like this:
$(':radio').change(function(e) {
var id = $(this).data('id');
$('#' + id).removeClass('none').siblings('div').addClass('none');
}).first().prop('checked', true).trigger('change');
.none {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name='thing' value='valuable' data-id="bank" />
<input type="radio" name='thing' value='valuable' data-id="school" />
<hr />
<div id="bank" class="none">Bank</div>
<div id="school" class="none">School</div>
You can set checked to true and then trigger the change event like
$("input[data-id='bank']").prop("checked", true).trigger("change")
Here is snippet
$(':radio').change(function (event) {
var id = $(this).data('id');
$('#' + id).addClass('none').siblings().removeClass('none');
});
$("input[data-id='bank']").prop("checked", true).trigger("change")
.none {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name='thing' value='valuable' data-id="bank" />
<input type="radio" name='thing' value='valuable' data-id="school" />
<hr />
<div id="bank" class="none">Bank</div>
<div id="school" class="none">School</div>
This should do the trick:
// Get all radios, then simply emulate a click on the first one
var radios = document.getElementsByTagName('input');
radios[0].click();

add highlight class to the label of a checked check box via a button

I have checked all over stack overflow, but they're not exactly what I need.
I have checkboxes with associated labels
<p>
<input type="checkbox" name="animals" value="dog" id="dg" />
<label for="dg">Dog</label>
</p>
<p>
<input type="checkbox" name="animals" value="cat" id="ct" />
<label for="ct">Cats</label></p>
<p>
<p><input type="button" id='bt' value="Record" /></p>
There is also a button, when the button is clicked, if the checkbox is checked, the label associated with it has a highlight class added to the label. I already have the highlight class written I am just having trouble applying it using the addClass method.
I have:
$(':checkbox:checked').addClass('highlight');
but it does nothing
Let's say this is your HTML:
<p>
<input type="checkbox" name="animals" value="dog" id="dg" />
<label for="dg">Dog</label>
</p>
<p>
<input type="checkbox" name="animals" value="cat" id="ct" />
<label for="ct">Cats</label></p>
<p>
<p>
<button id="btnSubmit">Click Me!</button>
</p>
and this is your CSS class:
.highlight {
background-color: yellow;
}
One thing you could do is loop through each checked checkbox and just apply the class using the label[for=*] property:
$('#btnSubmit').click(function() {
$('input:checked').each(function () {
$("label[for='" + $(this).attr('id') + "']").addClass("highlight");
});
});
However, using the above method, you're not allowing a way to remove the highlight class should you uncheck a box and hit Submit again. I would prefer the below method... which loops through ALL checkboxes, and tests them to determine if they're checked or not:
$('#btnSubmit').click(function() {
$('input[type=checkbox]').each(function () {
if (this.checked) {
$("label[for='" + $(this).attr('id') + "']").addClass("highlight");
} else {
$("label[for='" + $(this).attr('id') + "']").removeClass("highlight");
}
});
});
Try this Fiddle
I'm trying to find a way to just reference the label of all checked checkboxes in one line of code. Because if you could do that, you can just do away with the looping and the if statements. I'll keep researching, and if I find it, I'll edit my post accordingly.
Update: Okay, I think I understand what you need. See updated example.
The trick is knowing how to find the label and checkbox associated with the button. Since the buttons were not included in the question code, I had to guess. If the button is elsewhere, you can experiment using these jQuery traversing methods.
$(document).ready(function(){
$('#mybutt').click(function(){
var chkboxes = $('input[type=checkbox]');
$(chkboxes).each(function(){
if ( $(this).is(':checked') ){
$(this).parent().find('label').addClass('highlight');
}else{
$(this).parent().find('label').removeClass('highlight');
}
});
});
}); //END document.ready
.highlight{background:red;color:yellow;padding:2px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>
<input type="checkbox" name="animals" value="dog" id="dg" />
<label for="dg">Dog</label>
</p>
<p>
<input type="checkbox" name="animals" value="cat" id="ct" />
<label for="ct">Cats</label>
<p>
<button id="mybutt">Go</button>
I guess, what you are trying to do is to change a class, after the value of your checkbox has changed, easiest way to do this is using the onChange event, you can also bind the event with jQuery using $('#your_checkbox').on('change', function(){})
$('[type="checkbox"]').on('change', function() {
if (!$(this).attr('checked')) {
$(this).attr('checked', 'checked');
$(this).parent().addClass('checked');
} else if ($(this).attr('checked') === 'checked') {
$(this).removeAttr('checked', '');
$(this).parent().removeClass('checked');
}
});
$('#btnSubmit').on('click', function() {
var inputs = $(this).parent().parent().find('[type="checkbox"]')
inputs.each(function(){
if ($(this).attr('checked') === 'checked') {
$(this).parent().addClass('iam-checked');
}
else {
$(this).parent().removeClass('iam-checked');
}
});
});
.checked {
border-bottom: 1px solid green;
}
.iam-checked {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<input type="checkbox" name="animals" value="dog" id="dg" />
<label for="dg">Dog</label>
</p>
<p>
<input type="checkbox" name="animals" value="cat" id="ct" />
<label for="ct">Cats</label></p>
<p>
<p>
<button id="btnSubmit">Click Me!</button>
</p>
This is a little late, but I was surprised that no one mentioned the next method. You are trying to style the label after the checkbox, not the checkbox itself. In other words, the label is the next sibling of the checkbox.
I think this is the most jQuery way to solve this so wanted to add my two cents.
$("#bt").on("click", function() {
$(":checked").each(function() {
$(this).next().addClass("highlight");
});
});
.highlight { background: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<input type="checkbox" name="animals" value="dog" id="dg" />
<label for="dg">Dog</label>
</p>
<p>
<input type="checkbox" name="animals" value="cat" id="ct" />
<label for="ct">Cats</label></p>
<p>
<p><input type="button" id='bt' value="Record" /></p>

How to toggle div visibility using radio buttons?

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>

jQuery Custom Radio Buttons not working as radio buttons

I am using JQuery and custom images for custom radio buttons. Right now, it would work as a checkbox. I need it to work as a radio.
When I click on either of both radio's both will get ticked instead of one at a time. Am I missing something?
HTML:
<label for="radio1">
<img src="radio_unchecked.png" style="vertical-align:middle" />
<input name="radiogroup" type="radio" id="radio1" style="display:none;">
</label>
<label for="radio2">
<img src="radio_unchecked.png" style="vertical-align:middle" />
<input name="radiogroup" type="radio" id="radio2" style="display:none;">
</label>
JavaScript:
$(document).ready(function() {
$("#radio1").change(function() {
if (this.checked) {
$(this).prev().attr("src", "radio_checked.png");
} else {
$(this).prev().attr("src", "radio_unchecked.png");
}
});
$("#radio2").change(function() {
if (this.checked) {
$(this).prev().attr("src", "radio_checked.png");
} else {
$(this).prev().attr("src", "radio_unchecked.png");
}
});
});
The radio buttons are working correctly (proof), but your logic for updating the images is incorrect. Both images have to change when either radio button is clicked, since both values change (and the change handler is only fired on the one that you clicked). Have a single change handler used by both radio buttons, and set both images on every change, e.g.:
$('#radio1, #radio2').change(function() {
var r;
r = $("#radio1");
r.prev().attr("src", r[0].checked ? checkedImage : uncheckedImage);
r = $("#radio2");
r.prev().attr("src", r[0].checked ? checkedImage : uncheckedImage);
});
Live example
Side note: If your target browsers support the :checked pseudo-class (IE only has this as of IE9, not in IE8 or earlier) and adjacent sibling combinator from CSS3, you can do this entirely with CSS:
HTML:
<input type="radio" name="radiogroup" id="radio1" style="display: none">
<label for="radio1"></label>
<input type="radio" name="radiogroup" id="radio2" style="display: none">
<label for="radio2"></label>
CSS:
#radio1 + label, #radio2 + label {
display: inline-block;
background-image: url(radio_unchecked.png);
width: 32px; /* Whatever matches the images */
height: 32px; /* Whatever matches the images */
}
#radio1:checked + label, #radio2:checked + label {
background-image: url(radio_checked.png);
}
Live example
Or alternately (it's just the selectors that are different):
input[name="radiogroup"] + label {
display: inline-block;
background-image: url(radio_unchecked.png);
width: 32px; /* Whatever matches the images */
height: 32px; /* Whatever matches the images */
}
input[name="radiogroup"]:checked + label {
background-image: url(radio_checked.png);
}
The change event fires only for the radio button that was changed by the user, not for any other radio buttons that may be automatically unchecked in that process.
You should update all of the images when the change event for any radio button fires:
var radios = $('input:radio');
radios.change(function() {
radios.filter(':checked').prev().attr("src", "radio_checked.png");
radios.filter(':not(:checked)').prev().attr("src", "radio_unchecked.png");
});
This will work for any number of radio buttons. A reference to the original collection of radio inputs is kept in radios (this is more efficient). When any of the <label>s is clicked, the event handler fires. Inside the handler, filter() is used to separate the radios collection into checked and the unchecked radio inputs.
Working demo: http://jsbin.com/ibaqid/2/edit#javascript,live
This should work:
<label for="radio1">
<img src="radio_unchecked.png" style="vertical-align:middle" />
<input name="radiogroup" type="radio" id="radio1" style="display:none;">
</label>
<label for="radio2">
<img src="radio_unchecked.png" style="vertical-align:middle" />
<input name="radiogroup" type="radio" id="radio2" style="display:none;">
</label>
<script>
$(document).ready(function(){
$("input[name=radiogroup]").change(function() {
$("input[name=radiogroup]").prev().attr("src", "radio_unchecked.png");
$(this).prev().attr("src", "radio_checked.png");
});
});
</script>
Try replacing:
this.checked
with this:
$(this).is(':checked')

Categories

Resources