Attaching Click event to Bootstrap Toggle Radio Buttons - javascript

I have a boostrap toggle with the code below. It is visually working right
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="showBuildQuantity" autocomplete="off" checked>Build Quantity
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="showNumberOfScreens" autocomplete="off" onclick="showBuildQuantity()">Number of Screens
</label>
</div>
Below it I have some code to handle click events:
$(document).ready(function () {
$('#showBuildQuantity').on('click', function () {
<code here>
});
$('#showNumberOfScreens').on('click', function () {
<code here>
});
});
The issue I am having is that the click event's are never run when I click the toggle buttons.
I have other buttons on the same page using the same kind of jQuery click event and they do not have an issue.

After some research I found I need to use change instead of click. So the code should look like this:
$('#showBuildQuantity').on('change', function () {
if (myChart != null) {
myChart.destroy();
}
setChart(getBuildQuantityData);
});
$('#showNumberOfScreens').on('change', function () {
if (myChart != null) {
myChart.destroy();
}
setChart(getNumScreensData);
});

Related

Uncheck bootstrap radio button

I'm trying to uncheck a radio button wrapped with a label in a button group like this:
<div>
<label class="btn btn-primary">
<input type="radio" name="radio1" class="radio1" />
Radio1
</label>
</div>
<div>
<label class="btn btn-primary">
<input type="radio" name="radio2" class="radio2" />
Radio2
</label>
</div>
$('.btn').on('click', function(e) {
// Check if another option was previously checked
if ($(this).parent().parent().find(':radio:checked').length == 1) {
inner_input = $(this).find('input');
if (inner_input.prop('checked')) {
e.stopImmediatePropagation();
e.preventDefault();
inner_input.prop('checked', false);
$(this).removeClass('active');
}
});
Unfortunately it doesn't work and the label is still active even after the second click.
The solution in current answer works well for radio inputs. But it didn't work for button groups. To save other searchers of trouble, following code might be helpful:
$('label').click(function(e) {
e.preventDefault();
var radio = $(this).find('input[type=radio]');
if (radio.is(':checked')) {
e.stopImmediatePropagation();
$(this).removeClass("active");
radio.prop('checked', false);
} else {
radio.prop('checked', true);
}
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-outline-secondary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked>
option 1
</label>
<label class="btn btn-outline-secondary">
<input type="radio" name="options" id="option2" autocomplete="off">
option 2
</label>
<label class="btn btn-outline-secondary">
<input type="radio" name="options" id="option3" autocomplete="off">
option 3
</label>
</div>
Why this happens?
Let's first see what are click, mouseup and mousedown events :
mousedown
Fires when the user depresses the mouse button.
mouseup
Fires when the user releases the mouse button.
click
Fires when a mousedown and mouseup event occur on the same element.
Fires when the user activates the element that has the keyboard focus
(usually by pressing Enter or the space bar).
So When using click event, the radio button is checked, it means that radio.is(':checked') will always return true unless you disable default behavior. So you can do what you want in 2 ways :
1- With Mouseup event, in this case you can determine the state of radio button wether it's checked or not.But in this way you need one little extra code to disable the default behvaior of click event
$('label').on('mouseup', function(e){
var radio = $(this).find('input[type=radio]');
if( radio.is(':checked') ){
radio.prop('checked', false);
} else {
radio.prop('checked', true);
}
});
// Disable default behavior
$('label').click(function(e){
e.preventDefault();
});
Fiddle
And 2 , You can wrap it all together, disable click's default behavior and do the rest in one event:
$('label').click(function(e) {
e.preventDefault();
var radio = $(this).find('input[type=radio]');
if (radio.is(':checked')) {
radio.prop('checked', false);
} else {
radio.prop('checked', true);
}
});
Fiddle
I did answer this question using 2 different events with a purpose, sometimes in more complex problems you may be forced to use the mouseup event instead of click

Disable radio button in bootstrap 3?

How can I disable Bootstrap 3 radio buttons? If I start with the BS3 example and add disabled="disabled" to each input element, there are no changes in appearance or behavior:
<div class="container">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked disabled="disabled">Radio 1 (preselected)</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2" autocomplete="off" disabled="disabled">Radio 2</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3" autocomplete="off" disabled="disabled">Radio 3</label>
</div>
Demo: JSFiddle.
I guess this is because the disabled attribute is only applied to the now-invisible button and not the clickable text label, but I don't see anything in the BS3 docs about this.
Add disabled class to the label like this
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 1 (pre-checked)
</label>
<label class="btn btn-primary active disabled">
<input type="checkbox" autocomplete="off"> Checkbox 2
</label>
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 3
</label>
</div>
Here is a demo
As mentioned by #giammin in the comments to the accepted answer, setting 'disabled' on the input elements doesn't work in 3.3.6 of bootstrap. (Current version at time of publication of this answer).
I was having exactly the same issue, and my solution was to use the CSS property "pointer events". This makes sure the element and children are never a target of click events. However this is not a foolproof solution - users can still tab in and use space to click the hidden elements on a desktop browser.
.disabled-group
{
pointer-events: none;
}
If you set this on your '.btn-group' element, you'll completely disable
<div class="btn-group disabled-group" data-toggle="buttons">
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 1 (pre-checked)
</label>
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 2
</label>
<label class="btn btn-primary disabled">
<input type="checkbox" autocomplete="off"> Checkbox 3
</label>
</div>
The '.disabled' class is then optional - use it for graying out and 'cursor: not-allowed;' property.
The discussion of the fix solution is at this source:
https://github.com/twbs/bootstrap/issues/16703
For radio button groups, add class disabled to the one you wish disabled.
Make sure you have something like this code:
$('.btn-group').on("click", ".disabled", function(event) {
event.preventDefault();
return false;
});
This will get all your .disabled classed buttons inside the button groups also disabled. This works also for radio type button groups.
You can use the above to disable an input[type='radio'] that is inside a label (bootstrap 3 style),
$("input[name='INPUT_RADIO_NAME']").prop("disabled", true);
$("input[name='INPUT_RADIO_NAME']").closest("div").css("pointer-events", "none");
The above to enable again,
$("input[name='INPUT_RADIO_NAME']").prop("disabled", false);
$("input[name='INPUT_RADIO_NAME']").closest("div").css("pointer-events", "auto");
You can also extend JQuery and create a dummy disable method (that you could upgrade with more functionality) like this,
(function ($) {
$.fn.disableMe = function () {
// Validate.
if ($.type(this) === "undefined")
return false;
// Disable only input elements.
if ($(this).is("input") || $(this).is("textarea")) {
// In case it is a radio inside a label.
if ($(this).is("[type='radio']") && $(this).parent().is("label.btn")) {
$("input[name='safeHtml']").closest("label").addClass("disabled");
$(this).closest("div").css("pointer-events", "none");
}
// General input disable.
$(this).prop("disabled", true);
}
};
$.fn.enableMe = function () {
// Validate.
if ($.type(this) === "undefined")
return false;
// Enable only input elements.
if ($(this).is("input") || $(this).is("textarea")) {
// In case it is a radio inside a label.
if ($(this).is("[type='radio']") && $(this).parent().is("label.btn")) {
$("input[name='safeHtml']").closest("label").removeClass("disabled");
$(this).closest("div").css("pointer-events", "auto");
}
// General input enable.
$(this).prop("disabled", false);
}
};
$.fn.toggleDisable = function () {
if ($.type(this) === "undefined")
return false;
// Toggle only input elements.
if ($(this).is("input") || $(this).is("textarea")) {
var isDisabled = $(this).is(":disabled");
// In case it is a radio inside a label.
if ($(this).is("[type='radio']") && $(this).parent().is("label.btn")) {
$("input[name='safeHtml']").closest("label").toggleClass("disabled");
$(this).closest("div").css("pointer-events", isDisabled ? "auto" : "none");
}
// General input enale.
$(this).prop("disabled", !isDisabled);
}
};
}(jQuery));
Usage example,
$("input[name='INPUT_RADIO_NAME']").disableMe();
$("input[name='INPUT_RADIO_NAME']").enableMe();
$("input[name='INPUT_RADIO_NAME']").toggleDisable();
In bootstrap if you want to disabled any input type or button, You just have to add bootstrap's .disabled class then your button become disabled.
Like this
<input type="radio" class="btn btn-primary disabled">Primary Button</button>

Trouble with binding events to Bootstrap 3 (button.js) button radios

I'm having trouble getting the correct value from a segmented control I made with the radio button component of button.js in Twitter Bootstrap 3. When I bind a click event to the segmented control that runs $.serialize() on the parent form, it return the unchecked value of the radio button along with all the other correct values from the other inputs.
I suspect it might be related to the fact that I can't bind this event directly to the segmented control's input. When I tried to bind the event directly to the input I didn't get a response back, so I bound it to the label.
Here's an example of the problem in a fiddle: https://jsfiddle.net/stevekas/9w94pL4o/
<form id="form">
<div id="radios">
<div class="radio">
<label class="major-category">
<input facet="exclusive" type="radio" name="hipsum" value="hashtag" />hashtag</label>
</div>
<div class="radio">
<label class="major-category">
<input facet="exclusive" type="radio" name="hipsum" value="farm-to-table" />farm-to-table</label>
</div>
<div class="radio">
<label class="major-category">
<input facet="exclusive" type="radio" name="hipsum" value="gastropub" />gastropub</label>
</div>
</div>
<!--/ #radios -->
<div id="segmented-control" class="btn-group btn-group-justified" data-toggle="buttons">
<label class="btn btn-default active">
<input type="radio" name="segmented-control" id="roof" value="roof" autocomplete="off" checked />roof</label>
<label class="btn btn-default">
<input type="radio" name="segmented-control" id="party" value="party" autocomplete="off" />party</label>
</div>
<!--/ #segmented-control -->
</form>
<script>
$('.radio input').on('click', function () {
var data = $('#form').serialize();
});
$('#segmented-control label').on('click', function () {
var data = $('#form').serialize();
});
</script>
It probably happens because the click for the label is processed before the click for the input (the label is higher in the DOM tree).
You can force debug to be called after all the events have been processed using setTimeout() without any delay, like this:
$('#segmented-control label').on('click', function () {
setTimeout(function() {
debug();
}, 0);
});
This works because setTimeout() enqueues a new event, which will be run after all the current pending ones.

onclick on Bootstrap radio button does not work

I have declared the same structure:
<div class="btn-group" data-toggle="buttons" style="margin-left:50px;">
<label class="btn btn-default">
<input id="past5m" type="radio"> 5m
</label>
<label class="btn btn-default">
<input id="past1h" type="radio"> 1h
</label>
</div>
which, according to this should enable me to attach an onclick event by adding:
$(document).ready(function() {
$('#past5m').click(function() {
alert('hello');
});
});
JQuery is already included in the code.
However, when `#past5m' is pressed, nothing happens.
Can you please help me to spot the error?
Thanks.
You click the label, not the value. Try
$(window).ready(function() {
$('#past5m').closest('label').click(function() {
alert('hello');
});
});
Try it on JSFiddle
Ok, figured it out thanks to this:
$(document).ready(function() {
$('#past5m').change(function() {
alert('hello');
});
});

Disable Next Page button until all radio button groups have been answered

I'm trying to figure out how to disable a "Next section" button until all three groups of radio buttons have been answered. I've searched at length for a solution, but most refer to when a form is submitted. I'm trying to configure it so that the button is enable once all questions are answered.
This page has three panels, with only one visible at a time. When panel one is visible, panels two and three are hidden. Once all the questions on panel one are answered, the user clicks a "Next section" button, which slides up section one, and slides down section two. The trouble I'm having is the validation... making sure all questions on each panel are answered before enabling the button.
Here's a very shortened version of what I'm working with:
Q1
<div id="one">
<input type="radio" name="question01" value="Q1-A">
<input type="radio" name="question01" value="Q1-B">
<input type="radio" name="question01" value="Q1-C">
</div>
Q2
<div id="two">
<input type="radio" name="question02" value="Q2-A">
<input type="radio" name="question02" value="Q2-B">
<input type="radio" name="question02" value="Q2-C">
</div>Q3
<div id="three">
<input type="radio" name="question03" value="Q3-A">
<input type="radio" name="question03" value="Q3-B">
<input type="radio" name="question03" value="Q3-C">
</div>
<button class="btn btn-primary" type="button" id="submit1" disabled="true">Next section</button>
$(document).ready(function () {
var q01 = $('input[name=question01]');
var q02 = $('input[name=question02]');
var q03 = $('input[name=question03]');
validate();
$(q01, q02, q03).change(validate);
});
function validate() {
if ($(q01).is(':checked') && $(q02).is(':checked') && $(q03).is(':checked')) {
$(".btn#submit1").prop("disabled", false);
} else {
$(".btn#submit1").prop("disabled", true);
}
}
I think this is what you need:
http://jsfiddle.net/vss9D/4/
$(document).ready(function() {
var q01 = $('input[name=question01]');
var q02 = $('input[name=question02]');
var q03 = $('input[name=question03]');
validate();
$("input[type='radio']").change(validate);
function validate() {
if ($(q01).is(':checked') && $(q02).is(':checked') && $(q03).is(':checked')) {
$(".btn#submit1").removeAttr("disabled", false);
} else {
$(".btn#submit1").attr("disabled", true);
}
}
});
The important part here is where you bind the "validate" function to the radio groups.
$(q01, q02, q03).change(validate); is not a valid way to select three jQuery elements.
you can use the .add() function to select multiple jQuery variables (see this stack overflow question)

Categories