Bootstrap 4 toggle button - javascript

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

Related

likert scale toggle effect missing-Bootstrap with Blaze Meteor

I have the following html displaying a scale 1-5, I get the value that is clicked but it seems as it does not toggle or change the color when a number is clicked it only changes the color temporarily as shown in file attached
<div class="row">
<div class="btn-toolbar mr-2" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group" role="group" aria-label="likert group">
<div class="btn-group btn-group-toggle mr-2" data-toggle="buttons">
<a class="btn btn-link disabled ml-5" disabled>Totally Not</a>
<label class="btn btn-success" >
<input type="radio" name="likert" value="1" autocomplete="off">1
</label>
<label class="btn btn-success ">
<input type="radio" name="likert" value="2" autocomplete="off">2
</label>
<label class="btn btn-success ">
<input type="radio" name="likert" value="3" autocomplete="off">3
</label>
<label class="btn btn-success ">
<input type="radio" name="likert" value="4" autocomplete="off">4
</label>
<label class="btn btn-success ">
<input type="radio" name="likert" value="5" autocomplete="off">5
</label>
<a class="btn btn-link disabled" disabled>Very Much</a>
</div>
</div>
</div>
</div>
How can I make it maintain the toggle effect once it is selected?Is there something missing from the above code ?
(I use Meteor Blaze framework with Bootstrap 4)
The solution was to add the below javascript file of npm module in meteor js file
import 'bootstrap/dist/js/bootstrap.bundle'

Vue js when clicked get the value of radio button

I am trying to created a filter component, but first I would like to be able to console.log() the value of the filter model base on the selected radio button.
<template>
<Section>
<h5>Filter</h5>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="filter" id="all" v-model="filter" value="all" />All
</label>
<label class="btn btn-primary">
<input type="radio" name="filter" id="completed" v-model="filter" value="completed" />Completed
</label>
<label class="btn btn-primary">
<input type="radio" name="filter" id="notcompleted" v-model="filter" value="notcompleted" />Not Completed
</label>
<button class="btn btn-primary" #click="consoleFilter">console the value</button>
</div>
</Section>
</template>
if the radio "all" is check, and I click the button the console_log value I want must also be "all"
<script>
export default {
name: "Filter",
data() {
return { filter: null };
},
methods: {
consoleFilter() {
console.log(this.filter);
}
}
};
</script>
anyone know how I can do this?
Well, so far I get the point that you are trying to get the value of checked button when it's clicked. Simply you can add onChange event to input tag as follows
<Section>
<h5>Filter</h5>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="filter" #change="consoleFilter" id="all" v-model="filter" value="all" />All
</label>
<label class="btn btn-primary">
<input type="radio" name="filter" #change="consoleFilter" id="completed" v-model="filter" value="completed" />Completed
</label>
<label class="btn btn-primary">
<input type="radio" name="filter" #change="consoleFilter" id="notcompleted" v-model="filter" value="notcompleted" />Not Completed
</label>
<button class="btn btn-primary" #click="consoleFilter">console the value</button>
</div>
</Section>
and if you don't want to do this you can add a watcher too as
watch:{
filter(value){
console.log(value)
}
}

Using multiple bootstrap buttongroups in one page

Let's say I would like to have 2 different button groups on my page.
<div class="btn-group fruits" role="group" aria-label="fruits" id="fruits">
<button type="button" name="fruits" class="btn btn-default">apple</button>
<button type="button" name="fruits" class="btn btn-default">cherry</button>
<button type="button" name="fruits" class="btn btn-default">melon</button>
</div>
<div class="btn-group vegetables" role="group" aria-label="vegetables" id="vegetables">
<button type="button" name="vegetables" class="btn btn-default">cucumber</button>
<button type="button" name="vegetables" class="btn btn-default">aubergine</button>
<button type="button" name="vegetables" class="btn btn-default">pepper</button>
</div>
Whenever I click on a button, the selected button on other group became deselected.
I have added, different "ids", "names", "classes" to each buttongroup and button. But unfortunately no success. How can I have multiple buttongroups on a page without affecting eachother?
All the examples on official bootstrap page are even like that. When you click on o buttongroup, other buttongroup deselected. Bootstrap Button Group
Thanks for any idea.
Here is what you can do.
Checkbox / Radio
Add data-toggle="buttons" to a .btn-group containing checkbox or radio inputs to enable toggling in their respective styles.
$('input').on('change', function () {
console.clear();
console.log(this.value)
})
#import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');
body {
margin: 12px 0 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-12 text-center">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default">
<input type="radio" name="options" value="left" autocomplete="off"> Left
</label>
<label class="btn btn-default">
<input type="radio" name="options" value="middle" autocomplete="off"> Middle
</label>
<label class="btn btn-default">
<input type="radio" name="options" value="right" autocomplete="off"> Right
</label>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-md-12 text-center">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default">
<input type="radio" name="options" value="left 2" autocomplete="off"> Left 2
</label>
<label class="btn btn-default">
<input type="radio" name="options" value="middle 2" autocomplete="off"> Middle 2
</label>
<label class="btn btn-default">
<input type="radio" name="options" value="right 2" autocomplete="off"> Right 2
</label>
</div>
</div>
</div>
</div>

knockoutJS binding doesn't work if data-toggle=buttons used in bootstrap for radio button

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>

Uncheck a group of check buttons

I'm trying to uncheck a group of check buttons in an onclick event:
HTML:
</div>
<button onclick="getChart(); uncheck();" type="submit" class="btn btn-default" id="refreshChart">Request</button>
</div>
<form class="form">
<div class="btn-group btn-group-justified " data-toggle="buttons" name="chartSelect">
<label class="btn btn-info" id ="hide">
<input name="hide" type="checkbox" ><span>Hide</span>
</label>
<label class="btn btn-info">
<input name="total" id="total" type="checkbox">Total
</label>
<label class="btn btn-info">
<input name="max" id="max" type="checkbox">Max
</label>
<label class="btn btn-info">
<input name="mean" id="mean" type="checkbox">Mean
</label>
<label class="btn btn-info">
<input name="min" id="min" type="checkbox">Min
</label>
<label class="btn btn-info">
<input name="extrapo" id="extrapolation" type="checkbox">Extrapo
</label>
<label class="btn btn-info">
<input name="all" id="all" type="checkbox">All
</label>
</div>
</form>
I'm even just trying to just get one button to uncheck with no success.
JS:
function uncheck() {
if ($('[name=max]').is(':checked')) {
$('[name=max]').attr('checked', false);
}
}
It seems that calling filter is like this:
$("div[data-toggle='buttons'] input[type='checkbox']").is(":checked")
does not work. But if you put it with selector, it works. So this is fine:
$("div[data-toggle='buttons'] input[type='checkbox']:checked")
Now you can uncheck them all:
$("div[data-toggle='buttons'] input[type='checkbox']:checked").removeAttr("checked");
Try it in this fiddle
It looks like your code is working except that you have a call to a function getChart() that is not defined. When I remove that function call the checkbox is unchecked when clicking the button.
https://jsbin.com/yakiyopoye/edit?html,output

Categories