I have a form that has two checkboxes, now you can click the checkbox on both
The question is, is it possible to make it so that there is only one choice? For example, clicked on the first one, it turned on, clicked on the second one, the first turned off, the second turned on. It should also be possible to uncheck the box at any time. I know that I can use the radio type, but I need only checkboxes
.call-form-item {
padding-bottom: 12px;
margin-bottom: 24px;
margin-left: 50px;
margin-right: 50px;
}
input {
margin: 0;
box-sizing: border-box;
outline: none;
border: none;
background-color: #EEF0F7;
margin-right: 10px;
}
.input-wrapper {
display: flex;
align-items: flex-start;
}
label {
color: #808694;
font-family: Montserrat;
font-size: 10px;
font-weight: bold;
letter-spacing: 0;
line-height: 16px;
text-transform: uppercase;
margin-right: 10px;
}
input[type=checkbox]:focus {
outline: rgba(0, 0, 0, 0.2);
}
input[type=checkbox] {
background-color: #EEF0F7;
border-radius: 2px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: 17px;
height: 17px;
cursor: pointer;
position: relative;
}
input[type=checkbox]:checked {
background-color: #808694;
background: #808694 url("data:image/gif;base64,R0lGODlhCwAKAIABAP////3cnSH5BAEKAAEALAAAAAALAAoAAAIUjH+AC73WHIsw0UCjglraO20PNhYAOw==") 3px 3px no-repeat;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="contacts-call-form">
<form class="js-form" action="{{ route('send-contacts-call') }}">
<div class="col-md-6">
<div class="call-form-item">
<label for="name">Name *</label>
<div class="input-wrapper">
<input class="js-form-call-name" id="name" type="text" name="name">
</div>
</div>
</div>
<div class="col-md-6">
<div class="call-form-item">
<label for="email">Email *</label>
<div class="input-wrapper">
<input class="js-form-call-email" id="email" type="email" name="email">
</div>
</div>
</div>
<div class="col-md-6">
<div class="call-form-item">
<div class="input-wrapper">
<input class="js-form-call-check1" id="check1" name="check1" type="checkbox"><label>Check 1</label>
<input class="js-form-call-check2" id="check2" name="check2" type="checkbox"><label>Check 2</label>
</div>
</div>
</div>
</form>
</div>
The script would loo something like this. I didn't test this so there might be misspellings causing errors and such.
// get first checkbox element
let box1 = document.getElementByID( "check1" );
// get second checkbox element
let box2 = document.getElementByID( "check2" );
// add events that fires when boxes are checked
box1.addEventListener( "change", function() {
// see if the other box is already checked
if ( box2.checked ) {
// if so, uncheck it
box2.checked = false;
}
});
box2.addEventListener( "change", function() {
if ( box1.checked ) {
box1.checked = false;
}
});
But you can also just use radio buttons and invoke a hidden reset button when you click a checked radio button I think.
Here is another version that will work with any number of checkboxes.
const inps=document.querySelectorAll(".input-wrapper input");
inps.forEach(e=>e.addEventListener("click",ev=>{
inps.forEach(c=>{if(c!==e) c.checked=false})
}))
.call-form-item {
padding-bottom: 12px;
margin-bottom: 24px;
margin-left: 50px;
margin-right: 50px;
}
input {
margin: 0;
box-sizing: border-box;
outline: none;
border: none;
background-color: #EEF0F7;
margin-right: 10px;
}
.input-wrapper {
display: flex;
align-items: flex-start;
}
label {
color: #808694;
font-family: Montserrat;
font-size: 10px;
font-weight: bold;
letter-spacing: 0;
line-height: 16px;
text-transform: uppercase;
margin-right: 10px;
}
input[type=checkbox]:focus {
outline: rgba(0, 0, 0, 0.2);
}
input[type=checkbox] {
background-color: #EEF0F7;
border-radius: 2px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
width: 17px;
height: 17px;
cursor: pointer;
position: relative;
}
input[type=checkbox]:checked {
background-color: #808694;
background: #808694 url("data:image/gif;base64,R0lGODlhCwAKAIABAP////3cnSH5BAEKAAEALAAAAAALAAoAAAIUjH+AC73WHIsw0UCjglraO20PNhYAOw==") 3px 3px no-repeat;
}
<div class="contacts-call-form">
<form class="js-form" action="{{ route('send-contacts-call') }}">
<div class="col-md-6">
<div class="call-form-item">
<label for="name">Name *</label>
<div class="input-wrapper">
<input class="js-form-call-name" id="name" type="text" name="name">
</div>
</div>
</div>
<div class="col-md-6">
<div class="call-form-item">
<label for="email">Email *</label>
<div class="input-wrapper">
<input class="js-form-call-email" id="email" type="email" name="email">
</div>
</div>
</div>
<div class="col-md-6">
<div class="call-form-item">
<div class="input-wrapper">
<input class="js-form-call-check1" id="check1" name="check1" type="checkbox"><label>Check 1</label>
<input class="js-form-call-check2" id="check2" name="check2" type="checkbox"><label>Check 2</label>
</div>
</div>
</div>
</form>
</div>
And here is an alternative, using radio buttons:
const inps=document.querySelectorAll(".input-wrapper input");
inps.forEach(e=>e.addEventListener("click",ev=>{
e.checked=e!==inps.last;
inps.last=e.checked?e:null
}))
<div class="input-wrapper">
<label><input name="radio" value="1" type="radio">Check 1</label>
<label><input name="radio" value="2" type="radio">Check 2</label>
<label><input name="radio" value="3" type="radio">Check 3</label>
</div>
Alternate solution:
HTML:
<section>
<label><input type="checkbox" value="CBox 1"> CBox 1</label>
<label><input type="checkbox" value="CBox 2"> CBox 2</label>
<label><input type="checkbox" value="CBox 3"> CBox 3</label>
<label><input type="checkbox" value="CBox 4"> CBox 4</label>
<label><input type="checkbox" value="CBox 5"> CBox 5</label>
</section>
<p> Checkbox acts like a radio button, but can be reset </p>
Javascript:
const sel = document.querySelectorAll('section input[type="checkbox"]');
for (el of sel) {
el.addEventListener('click',
function(e) { sel.forEach( (x) => { if (e.currentTarget != x) x.checked = false; } ); }
);
};
You can use JavaScript / jQuery for it. If check1 is active, just disable check2.
See change event and disabled
Related
I am trying to add a class to the radio button parent element when checked.
The problem is, the class doesn't seem to delete when using removeClass. I can still see the red background when the checkbox is unchecked.
This is what I came up with so far ...
$('input:radio').change(function () {
if($(this).is(':checked')) {
$(this).parent().addClass('selected');
} else {
$(this).parent().removeClass('selected');
}
});
.selected {
background-color: #fff5f5;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Select a maintenance drone:</p>
<div class="">
<input type="radio" id="huey" name="drone" value="huey"
checked>
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey">
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie">
<label for="louie">Louie</label>
</div>
How do I need to change my code in order to achieve the correct behavior?
No need to check else part in the is(':checked') condition.
On click of radio button;
Firstly, perform removeClass() from all radio button.
Then, addClass() only to the respective checked parent element.
$('input:radio').change(function(){
$('input:radio[name=' + this.name + ']').parent().removeClass('selected'); //remove class "selected" from all radio button with respective name
$(this).parent().addClass('selected'); //add "selected" class only to the checked radio button
});
input[type="radio"] + label {
cursor: pointer;
display: block;
height: 40px;
width: 200px;
text-align: center;
line-height: 40px;
}
.selected {
background-color: #fff5f5;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<p>Select a maintenance drone:</p>
<div class="">
<input type="radio" id="huey" name="drone" value="huey">
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey">
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie">
<label for="louie">Louie</label>
</div>
First remove all classes of parents, then add class to parent of selected one.
$('input[type=radio]').change(function() {
$('input[type=radio]').each(function() {
$(this).parent().removeClass('selected');
});
$(this).parent().addClass('selected');
});
.selected {
background-color: #fff5f5;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Select a maintenance drone:</p>
<div class="">
<input type="radio" id="huey" name="drone" value="huey" checked>
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey">
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie">
<label for="louie">Louie</label>
</div>
you can solve it with only css
input[type="radio"] ~ label {
cursor: pointer;
display: block;
height: 40px;
width: 200px;
text-align: center;
line-height: 40px;
}
input[type="radio"] {
position: absolute;
}
input[type="radio"]:checked ~ label {
background-color: #fff5f5;
color: red;
}
This is a "fat free, valid HTML and CSS only" variant with a slightly improved semantic structure ...
.radio-group label,
.radio-group .content {
display: block;
position: relative;
}
.radio-group label {
cursor: pointer;
}
.radio-group label:hover {
background-color: #fffbfb;
}
.radio-group .content {
z-index: 0;
padding: 1.3em 8px 8px 24px;
margin: -1.3em 0 0 0;
}
.radio-group .label,
.radio-group [type="radio"] {
position: relative;
z-index: 1;
}
.radio-group [type="radio"] {
top: 1px;
}
.radio-group [type="radio"]:checked ~ span {
color: red;
}
.radio-group [type="radio"]:checked ~ .content {
background-color: #fff5f5;
}
<fieldset class="radio-group">
<legend>Select a maintenance drone:</legend>
<label>
<input type="radio" name="drone" value="huey"/>
<span class="label">Huey</span>
<span class="content">... more phrasing content ...</span>
</label>
<label>
<input type="radio" name="drone" value="dewey"/>
<span class="label">Dewey</span>
<span class="content">... more phrasing content ...</span>
</label>
<label>
<input type="radio" name="drone" value="louie"/>
<span class="label">Louie</span>
<span class="content">... more phrasing content ...</span>
</label>
</fieldset>
This works fine
$('input:radio').change(function(){
$('input:radio').parent().removeClass('selected'); // Remove the class from every element
$(this).parent().addClass('selected'); // Add calss to the clicked element
});
.selected {
background-color: #fff5f5;
color: red;
}
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="">
<input type="radio" id="huey" name="drone" value="huey"
checked />
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey" />
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie" />
<label for="louie">Louie</label>
</div>
</body>
I have a problem. I created the following topbar:
#topBar {
height: 30px;
margin-top: 10px;
}
#comboBoxAgent {
width: 400px;
height: 100%;
}
#comboBoxCoin1 {
min-width: 60px;
height: 100%;
}
#comboBoxCoin2 {
min-width: 60px;
height: 100%;
}
#btnToggleAgent {
float: right;
height: 100%;
min-width: 60px;
width: 70px;
border-radius: 10px;
font-size: 18px;
color: white;
}
#toggleSwitch {
height: 100%;
display: inline-block;
}
#txtStartDateTime {
margin-left: 10px;
}
.simulator-progress {
font-weight: bold;
}
#media only screen and (max-width: 1100px) {
#comboBoxCoin2 {
display: none;
}
}
#maxOrders {
padding: 5px 0px;
}
.txtOrderRadioBtn {
padding: 0px;
margin: 0px;
display: inline-block;
}
#maxOrdersBtn {
padding: 0px;
margin: 0px;
display: inline-block;
}
<div id="topBar">
<select id="comboBoxAgent" onchange="changeAgent()"></select>
<select id="comboBoxCoin1" class="comboBoxCoin" onchange="loadCoinPriceData()">
<option value="">-</option>
</select>
<select id="comboBoxCoin2" class="comboBoxCoin" onchange="loadCoinPriceData()">
<option value="">-</option>
</select>
<div id="toggleSwitch">
<div class="radio-group">
<input type="radio" id="environmentReal" name="environment" checked="checked" value="Real"><label for="option-one">Real</label>
<input type="radio" id="environmentSim" name="environment" value="Simulator"><label for="option-two">Sim</label>
</div>
</div>
<div id="simulatorControls" style="display: none;">
<input type="text" id="txtStartDateTime" placeholder="Start (0000-00-00 00:00:00)">
<button id="btnToggleSimulator" onClick="toggleSimulator()"></button>
<label id="txtSimulatorProgress" class="simulator-progress"></label>
</div>
<button id="btnToggleAgent" onClick="toggleAgent()"></button>
</div>
<div id="maxOrders">
<label class="txtOrderRadioBtn">Max visible orders</label>
<form id="maxOrdersBtn">
<label class="radio-inline">
<input type="radio" value="50" name="maxOrderOption" checked>50
</label>
<label class="radio-inline">
<input type="radio" value="100" name="maxOrderOption">100
</label>
<label class="radio-inline">
<input type="radio" value="250" name="maxOrderOption">250
</label>
<label class="radio-inline">
<input type="radio" value="All" name="maxOrderOption">All
</label>
</form>
</div>
The snippet isn't working properly, but I think thats just because its a snippet. The point is, that when I click on the radio button "Sim" the input field with the datetime shows up. Now this works properly on desktop, but on my mobile device the input field goes trough the maxOrders div. Here is an image of the mobile result:
Now how can I fix this using media queries. There are a few things that are important for the solution. The <button id="btnToggleAgent" onClick="toggleAgent()"></button> has to stay in the top right corner and the maxOrders needs to be below the simulator datetime input field on mobile. Please let me know how I can fix this!
I would do two things: Eliminate as many hard-coded widths as you can. The modern web should be flexible. Eliminate floats. They're a pain, and there are better ways (such as flexbox).
Other tips:
Use styling classes instead of IDs. This makes them reusable and forces you to consider how to simplify.
Apply padding and spacing globally, rather than in one-offs. Use generic classes or a small library.
#topBar {
height: 30px;
margin-top: 10px;
display: flex;
align-items: stretch;
}
#comboBoxAgent {
flex: auto;
}
.comboBoxCoin1 {
min-width: 60px;
}
#btnToggleAgent {
min-width: 60px;
width: 70px;
border-radius: 10px;
font-size: 18px;
color: white;
}
.simulator-progress {
font-weight: bold;
}
#media only screen and (max-width: 1100px) {
#comboBoxCoin2 {
display: none;
}
}
#maxOrders {
padding: 5px 0px;
}
.txtOrderRadioBtn {
padding: 0px;
margin: 0px;
}
#maxOrdersBtn {
padding: 0px;
margin: 0px;
}
<div id="topBar">
<select id="comboBoxAgent" onchange="changeAgent()"></select>
<select id="comboBoxCoin1" class="comboBoxCoin" onchange="loadCoinPriceData()">
<option value="">-</option>
</select>
<select id="comboBoxCoin2" class="comboBoxCoin" onchange="loadCoinPriceData()">
<option value="">-</option>
</select>
<div id="toggleSwitch">
<div class="radio-group">
<input type="radio" id="environmentReal" name="environment" checked="checked" value="Real"><label for="option-one">Real</label>
<input type="radio" id="environmentSim" name="environment" value="Simulator"> <label for="option-two">Sim</label>
</div>
</div>
<div id="simulatorControls" style="display: none;">
<input type="text" id="txtStartDateTime" placeholder="Start (0000-00-00 00:00:00)">
<button id="btnToggleSimulator" onClick="toggleSimulator()"></button>
<label id="txtSimulatorProgress" class="simulator-progress"></label>
</div>
<button id="btnToggleAgent" onClick="toggleAgent()"></button>
</div>
<div id="maxOrders">
<label class="txtOrderRadioBtn">Max visible orders</label>
<form id="maxOrdersBtn">
<label class="radio-inline">
<input type="radio" value="50" name="maxOrderOption" checked>50
</label>
<label class="radio-inline">
<input type="radio" value="100" name="maxOrderOption">100
</label>
<label class="radio-inline">
<input type="radio" value="250" name="maxOrderOption">250
</label>
<label class="radio-inline">
<input type="radio" value="All" name="maxOrderOption">All
</label>
</form>
</div>
I want to change the styling of a dropdown with check boxes using only CSS and javascript. I have added a picture of what I am trying to make when the button is pressed.. It would be nice if I could make a focus to the selected check box just like the grey container at the first checkbox
var expanded = false;
function showCheckboxes() {
var checkboxes = document.getElementById("checkboxes");
if (!expanded) {
checkboxes.style.display = "block";
expanded = true;
} else {
checkboxes.style.display = "none";
expanded = false;
}
}
.multiselect {
width: 200px;
}
.selectBox {
position: relative;
}
.selectBox select {
width: 100%;
font-weight: bold;
}
.overSelect {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
#checkboxes {
display: none;
border: 1px #dadada solid;
}
#checkboxes label {
display: block;
}
#checkboxes label:hover {
background-color: #1e90ff;
}
<form>
<div class="multiselect">
<div class="selectBox" onclick="showCheckboxes()">
<select>
<option>Group</option>
</select>
<div class="overSelect"></div>
</div>
<div id="checkboxes">
<label for="one">
<input type="checkbox" id="one" /> Boiler
</label>
<label for="two">
<input type="checkbox" id="two" /> Engine
</label>
<label for="three">
<input type="checkbox" id="three" /> Fan
</label>
<label for="one">
<input type="checkbox" id="four" /> Location
</label>
<label for="two">
<input type="checkbox" id="five" /> Ship
</label>
<label for="three">
<input type="checkbox" id="six" /> Valmarine
</label>
<label for="three">
<input type="checkbox" id="seven" /> Voyage</label>
</div>
</div>
</form>
For example I want to change the color of the dropdown button, the color of the box with the arrow on the right of the dropbox, the color of the checkboxes (dark grey) etc..
I am trying to make it as simple as possible using only CSS and javascript.
You can get pretty far on css alone. Most of the trick here is using a pseudo element on checkbox to represent selected state.
No html and js changes in this solution.
var expanded = false;
function showCheckboxes() {
var checkboxes = document.getElementById("checkboxes");
if (!expanded) {
checkboxes.style.display = "block";
expanded = true;
} else {
checkboxes.style.display = "none";
expanded = false;
}
}
* {
box-sizing: border-box;
}
body {
background: #0b4a79;
}
input[type="checkbox"]:checked::after {
border: 1px solid #a8a8a8;
background: #dadada;
background: linear-gradient(to bottom, #f0f0f0 0%, #c5c5c5 100%);
content: "";
left: 0;
right: 0;
top: 0;
bottom: 0;
position: absolute;
z-index: -10;
border-radius: 2px;
}
.multiselect {
width: 200px;
}
.selectBox {
position: relative;
}
.selectBox select {
width: 100%;
font-weight: bold;
background: #0000;
border: none;
border-radius: 2px;
background: linear-gradient(to bottom, #c9dde8 0%, #86b3cc 100%);
}
.overSelect {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
#checkboxes {
background-color: #103c5d;
display: none;
border: 1px #dadada solid;
margin: 5px 0 0 0;
border-radius: 3px;
}
#checkboxes label {
display: block;
font-family: Helvetica, Arial, sans-serif;
margin: 4px;
padding: 3px 2px;
position: relative;
color: #ffffff;
background: rgba(0, 0, 0, 0);
z-index: 1;
}
#checkboxes label:hover {
background-color: #1e90ff;
border-radius: 2px;
}
<form>
<div class="multiselect">
<div class="selectBox" onclick="showCheckboxes()">
<select>
<option>Group</option>
</select>
<div class="overSelect"></div>
</div>
<div id="checkboxes">
<label for="one">
<input type="checkbox" id="one" /> Boiler
</label>
<label for="two">
<input type="checkbox" id="two" /> Engine
</label>
<label for="three">
<input type="checkbox" id="three" /> Fan
</label>
<label for="one">
<input type="checkbox" id="four" /> Location
</label>
<label for="two">
<input type="checkbox" id="five" /> Ship
</label>
<label for="three">
<input type="checkbox" id="six" /> Valmarine
</label>
<label for="three">
<input type="checkbox" id="seven" /> Voyage</label>
</div>
</div>
</form>
To highlight the label you can go with something like mentioned in this post from #dfsq and add/remove a special class to your label on the click-event.
// get all your inputs within "#checkboxes label"
var checkedInput = document.querySelectorAll('#checkboxes label > input');
// loop over your inputs, by on change of your input (checked/unchecked)
// toggle the css class for the closest "label"
Array.from(checkedInput ).forEach(input => {
input.addEventListener('change', function(event) {
this.closest("label").classList.toggle("with-focus");
});
});
You can style then the new class
#checkboxes label.with-focus {
display: block;
background-color: #eee;
border-radius: 2px;
}
I've changed your snippet with this:
var expanded = false;
function showCheckboxes() {
var checkboxes = document.getElementById("checkboxes");
if (!expanded) {
checkboxes.style.display = "block";
expanded = true;
} else {
checkboxes.style.display = "none";
expanded = false;
}
}
// get all your inputs within "#checkboxes label"
var checkedInput = document.querySelectorAll('#checkboxes label > input');
// loop over your inputs, by on change of your input (checked/unchecked)
// toggle the css class for the closest "label"
Array.from(checkedInput ).forEach(input => {
input.addEventListener('change', function(event) {
this.closest("label").classList.toggle("with-focus");
});
});
.multiselect {
width: 200px;
}
.selectBox {
position: relative;
}
.selectBox select {
width: 100%;
font-weight: bold;
}
.overSelect {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
#checkboxes {
display: none;
border: 1px #dadada solid;
padding: 5px;
background-color: #103c5d;
}
#checkboxes label {
display: block;
}
#checkboxes label.with-focus {
display: block;
background-color: #eee;
border-radius: 2px;
}
#checkboxes label:hover {
background-color: #1e90ff;
}
<form>
<div class="multiselect">
<div class="selectBox" onclick="showCheckboxes()">
<select>
<option>Group</option>
</select>
<div class="overSelect"></div>
</div>
<div id="checkboxes">
<label for="one">
<input type="checkbox" id="one" /> Boiler
</label>
<label for="two">
<input type="checkbox" id="two" /> Engine
</label>
<label for="three">
<input type="checkbox" id="three" /> Fan
</label>
<label for="one">
<input type="checkbox" id="four" /> Location
</label>
<label for="two">
<input type="checkbox" id="five" /> Ship
</label>
<label for="three">
<input type="checkbox" id="six" /> Valmarine
</label>
<label for="three">
<input type="checkbox" id="seven" /> Voyage</label>
</div>
</div>
</form>
For all the other CSS stuff you should probably dig around, thats not as hard as its sounds ;)
I'm making a website where you can select a couple of options to create your own boat. I need to select radio buttons that are hidden behind a label, so in order to select them I'm writing some JS that does that exact thing.
Here is a small amount of code that contains the particular problem (this code is used in the whole website).
<div class="row specs">
<div class="subtitle">Hull Colour</div>
<div class="fourcol">
<label class="item" id="white">
<img src="images/8meter-outboard.jpg">
<div class="price">Orange</div>
<input class="form-input" data-color="white" name="color" type="radio" value="white" id="white_radio" />
</label>
</div>
<div class="fourcol">
<label class="item" id="Test">
<img src="images/8meter-outboard.jpg">
<div class="price">Grey</div>
<input data-color="grey" name="color" type="radio" value="Test">
</label>
</div>
<div class="fourcol last">
<label class="item" id="orange">
<img src="images/8meter-outboard.jpg">
<div class="price">White</div>
<input data-color="orange" name="color" type="radio" value="orange">
</label>
</div>
</div>
the JS:
$('.item').on('click', function(e){
e.preventDefault();
$(this).toggleClass('done');
document.getElementById('this').checked = true;
});
Without my Javascript, this markup seems to work. I want to put the display of the <input> on none at the end
You can utilize native HTML to achieve what you are trying to do. As Josh Sanger mentioned, when the for attribute is assigned to a label, a hook into the input for that label is instantiated automatically. As long as the targeted input has a match id attribute it will be linked. Once that hook has been made, you can use some basic jQuery selector mechanics to add classes to the HTML elements that you want appear differently.
Make certain that the input tag for the label is within the label so that bound click events will properly trigger it.
$('input[type="radio"]').on('click', function(e) {
var colorDiv = $(this).closest($('div.fourcol')).find($('.price'));
var removeSelected = $('div.fourcol').find($('.price').not($(this)));
$(removeSelected).removeClass('done');
$(colorDiv).addClass('done');
});
.orange,
.gray,
.white {
width: 48px;
height: 48px;
font-size: .79em;
text-align: center;
}
.orange {
background-color: orange;
border: solid 1px orange;
}
.gray {
background-color: #CCC;
border: solid 1px #CCC;
}
.white {
background-color: #FFF;
border: solid 1px #FFF;
}
input {
float: left;
display: inline-block;
clear: none;
}
.row.specs {
width: 250px;
}
.price.noColor {
border: solid 1px #ACE;
}
.noColor {
width: 48px;
height: 48px;
text-align: center;
font-family: arial;
font-size: 35px;
color: red;
}
.fourcol {
display: inline-block;
vertical-align: top;
font-family: arial;
}
.done {
border: dashed 1px green;
}
.price.noColor.done {
border: dashed 1px green;
}
body{
background-color: #DDE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="row specs">
<div class="subtitle">Hull Colour</div>
<div class="fourcol">
<label class="item" for="orange_radio">
<div class="price orange">Orange</div>
</label>
<input data-color="orange" name="color" type="radio" value="orange" id="orange_radio" />
</div>
<div class="fourcol">
<label class="item" for="grey_radio">
<div class="price gray">Grey</div>
</label>
<input data-color="grey" name="color" type="radio" value="gray" id="grey_radio" />
</div>
<div class="fourcol">
<label class="item" for="white_radio">
<div class="price white">White</div>
</label>
<input data-color="white" name="color" type="radio" value="white" id="white_radio" />
</div>
<div class="fourcol">
<label class="item" for="noColor_radio">
<div class="price noColor">X</div>
</label>
<input data-color="nocolor" name="color" type="radio" value="nocolor" id="noColor_radio" />
</div>
</div>
I am trying to implement "changing Div border color" when clicking on one of the radio buttons. It works well for scenario 1 but won't work on scenario 2.
$(":radio:checked").closest(".discount").addClass("checked");
$(":radio").on("change", e => {
const $div = $(e.target).closest(".discount");
console.log($div);
$(".discount").removeClass("checked");
$div.addClass("checked");
});
$(":radio:checked").closest(".discount2").addClass("checked");
$(":radio").on("change", e => {
const $div = $(e.target).closest(".discount2");
console.log($div);
$(".discount2").removeClass("checked");
$div.addClass("checked");
});
.discount {
border: 2px solid #cccccc;
padding: 2px;
padding: 10px;
width: 100%;
text-align: center;
border-radius: 5px;
}
.discount.checked {
border-color: red;
}
.discount2 {
border: 2px solid #cccccc;
padding: 2px;
padding: 10px;
width: 100%;
text-align: center;
border-radius: 5px;
}
.discount2.checked {
border-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label style="width:100%">
<div class="discount">
<input type="radio" name="fruits" checked>Apple</div>
</label>
<label style="width:100%">
<div class="discount">
<input type="radio" name="fruits">Banana</div>
</label>
<label style="width:100%">
<div class="discount2">
<input type="radio" name="drinks" checked>Milk</div>
</label>
<label style="width:100%">
<div class="discount2">
<input type="radio" name="drinks">Zzz</div>
</label>
<label style="width:100%">
<div class="discount2">
<input type="radio" name="drinks">Bbb</div>
</label>
In scenario 2, when clicking on 'Zzz', the Div border "Red" is gone! Anyone know whats wrong ?
There is no need to use multiple clases and such:
(I added another version of the example, where no <div>s were used (and changed the coloring a bit)
$('input[type=radio]:checked').parent().addClass('checked');
$('input[type=radio]').on('change',function(e) {
var thisGroup = $(this).attr('name');
if ($(this).is(':checked')) {
$('input[name='+thisGroup+']').parent().removeClass('checked');
$(this).parent().addClass('checked');
}
});
.discount, .discount-label{
border: 2px solid #cccccc;
padding:2px;
padding:10px;
width:10%;
text-align:center;
border-radius: 5px;
}
.discount.checked,.discount-label.checked {
border-color: red;
}
.discount-label input[type=radio] {
display: none;
}
.discount-label.checked {
background: red;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label><div class="discount"><input type="radio" name="fruits" checked>Apple</div></label>
<label><div class="discount"><input type="radio" name="fruits">Banana</div></label>
<label><div class="discount"><input type="radio" name="drinks" checked>Milk</div></label>
<label><div class="discount"><input type="radio" name="drinks">Zzz</div></label>
<label><div class="discount"><input type="radio" name="drinks">Bbb</div></label>
<h2>example two</h2>
<label class="discount-label"><input type="radio" name="fruits2" checked>Apple</label>
<label class="discount-label"><input type="radio" name="fruits2">Banana</label>
<label class="discount-label"><input type="radio" name="drinks2" checked>Milk</label>
<label class="discount-label"><input type="radio" name="drinks2">Zzz</label>
<label class="discount-label"><input type="radio" name="drinks2">Bbb</label>
The problem is that both $(":radio").on("change") are triggered and both the .checked classes are removed but it's only added the current changed checkbox. You can use 1 css class instead or change the javascript to remove all checked classes and add them back like you do on a page load.
updateBorders();
$(":radio").on("change", e => {
const $div = $(e.target).closest(".discount");
console.log($div);
updateBorders();
});
function updateBorders() {
$(".discount").removeClass("checked");
$(".discount2").removeClass("checked");
$(":radio:checked").closest(".discount").addClass("checked");
$(":radio:checked").closest(".discount2").addClass("checked")
}
Full JSFiddle here.