I'm trying to use Bootstrap's collapse functionality to show/hide divs based on which radio button is checked. I was able to get things to work fine when I don't use Bootstrap's collapse function, however, in order to give a more consistent feel I'd like to take advantage of this function.
Here's a snippet of the HTML in question:
<div class="col-xs-12 form-group">
<label class="radio-inline">
<input type="radio" id="send-now-radio" name="when" value="send-now" checked> <strong>Send Now</strong>
</label>
<label class="radio-inline">
<input type="radio" id="pickup-radio" name="when" value="pickup"> <strong>Hold for pickup</strong>
</label>
<label class="radio-inline">
<input type="radio" id="fax-radio" name="when" value="fax"> <strong>Fax</strong>
</label>
<label class="radio-inline">
<input type="radio" id="email-radio" name="when" value="email"> <strong>Email</strong>
</label>
</div>
<div class="col-xs-12">
<div id="send">Send</div>
<div id="pickup">Pickup</div>
<div id="fax">Fax</div>
<div id="email">Email</div>
</div>
And here's my javascript code:
$(document).ready(function()
{
// Hide all but one method div (since all are shown in case the user has JS disabled)
$('#send').show();
$('#pickup').hide();
$('#fax').hide();
$('#email').hide();
// Attach to the radio buttons when they change
$('#send-now-radio, #pickup-radio, #fax-radio, #email-radio').on('change', function () {
// Make sure that this change is because a radio button has been checked
if (!this.checked) return
// Check which radio button has changed
if (this.id == 'send-now-radio') {
$('#send').collapse('show');
$('#pickup').collapse('hide');
$('#fax').collapse('hide');
$('#email').collapse('hide');
} else if (this.id == 'pickup-radio') {
$('#send').collapse('hide');
$('#pickup').collapse('show');
$('#fax').collapse('hide');
$('#email').collapse('hide');
} else if (this.id == 'fax-radio') {
$('#send').collapse('hide');
$('#pickup').collapse('hide');
$('#fax').collapse('show');
$('#email').collapse('hide');
} else // if (this.id == 'email-radio') {
$('#send').collapse('hide');
$('#pickup').collapse('hide');
$('#fax').collapse('hide');
$('#email').collapse('show');
}
});
};
Here's a link to a JS fiddle with all of this: http://jsfiddle.net/DTcHh/156/
Unfortunately I'm missing something, cause the behavior is weird and not what I would expect.
First of all, excellent question. You provided code, made it clear what you tried, etc. Love it.
I forked your JSFiddle, and came up with this:
http://jsfiddle.net/emptywalls/EgVF9/
Here's the Javascript:
$('input[type=radio]').on('change', function () {
if (!this.checked) return
$('.collapse').not($('div.' + $(this).attr('class'))).slideUp();
$('.collapse.' + $(this).attr('class')).slideDown();
});
I wouldn't recommend using the collapse functionality from Bootstrap, it relies on a very different DOM structure from what you need. My fiddle uses just jQuery to accomplish what you need. My approach was to pair the radio buttons and divs with classes, so you can DRY up your code.
As #emptywalls mentioned, the Bootstrap collapse function won't work. I tried it and it almost does, except that it is based on clicking the source element, not it's state. A radio button needs to pay attention to it's state.
But I wanted something that allowed me to mark up the element with data tags and have it inherit the functionality, as the bootstrap collapse does. So I came up with this:
<input data-target="#send" data-toggle="radio-collapse" id="send_now_radio" name="when" type="radio" value="send-now">
<div id="send" class="collapse">Send</div>
And then have this included once in your site and it will apply to all such buttons.
$('input[type=radio][data-toggle=radio-collapse]').each(function(index, item) {
var $item = $(item);
var $target = $($item.data('target'));
$('input[type=radio][name="' + item.name + '"]').on('change', function() {
if($item.is(':checked')) {
$target.collapse('show');
} else {
$target.collapse('hide');
}
});
});
This uses the collapse function of Bootstrap for the animation. You could just as easily use jQuery hide() and show().
Unless I'm mistaken, #jwadsack code won't work if you have another group of radio buttons with a different name attribute.
That's because the $item and $target variables are declared globally. The $item variable will be overidded by the last group and only this one will hide/show the collaspe.
Adding var before the variable definition seems to fix the problem.
The code is then
$('input[type=radio][data-toggle=radio-collapse]').each(function(index, item) {
var $item = $(item);
var $target = $($item.data('target'));
$('input[type=radio][name="' + item.name + '"]').on('change', function() {
if($item.is(':checked')) {
$target.collapse('show');
} else {
$target.collapse('hide');
}
});
});
Related
I'm working on a project where a button needs to be disabled until a hyperlink is clicked and a checkbox is checked. I currently have the checkbox part down using jQuery:
$('#tc-checkbox').change(function(){
if($(this).is(":checked")) {
$('#tc-btn').removeClass('tc-disable');
} else {
$('#tc-btn').addClass('tc-disable');
}
});
But I also need to set it up so the class of tc-disable is still on the button until an anchor tag is clicked as well. I've never really done this before where a link needs to be clicked before removing a class and couldn't find what I was looking for as I was Googling for an answer.
Hope the code below helps. I also added console out put so you can track the value. Another option is use custom attribute on link element instead of javascript variable to track if the link is clicked.
var enableLinkClicked = false;
$('#tc-link').click(function() {
enableLinkClicked = true;
console.log("link clicked\ncheckbox value: " + $($('#tc-checkbox')).is(":checked"));
console.log("link clicked: " + enableLinkClicked);
if ($('#tc-checkbox').is(":checked")) {
$('#tc-btn').removeClass('tc-disable');
}
});
$('#tc-checkbox').change(function() {
console.log("checkbox clicked\ncheckbox value: " + $(this).is(":checked"));
console.log("link clicked: " + enableLinkClicked);
if ($(this).is(":checked") && enableLinkClicked) {
$('#tc-btn').removeClass('tc-disable');
} else {
$('#tc-btn').addClass('tc-disable');
}
});
#tc-btn.tc-disable {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<button id="tc-btn">My Button</button>
<br/>
<a id="tc-link" href="javascript:void(0);">Link to enable button</a>
<br/>
<input type="checkbox" id="tc-checkbox" />
If the page is refreshing or taking you to a different page when you click the hyperlink, you will want to look into sessionStorage. When the hyperlink is clicked you will want to set a sessionStorage variable and when the page loads you want to check that variable to see if it is populated. If the variable is populated, enable the button.
Set the variable.
sessionStorage.setItem('key', 'value');
Get the variable
var data = sessionStorage.getItem('key');
If you need to re-disable the button you can clear the session storage and reapply the disabled class.
sessionStorage.clear();
You can learn more about session storage here.
If the page does not refresh you could just set an attr on the link when it is clicked like so.
$('#tc-link').on('click', function() {
$(this).attr('clicked', 'true');
});
Then when the checkbox is checked you can check this in your function.
$('#tc-checkbox').change(function(){
if($(this).is(":checked") && $('#tc-link').hasAttr('clicked')) {
$('#tc-btn').removeClass('tc-disable');
} else {
$('#tc-btn').addClass('tc-disable');
}
});
These are just some solutions I could think of off the top of my head. Hope this helps.
Maybe this is better for you. First you make an .on('click' event listener on the anchor element, then, if the checkbox is checked enable the button. I added the else statement to disable the button if a user clicks the link and the checkbox is not set for an example. In this example you don't need the classes.
But if you needed to keep the the classes then you would replace the $('#tc-btn').prop('disabled', false); with $('#tc-btn').addClass() or .removeClass()
$( '#theLink' ).on( 'click', function(e)
{
e.preventDefault();
if($('#tc-checkbox').is(':checked'))
{
$('#tc-btn').prop('disabled', false);
$('#tc-btn').val('Currently enabled');
}
else
{
$('#tc-btn').val('Currently disabled');
$('#tc-btn').prop('disabled', true);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="tc-checkbox" />
This link will enable the button
<input type="button" id="tc-btn" value="Currently disabled" disabled="disabled"/>
Here a much more simple solution and it handles the state of the button if they uncheck the "I Accept" checkbox. It is pretty easy to implement. I just used Bootstrap to pretty up the example.
//Handles the anchor click
$("#anchor").click(() => {
$("#anchor").addClass("visited");
$("#acceptBtn").prop("disabled", buttonState());
});
//Handles the checkbox check
$("#checkBx").on("change", () => {
$("#acceptBtn").prop("disabled", buttonState());
});
//Function that checks the state and decides if the button should be enabled.
buttonState = () => {
let anchorClicked = $("#anchor").hasClass("visited");
let checkboxChecked = $("#checkBx").prop("checked") === true;
return !(anchorClicked && checkboxChecked);
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-12">
View Terms
</div>
</div>
<div class="row">
<div class="col-md-12">
<label class="form-check-label">
<input class="form-check-input" id="checkBx" type="checkbox" value="">
I accept the terms
</label>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button id="acceptBtn" class="btn btn-success" disabled="disabled">
Ok
</button>
</div>
</div>
</div>
A one-liner solution using Javascript could be:
<input type="submit" id="test" name="test" required disabled="disabled">
<label for="test">I clicked the <a target="_blank" href="https://stackoverflow.com" onclick="document.getElementById('test').disabled=false">link</a>.</label>
Change the type "submit" to "button" or "checkbox" accordingly to your needs.
I am currently tackling some JQuery and Javascript and I have encountered a small problem that I can't for the life of me figure out how to solve.
I have a form which dynamically loads information from a json file which re-uses a "wpTemplate" and populates a select list. This form compromises something of the following;
<div class="wp" id="wpTemplate" >
<input type="checkbox" id="wpCheck" name="" class="wp" value="">
<label id="wpLabel" class="wpLabel"></label>
<div class="uc" id="uc">
<select class="ucSelect" id="ucSelect" name="case" multiple>
<option id="option" class="option"></option>
</select>
</div>
</div>
In essence, there could be multiple div "wpTemplate". My aim is to somehow have the ability to select either one or many "wpCheck" checkbox and for the "uc" div to display depending on the specific checkbox being selected.
I tried adding style="display: none;" to the "uc" class and a simple if-else statement with the show/hide functionality but to no avail.
$('.wp').each(function() {
if($(this).is(":checked")) {
$('.uc').show();
} else {
$('.uc').hide();
}
});
I'm new to JQuery so any help or alternative ways would be much appreciative.
How about:
$('.wpCheck').on('change', function () {
var $uc = $(this).closest('.wpTemplate').find('.uc')
if ($(this).prop('checked')) {
$uc.show()
} else {
$uc.hide()
}
})
Here's a working fiddle
Here is another way:
$( document ).ready(function() {
$('input.wp').change(function() {
var $this = $(this);
if ($this.is(":checked"))
{
$this.siblings('div.uc').show();
}
else
{
$this.siblings('div.uc').hide();
}
});
});
fiddle
I have a checkbox (#FBmngCH) that reveals a set of radio buttons (name=adManage) when clicked. When the checkbox is unclicked, the radio button that was previously selected still remains checked. I would like to have the checked status of the radio button removed once the checkbox is unchecked.
This is being used in a form, so if the user changes their mind about selecting that service, I would like the details about that service to be wiped also (so the value of the selected radio will not end up in the PHP and ultimately the email). I hope this makes sense.
I have given this some considerable time and am not seeming to get this to work correctly. The last set of if-statements is the part of the code that I wrote. Not sure if I am missing something, selecting something wrong, or what. Any help with this would be highly appreciated. Thanks!
HTML
<li>
<input type="checkbox" class="cbox" name="FBchecks[]" value="Facebook Ad MGMT" id="FBmngCH">
<label for="test">Facebook Ad Management</label>
<ul id="FBmngList">
<li>
<input type="radio" name="adManage" value="Ad Management 1" id="adMan1">
<label for="adMan1">Ad Fund - 1</label>
</li>
<li>
<input type="radio" name="adManage" value="Ad Management 2" id="adMan2">
<label for="adMan2">Ad Fund - 2</label>
</li>
<li>
<input type="radio" name="adManage" value="Ad Management 3" id="adMan3">
<label for="adMan3">Ad Fund - 3</label>
</li>
<li>
<input type="radio" name="adManage" value="Ad Management 4" id="adMan4">
<label for="adMan4">Ad Fund - 4</label>
</li>
<div id="FBADerror" class="acctError"></div>
</ul>
</li>
JS
$FBmngCH = $("#FBmngCH");
$FBmngList = $("#FBmngList");
//hide FB Management List
$FBmngList.hide();
//on FB Management select
$FBmngCH.click(function() {
//toggle FB Management List
$FBmngList.toggle();
});
$FBadValid = false;
$FBADerror = $("#FBADerror");
//if FB Ad Management is checked
if ($FBmngCH.attr('checked')) function validateFB() {
$("input[name=adManage]").each(function () { //LoopingthroughradioButtons
// "this" is the current element(radio) in the loop
if ($(this).is(':checked')) {
$FBadValid = true; //Radio Button is Checked);
}
if ($FBadValid.attr = true ) {
$FBADerror.empty();
}
});
};
if ($FBmngCH.blur($FBadValid.attr = false)) {
$FBADerror.append("<li> Please select a Facebook Ad plan. </li>");
//appends error to document
}
if ($FBmngCH.blur($FBmngCH.not('checked'))) {
$("input[name=adManage]").each(function () {
if ($(this).is(':checked')) {
$("input[name=adManage]").removeAttr('checked');
}
});
//remove checks from radios
};
$("input[name=adManage]").click(validateFB);
Maybe I am not understanding your requirements, but can't you just test for this in your checkbox event routine and uncheck the checked radio button:
$FBmngCH.click(function () {
//toggle FB Management List
$FBmngList.toggle();
if (!$FBmngList.attr('checked')) {
$FBmngList.find('input:checked').attr('checked', false);
}
});
See this Fiddle.
You have few errors in your code:
if ($FBmngCH.blur($FBadValid.attr = false)) {
This is not correct syntax. It should be:
$FBmngCH.blur(function(){
if ($FBadValid === false) {
}
});
Basically, since your're toggling the whole radios section and willing to remove their :checked property without checking any conditions, you do not need for loops or if($(this).is(':checked')) statements. Just remove :checked propery from all the radios. You can also show the error message on each check-box click, without if conditions, because the whole section is hidden anyways.
You should end up with very short code, like this:
$FBmngCH = $("#FBmngCH");
$FBmngList = $("#FBmngList").hide();
$FBADerror = $("#FBADerror");
$FBmngCH.click(function() {
// no need for loops and if's there. Radios and the message are hidden.
$FBmngList.toggle();
$FBADerror.html("<li> Please select a Facebook Ad plan. </li>");
$("input[name=adManage]").prop('checked', false);
});
$("input[name=adManage]").click(function(){
// no need for loops there. Radios and the message are hidden.
// Also, no need for if($(this).is(':checked')){. Since it's a click handler, something has to be :checked on radio click.
$FBADerror.empty();
});
DEMO
very new to javascript, but any help to get me started would be appreciated. I have a simple form:
<div><input type="radio" name="o1" id="burger" />Burger</div>
<div id="yesFries"><input type="checkbox" name="e1" id="fries" />Fries with that?</div>
<div><input type="radio" name="o1" id="pizza" />Pizza</div>
<div><input type="radio" name="o1" id="hotdog" />Hot Dog</div>
I want the "Fries" checkbox greyed out unless the "Burger" radio button is selected. I'm not sure if Javascript or CSS is the best way to do it. Thanks in advance!
what you want to do is set the elements disabled, until the state of the radio changes, that'd be done with javascript, and then you'd add/remove the disabled class in the onchange of the radio button.
What javascript libraries are you considering using? jQuery would make this fairly simple.
$('#burger').change( function () {
if ($('#burger').checked() ) {
$('#fries').removeClass('disabled');
} else {
$('#fries').addClass('disabled');
}
});
Actually with a bit CSS3 you can mock up a very simplistic solution.
Here we don't gray the button out, but you make it visible just if the checkbox is checked.
But, we could also gray it out with a bit more of CSS on top of this example.
You will always have to consider what kind of support you want to offer.
But if you are fine with it working on modern browsers, just give it a go.
Here's the HTML
<label>
<input type="checkbox" name="test" />
<span>I accept terms and cons</span><br><br>
<button>Great!</button>
</label>
Here's the CSS
button { display: none}
:checked ~ button {
font-style: italic;
color: green;
display: inherit;
}
And here's the DEMO http://jsfiddle.net/DyjmM/
I've noticed that you don't specify whether or not you can use jQuery. If that's an option, please see one of the other posts as I highly recommend it.
If you cannot use jquery then try the following:
<script>
function setFries(){
var el = document.getElementById("burger");
if(el.checked)
document.getElementById("fries").disabled = false;
else
document.getElementById("fries").disabled = true;
}
</script>
<div><input type="radio" name="o1" id="burger" onchange="setFries();"/>Burger</div>
<div id="yesFries"><input type="checkbox" name="e1" id="fries" disabled="disabled"/>Fries with that?</div>
<div><input type="radio" name="o1" id="pizza" onchange="setFries();"/>Pizza</div>
<div><input type="radio" name="o1" id="hotdog" onchange="setFries();"/>Hot Dog</div>
Simple example on jsFiddle
If you're using jQuery, a really-easy-to-use Javascript library (that I would highly recommend for beginners), you can do this in two steps by adding some code to a script tag in your page containing:
$(function(){
$("#burger").change(function() {
if ($(this).is(':checked')) $("#fries").removeAttr("disabled");
else $("#fries").attr("disabled", true);
});
});
This code does three things:
Listens for change events on #burger.
When a change occurs, execute the provided function.
In that function, set the disabled attribute of #fries to the checked property of #burger.
use JQuery
$().ready(function() {
var toggleAskForFries = function() {
if($('#burger').is(':checked')) {
$('#yesFries').show()
else
$('#yesFries').hide()
}
return false
}
toggleAskForFries()
$('#burger').change(toggleAskForFries)
}
Using jQuery: http://jsfiddle.net/kboucher/cMcP5/ (Also added labels to your labels)
You nay try this without any function library
<input type="checkbox" name="e1" id="fries" disabled />
JS
window.onload=function(){
var radios=document.getElementsByName('o1');
for(i=0;i<radios.length;i++) radios[i].onclick=checkFire;
};
function checkFire(e)
{
var fires=document.getElementById('fries');
var evt=e||window.event;
var target=evt.target||evt.srcElement;
if(target.checked && target.id==='burger') fires.disabled=false;
else
{
fires.checked=false;
fires.disabled=true;
}
}
DEMO.
I have a form with multiple inputs / radio buttons.
I also have a series of Yes & No radio buttons. When the "Yes" radio button is checked, I have some data slide down beneath.
HTML:
<div class="item seperator first clearfix">
<label>test</label>
<div class="radioWrap">
<label class="yes">
<input class="homepageContent" name="homepageContent" type="radio" value="yes" />
</label>
<label class="no">
<input class="homepageContent" name="homepageContent" type="radio" value="no" checked />
</label>
</div>
</div>
<div class="extrasInner">
<div class="item clearfix">
<label for="theContent">Your Content:</label>
<textarea id="theContent" name="theContent"></textarea>
</div>
</div>
<div class="extrasOuter hide clearfix">
Make Changes
<span>Click "Make Changes" to update.</span>
</div>
The jQuery:
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parent().parent().parent().next().slideDown();
$(this).parent().parent().parent().next().next().slideDown();
} else {
$(this).parent().parent().parent().next().slideUp();
$(this).parent().parent().parent().next().next().slideUp();
}
});
Question 1) This works absolutely fine in Google Chrome, but not in Firefox and IE. It doesn't seem to recognise the click function?
Solved: I had a function within one of my files that removes the value from input fields on focus and this was stripping the value of the radio buttons as well in IE / Firefox (but not chrome!).
Question 2) Is my DOM traversing for the slideUp / slideDown an acceptable way of achieving what I'm trying to do? Are there any disadvantages to how I'm doing it and can it be improved?
Answer to #1
As Anthony Grist pointed out, there doesn't seem to be an issue with the click function.
Answer to #2
Your DOM traversal seem a bit unnecessary. In fact, your DOM structure is in need of rearrangement.
Using a checkbox instead of radio buttons. A checkbox only accepts two values: true or false, or in your case, yes or no. It seems more suitable.
Encapsulate your extras inner and extras outer divs inside your item div instead of having it next to the checkbox. This way, you make it easier to traverse within the item.
Also, you should read up on the different types of traverse functions JQuery has:
.parent() / .parents()
.children()
.closest()
.next()
.prev()
.siblings()
.find()
and many more.
Knowing all of these traverse functions, you'll most likely never ever do parent().parent().parent()... again. :)
Here's a JSFiddle example | Code
HTML
<ul>
<li class='item'>
<label>
<input class="homepageContent" name="homepageContent" type="checkbox" value="yes" />
Item 1
</label>
<div class='extras'>
<div class='inner'>
<label>
Your Content:<textarea name="content"></textarea>
</label>
</div>
<div class='outer'>
Make Changes
<span>Click "Make Changes" to update.</span>
</div>
</div>
</li>
</ul>
Javascript
$("input:checkbox").click(function() {
var $this = $(this),
$item = $(this).closest(".item");
if($this.is(':checked')){
$(".extras", $item).slideDown();
}else{
$(".extras", $item).slideUp();
}
});
CSS
.extras{
display: none;
}
Value of the radio button will always be same, no matter it is checked or not. If you want to know the particular radio button is checked or not then use this code. Based on the status of the radio button do your stuff.
var value = $(this).attr('checked')
That is working for me in FF (jsfiddle), although the DOM looks a little convoluted (I'm guessing because it's missing a lot of your other CSS/resources).
I think you can simplify the jQuery selectors a lot. Generally, using simple ID or class selectors will make the your page much more performant (and simpler!)
$('.homepageContent').click(function() {
var value = $(this).val();
if (value == 'yes') {
$('.extrasInner').slideDown();
$('.extrasOuter').slideDown();
} else {
$('.extrasInner').slideUp();
$('.extrasOuter').slideUp();
}
});
Hopefully doing something like this makes it work cross browser better too.
try this way
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parents('.seperator').next().slideDown();
$(this).parents('.seperator').next().next().slideDown();
} else {
$(this).parents('.seperator').next().slideUp();
$(this).parents('.seperator').next().next().slideUp();
}
});
EDIT
and also a point
wrap your code inside
$(document).ready(function(){});
like this
$(document).ready(function(){
$("input:radio[name=homepageContent], input:radio[name=addSocialIcons], input:radio[name=addTracking]").click(function() {
var value = $(this).val();
if (value == 'yes') {
$(this).parents('.seperator').next().slideDown();
$(this).parents('.seperator').next().next().slideDown();
} else {
$(this).parents('.seperator').next().slideUp();
$(this).parents('.seperator').next().next().slideUp();
}
});
});