Consider we create radio buttons dynamically, so we can't access them by Id
<label class="btn btn-sm btn-white" onclick="test();"> <input type="radio" value="abc" name="options"> this is a text </label>
<label class="btn btn-sm btn-white" onclick="test();"> <input type="radio" value="dfdf" name="options"> this is a text </label>
<label class="btn btn-sm btn-white" onclick="test();"> <input type="radio" value="reewr" name="options"> this is a text </label>
How can alert the value of radiobutton inside clicked label?
function test(event){
event.stopPropagation();
console.log(event.currentTarget.firstElementChild.value);
}
<label class="btn btn-sm btn-white" onclick="test(event);"> <input type="radio" value="abc" name="options"> this is a text </label>
<label class="btn btn-sm btn-white" onclick="test(event);"> <input type="radio" value="dfdf" name="options"> this is a text </label>
<label class="btn btn-sm btn-white" onclick="test(event);"> <input type="radio" value="reewr" name="options"> this is a text </label>
First of all, you shouldn't really be using inline JS binding: use addEventListener instead. In the callback triggered by addEventListener, you will be able to get a reference to the element that triggers it via event.target.
event.target may refer to the <label> element or the <input> element, so we just have a simple if/else check to see which element the event is fired from, by checking event.target.tagName. If is an <input> element, we just get the element's value property.
See proof-of-concept below:
// Select the label elements in your DOM
// Note: You might have to adjust this!
var labelEls = document.querySelectorAll('label');
// Iterate through all selected `<label>` elements
Array.prototype.slice.call(labelEls).forEach(function(labelEl) {
// Iteratively add the `click` event listener
labelEl.addEventListener('click', function(event) {
// If event is emitted by `<input>`
if (event.target.tagName === 'INPUT') {
console.log('Value: ' + event.target.value);
}
});
});
<label class="btn btn-sm btn-white"> <input type="radio" value="abc" name="options"> this is a text </label>
<label class="btn btn-sm btn-white"> <input type="radio" value="dfdf" name="options"> this is a text </label>
<label class="btn btn-sm btn-white"> <input type="radio" value="reewr" name="options"> this is a text </label>
You can use label.control to reference HTML element associated with the label. Also avoid writing inline event handlers.
document.querySelectorAll("label").forEach(e => {
e.addEventListener("click", function(event){
// this will refer to label
console.log(this.control.value);
})
});
<label class="btn btn-sm btn-white"> <input type="radio" value="abc" name="options"> this is a text </label>
<label class="btn btn-sm btn-white"> <input type="radio" value="dfdf" name="options"> this is a text </label>
<label class="btn btn-sm btn-white"> <input type="radio" value="reewr" name="options"> this is a text </label>
Try like this:
html
onclick=“test(this)”
js
function test(elmnt) {
alert(elmnt.childNodes[1].value)
}
It's always better to add classes to a set of labels that you want to attach event listeners rather than attaching listeners based on tag names as there could many labels on your site webpage.
I have devised a solution using vanilla JS. Checks are done for event propagation (bubbling and capturing), type of the child element and tag name of the child element. This would keep the code safe even if we you add additional child elements to these labels when your application expands.
var labels = document.getElementsByClassName('labels');
for (var i = 0; i < labels.length; ++i) {
labels[i].addEventListener('click', function(event) {
if (event.target.tagName === 'LABEL') {
var kids = this.children;
for (var j = 0; j < kids.length; ++j) {
if (kids[j].type === 'radio' && kids[j].nodeName === 'INPUT') {
console.log(kids[j].value);
}
}
}
});
}
<label class="btn btn-sm btn-white labels"> <input type="radio" value="abc" name="options"> this is a text </label>
<label class="btn btn-sm btn-white labels"> <input type="radio" value="dfdf" name="options"> this is a text </label>
<label class="btn btn-sm btn-white labels"> <input type="radio" value="reewr" name="options"> this is a text </label>
Identify each input with an id, then pass it to each test():
<script type="text/javascript">
function test(e, id) {
var el = document.getElementById(id);
console.log(el.value);
}
</script>
<label class="btn btn-sm btn-white"> <input onclick="test(event,'id1')" type="radio" id="id1" value="abc" name="options"> this is a text </label>
<label class="btn btn-sm btn-white"> <input onclick="test(event,'id2');" type="radio" id="id2" value="dfdf" name="options"> this is a text </label>
<label class="btn btn-sm btn-white"> <input onclick="test(event,'id3');" type="radio" id="id3" value="reewr" name="options"> this is a text </label>
Related
I'm trying to refactor a small Javascript function that simply adds an active class to the parent <div> of a series of radio buttons on page load as well as via a change.
My function is:
function toggleActiveState (event) {
const el = event.target
const parent = el.closest('[data-toggle-has-btn-group]')
const buttons = parent.getElementsByClassName('js__btn-toggle')
var i
for (i = 0; i < buttons.length; i++) {
buttons[i].classList.remove('active')
}
el.parentElement.classList.add('active')
}
My markup is:
<div class="form-group">
<div class="btn-group-toggle d-flex flex-row" data-toggle="buttons" data-toggle-has-btn-group>
<label class="btn btn-custom btn-outline-primary btn-sm active flex-fill mr-1 js__btn-toggle">
<input type="radio" name="options" id="option1" value="Mr" checked onclick="toggleActiveState(event)"> Mr
</label>
<label class="btn btn-custom btn-outline-primary btn-sm flex-fill mx-1 js__btn-toggle">
<input type="radio" name="options" id="option2" value="Mrs" onclick="toggleActiveState(event)"> Mrs
</label>
<label class="btn btn-custom btn-outline-primary btn-sm flex-fill mx-1 js__btn-toggle">
<input type="radio" name="options" id="option3" value="Miss" onclick="toggleActiveState(event)"> Miss
</label>
<label class="btn btn-custom btn-outline-primary btn-sm flex-fill ml-1 js__btn-toggle">
<input type="radio" name="options" id="option4" value="Other" onclick="toggleActiveState(event)"> Other
</label>
</div>
</div>
When clicking a radio button, the toggleActiveState(event) runs and I'm able to remove the active classes and add a class to the input I clicked.
I have multiple of these .btn-group-toggle elements on the page.
What I need to do is be able to set the active class state of say the Mrs element on page load and it's value by calling my function like so:
toggleActiveState('options', 'Mrs') and then this would be active, and selected...
Any ideas?
You can add event listener on window load and add the class there. Like I've done below based on your code.
function toggleActiveState (event) {
const el = event.target
const parent = el.closest('[data-toggle-has-btn-group]')
const buttons = parent.getElementsByClassName('js__btn-toggle')
var i
for (i = 0; i < buttons.length; i++) {
buttons[i].classList.remove('active')
}
el.parentElement.classList.add('active')
}
window.addEventListener('load', () => {
const checkedInput = document.querySelector('input[type="radio"]:checked');
checkedInput.parentElement.classList.add('active');
})
.active {
color: red;
}
<div class="form-group">
<div class="btn-group-toggle d-flex flex-row" data-toggle="buttons" data-toggle-has-btn-group>
<label class="btn btn-custom btn-outline-primary btn-sm flex-fill mr-1 js__btn-toggle">
<input type="radio" name="options" id="option1" value="Mr" checked onclick="toggleActiveState(event)"> Mr
</label>
<label class="btn btn-custom btn-outline-primary btn-sm flex-fill mx-1 js__btn-toggle">
<input type="radio" name="options" id="option2" value="Mrs" onclick="toggleActiveState(event)"> Mrs
</label>
<label class="btn btn-custom btn-outline-primary btn-sm flex-fill mx-1 js__btn-toggle">
<input type="radio" name="options" id="option3" value="Miss" onclick="toggleActiveState(event)"> Miss
</label>
<label class="btn btn-custom btn-outline-primary btn-sm flex-fill ml-1 js__btn-toggle">
<input type="radio" name="options" id="option4" value="Other" onclick="toggleActiveState(event)"> Other
</label>
</div>
</div>
We have three buttons(English, Hindi & Urdu). How I can get the value of Selected button in JavaScript function?
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" checked> English
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2"> Hindi
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3"> Urdu
</label>
</div>
Firstly set value to your radio buttons then get buttons and bind event listener.
and you can get value of button from event target as following:
let btns= document.getElementsByName("options");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click",function(e) {
console.log(e.target.value);
});
}
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" checked value="English">English
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2"value="Hindi">Hindi
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3" value="Urdu">Urdu
</label>
</div>
Try This:
https://jsfiddle.net/f7ed1o0n/
$('input[name="options"]').change(function(){
alert($(this).val());
$(this).parents('.btn-group').find('input[type="radio"]').attr('disabled',
'disabled');
});
When I click option1, the showcontent will show hello 1, When I click option2, the showcontent will show hi 2, and more actions.I use JQuery to do this
$(document).ready(function() {
$("#option1").click(function() {
var s = "hello 1";
$(".showcontent").text(s);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked> Active
</label>
<label class="btn btn-secondary">
<input type="radio" name="options" id="option2" autocomplete="off"> Radio
</label>
<label class="btn btn-secondary">
<input type="radio" name="options" id="option3" autocomplete="off"> Radio
</label>
However this code can't run, when I click the button, I should not use $(".option1").click(function(){, any ideas?
Updates: typo $(".option1").click(function(){ should be $("#option1").click(function(){
Alright, you're attempting to refer to the Options as .option1 and .option2. However, the dot there actually means a class such as if you defined
<input type="radio" name="options"class="option1" autocomplete="off" checked>
So, replace your .option1 or whatever with #option1. That should fix your problem.
However, the class .showcontent doesn't exist within your code. Maybe you would like to add a blank div with the class showcontent
The event handler doesn't work because you're selecting by class, yet the each radio control has an id.
To fix this, and make the code simpler, put a common class on all the radio buttons and change their value attributes to the text you want to show in showcontent. Then you can simply set the text() of that element, like this:
$(".option").click(function() {
$(".showcontent").text($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary active">
<input type="radio" name="options" class="option" autocomplete="off" value="hello 1" checked> Active
</label>
<label class="btn btn-secondary">
<input type="radio" name="options" class="option" autocomplete="off" value="hi 2" /> Radio
</label>
<label class="btn btn-secondary">
<input type="radio" name="options" class="option" autocomplete="off" value="foo 3" /> Radio
</label>
<div class="showcontent"></div>
Because you are selecting a class not an id here: $(".option1").click(function() {. but you don't have any element contain class call .option1. so try something like this:
$(document).ready(function() {
$("#option1").click(function() {
var s = "hello 1";
$(".showcontent").text(s);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked> Active
</label>
<label class="btn btn-secondary">
<input type="radio" name="options" id="option2" autocomplete="off"> Radio
</label>
<label class="btn btn-secondary">
<input type="radio" name="options" id="option3" autocomplete="off"> Radio
</label>
<div class="showcontent"></div>
try using on click
$(document).ready(function() {
$(".option1").on("click",function() {
var s = "hello 1";
$(".showcontent").text(s);
});
});
Also if you want to attach it to the first option then use its ID in the selector
$(document).ready(function() {
$("#option1").on("click",function() {
var s = "hello 1";
$(".showcontent").text(s);
});
});
Also in html add the following in the html section inside body. This is because you are appending it to element with class showcontent on click
<div class="showcontent"></div>
I am building a simple vehicle inspection form and I would like to use checkboxes as buttons to capture true/false values.
This is supposed to be trivial using Bootstrap 4.
I would however like to adjust the default behaviour of the buttons; to toggle between the success and danger classes to denote true/false. And also in some cases to change the text of the button, eg. "Leaks" -> "No Leaks".
I have got the toggle working with the help of #Yass but I am not getting the correct true/false values when I submit the form. Even though the checkboxes are checked (true), the values are coming through as if they are false.
I'm not sure how to handle the change in text when toggling between the two states.
Checkbox Buttons
HTML
<div class="row">
<div class="col-sm-4 col-xs-12">
<p class="font-weight-bold">Bonnet</p>
<div data-toggle="buttons">
<label class="btn btn-block btn-success">
<input type="checkbox" name="oil" checked="checked" autocomplete="off"> Oil
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="coolant" checked="checked" autocomplete="off"> Coolant
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="breakfluid" checked="checked" autocomplete="off"> Break Fluid
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="screenwash" checked="checked" autocomplete="off"> Screen Wash
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="noleaks" checked="checked" autocomplete="off"> No Leaks
</label>
</div>
</div>
<div class="col-sm-4 col-xs-12">
<p class="font-weight-bold">Outside</p>
<div data-toggle="buttons">
<label class="btn btn-block btn-success">
<input type="checkbox" name="tyres" checked="checked" autocomplete="off">
Tyres
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="wiperblades" checked="checked" autocomplete="off">
Wiper Blades
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="lights" checked="checked" autocomplete="off">
Lights
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="indicators" checked="checked" autocomplete="off">
Indicators
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="outcleanliness" checked="checked" autocomplete="off">
Cleanliness
</label>
</div>
</div>
<div class="col-sm-4 col-xs-12">
<p class="font-weight-bold">Inside</p>
<div data-toggle="buttons">
<label class="btn btn-block btn-success">
<input type="checkbox" name="horn" checked="checked" autocomplete="off">
Horn
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="breaks" checked="checked" autocomplete="off">
Breaks/Handbrake
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="seatbelt" checked="checked" autocomplete="off">
Seatbelt
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="windscreen" checked="checked" autocomplete="off">
Windscreen
</label>
<label class="btn btn-block btn-success">
<input type="checkbox" name="incleanliness" checked="checked" autocomplete="off">
Cleanliness
</label>
</div>
</div>
</div>
JavaScript
$('label.btn').on('click', function() {
//Find the child check box.
var $input = $(this).find('input');
$(this).toggleClass('btn-danger btn-success');
//Remove the attribute if the button is "disabled"
if ($(this).hasClass('btn-danger')) {
$input.removeAttr('checked');
} else {
$input.attr('checked', '');
}
return false; //Click event is triggered twice and this prevents re-toggling of classes
});
https://jsfiddle.net/mstnorris/9fyzfu8w/
Here is an alternative solution with pure Javascript. Add a hidden input associated to each button, and update hidden values each time the button is clicked.
HTML :
<!-- Visible button -->
<input onclick="toogleButton(this,'hiddenButton')" class="btn btn-secondary" type="button" value="Toogle">
<!-- Hidden input -->
<input name="FM_city" id="hiddenButton" type="hidden" value="0"></input>
Javascript :
// Called when the button is clicked
function toogleButton(callingElement,hiddenElement)
{
// Check the color of the button
if (callingElement.classList.contains('btn-secondary'))
{
// If the button is 'unset'; change color and update hidden element to 1
callingElement.classList.remove('btn-secondary');
callingElement.classList.add('btn-success');
document.getElementById(hiddenElement).value="1";
}
else
{
// If the button is 'set'; change color and update hidden element to 0
callingElement.classList.remove('btn-success');
callingElement.classList.add('btn-secondary');
document.getElementById(hiddenElement).value="0";
}
}
When the form is submitted, process value of the hidden input. Note that you can easily change the text of the button with : callingElement.value="New text here"
Last remark : initial value of hidden elements must be in accordance with the initial color of the associated button.
Handle the click event of the buttons, and toggle the checked value of the input using jQuery .prop() like this..
var $chk = $(this).find('[type=checkbox]');
$chk.prop('checked',!$chk.prop('checked'));
Demo: http://codeply.com/go/IeuO1fPf7H
I am using knockout binding for radio button with bootstrap.
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default">
<input class="radio-inline" type="radio" data-bind="checked:daysBackParameter" value="true" name="daysradio" >{{texts.showAll}}
</label>
<label class="btn btn-default">
<input class="radio-inline" type="radio" data-bind="checked:daysBackParameter" value="30" name="daysradio" >{{texts.showOnly30Days}}
</label>
<label class="btn btn-default">
<input class="radio-inline" type="radio" data-bind="checked:daysBackParameter" value="60" name="daysradio" >{{texts.showOnly60Days}}
</label>
<label class="btn btn-default">
<input class="radio-inline" type="radio" data-bind="checked:daysBackParameter" value="90" name="daysradio" >{{texts.showOnly90Days}}
</label>
<!--
<label class="btn btn-default">
<span style="cursor:pointer" data-bind="click: function(){ filterClick(30) } ,css: { 'selectedFilter' : filterValue == 30 }"><u>30 </u></span>
</label>
-->
</div>
the probelm is when i use data-toggle=buttons then data-bind is not working
but if i remove this then data-binding works.
but in that case radio button style comes but i need button styles.
Could you please suggest any solution?
I used the mentioned custom binding and it worked for me. The deatails custom binding will be found on this custom biding by Roy J
<div class="btn-group" data-bind="radio: userType">
<button type="button" class="btn btn-primary" data-value="company">Main User</button>
<button type="button" class="btn btn-primary" data-value="person">Dummy user</button>