How to only allow "checking" of only one checkbox - javascript

How can I edit this codepen to allow for only checking one item, and if another item is checked, the previous one is unchecked and to use a custom image for the check instead of the current check automatically generated?
<!-- Example Dropdown -->
<div class="dropdown">
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown">Menu</button>
<div class="dropdown-menu">
Item 1
Item 2
Item 3
</div>
</div>
<p class="mt-4">
View the original post
</p>
<p>
This code is by #claviska and has been released into the public domain.
</p>
.dropdown-item-checked::before {
position: absolute;
left: .4rem;
content: '✓';
font-weight: 600;
}
body {
padding: 1rem;
}
// Toggle checkmarks
$(document).on('click', '.dropdown-item', function(event) {
event.preventDefault();
$(this).toggleClass('dropdown-item-checked');
});

I don't see why hiding radio button would be a problem (I don't mean for accessibility, I only mean for what you want to achieve).
Is that what you want?
[name=items] {
display: none;
}
label {
display: block;
padding-left: 1rem;
}
:checked + label::before {
position: absolute;
left: .4rem;
content: '✓';
font-weight: 600;
}
<input type="radio" name="items" id="item-1">
<label for="item-1">Item 1</label>
<input type="radio" name="items" id="item-2" checked>
<label for="item-2">Item 2</label>
<input type="radio" name="items" id="item-3">
<label for="item-3">Item 3</label>

Related

JS Event listener not being Invoked after using insertafter

I have two section where the second section is inserted into a div of the first section. This is done so the appropriate section is displayed side by side when any of the item in the first section is clicked.
However the issue that I am seeing is hapenning with the radio change event. The radio change event is not triggering consistently or being called if i use $('.checking-account-options').insertAfter('.offering-container'); (updating the DOM)
I made sure that the radio button change event is called after the DOM is updated but still having issues with firing the radio button event handler. What could be the issue here?
let bankOfferingClick = document.querySelectorAll('#banks .account-offering');
if (bankOfferingClick.length)
bankOfferingClick.forEach(button => button.addEventListener('click', updateDOM));
let radiobuttons = document.querySelectorAll('input[type="radio"]');
radiobuttons.forEach(radiobutton => {
radiobutton.addEventListener('change', updatecheckbox);
});
function updateDOM(event) {
$('.checking-account-options').insertAfter('.offering-container');
}
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function updatecheckbox(event) {
const target = event.target;
if (target.type === "radio")
for (const radio of radiobuttons) {
if (radio.checked)
target.previousElementSibling?.classList.add('checked');
else
target.previousElementSibling?.classList.remove('checked');
}
}
input [type="radio"] {
display: none;
}
.radio {
width: 1.25rem;
height: 1.25rem;
flex-shrink: 0;
border-radius: 100vmax;
margin-right: 0.5rem;
display: flex;
justify-content: center;
align-items: center;
position: relative;
border: 1px solid black;
background-color: white;
}
.radio-label {
display: flex;
align-items: center;
}
.radiocontainer {
padding-bottom: 1rem;
}
.radiocontainer label.radio-label.checked .radio::before {
content: "";
position: absolute;
width: 0.75rem;
height: 0.75rem;
background-color: black;
border-radius: 100vmax;
}
.hide {
display: none;
}
ul li {
margin-bottom: 1rem;
margin-top: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body id="banks">
<section class="bank-offering-container">
<div style="display:flex">
<div class="offering-container">
<ul style="list-style: none;">
<li class="checkingsaccount">
<span class="account-offering">
Checkings Account
</span>
</li>
<li class="savingsaccount">
<span class="account-offering">
Savings Account
</span>
</li>
<li class="investments">
<span class="account-offering">
Investments
</span>
</li>
</ul>
</div>
</div>
</section>
<section class="checking-account-options">
<div>
<div class="radiocontainer">
<label for="2" class="radio-label">
<span class="radio"></span>
Used for day to day purposes
</label>
<input type="radio" class="hide" id="2">
</div>
<div class="radiocontainer">
<label for="3" class="radio-label">
<span class="radio"></span>
Used to pay off student loans
</label>
<input type="radio" class="hide" id="3">
</div>
<div class="radiocontainer">
<label for="4" class="radio-label">
<span class="radio"></span>
Used to pay off mortagage
</label>
<input type="radio" class="hide" id="4">
</div>
<div class="radiocontainer">
<label for="5" class="radio-label">
<span class="radio"></span>
Used to pay off auto loan
</label>
<input type="radio" class="hide" id="5">
</div>
</div>
</section>
</body>
<body id="banks">
<section class="bank-offering-container">
<div style="display:flex">
<div class="offering-container">
<ul style="list-style: none;">
<li class="checkingsaccount">
<span class="account-offering">
Checkings Account
</span>
</li>
<li class="savingsaccount">
<span class="account-offering">
Savings Account
</span>
</li>
<li class="investments">
<span class="account-offering">
Investments
</span>
</li>
</ul>
</div>
</div>
</section>
<section class="checking-account-options">
<div>
<div class="radiocontainer">
<label for ="2" class="radio-label">
<span class="radio"></span>
Used for day to day purposes
</label>
<input type="radio" class="hide" id="2">
</div>
<div class="radiocontainer">
<label for ="3" class="radio-label">
<span class="radio"></span>
Used to pay off student loans
</label>
<input type="radio" class="hide" id="3">
</div>
<div class="radiocontainer">
<label for ="4" class="radio-label">
<span class="radio"></span>
Used to pay off mortagage
</label>
<input type="radio" class="hide" id="4">
</div>
<div class="radiocontainer">
<label for ="5" class="radio-label">
<span class="radio"></span>
Used to pay off auto loan
</label>
<input type="radio" class="hide" id="5">
</div>
</div>
</section>
</body>

How to contain jQuery datepicker within div?

UPDATES: I tried the suggestions below but they did not work.
I want to contain the calendar within the white div with a dark grey border (class = "profileEdit"), and only have its overflow viewable by scrolling. Right now, it's spilling onto profileEdit's parent divs.
SELECTED HTML
<div class="profileEdit">
<div class="profilePic">
</div>
<input type="text" class="form-control" id="usernameEdit" placeholder="Damon">
<form class="habitForm">
<h2>MY EXERCISE HABIT</h2>
<div class="habitFormGroup">
<div class="custom-select">
<select>
<option value="0">Before</option>
<option value="1">After</option>
<option value="2">During</option>
<option value="3">Every time</option>
<option value="4">When</option>
</select>
</div>
<input type="text" class="form-control" id="triggerEdit" placeholder="breakfast">
<p class="punctuation">,</p>
</div>
<p class="helperText">trigger</p>
<div class="habitFormGroup lockedLesson">
<p>I will</p>
<div class="exerciseEdit"></div>
<p class="punctuation">.</p>
</div>
<p class="helperText lockedLesson" id="exerciseHelper">exercise</p>
<div class="habitFormGroup lockedLesson">
<div class="exerciseEdit"></div>
<p>is my reward.</p>
</div>
<p class="helperText lockedLesson">reward</p>
</form>
<div class="reminderSwitch">
<p>Remind me to perform habit</p>
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</div>
<div>
<form class="reminderControls">
<label for="startDate">Start:</label>
<!-- CALENDAR -->
<div class="dateParent">
<input type="text" id="datepicker" value="">
</div>
</form>
</div>
Save</button>
</div>
DATEPICKER JQUERY
$(function () {
$("#datepicker").datepicker();
});
DATEPICKER CSS
.profileEdit {
text-align: center;
padding: 1.5rem;
margin: 3rem 1.5rem;
border: grey solid;
border-radius: 3px;
overflow-y: scroll;
position: relative;
}
#ui-datepicker-div {
position: absolute;
width: 280px;
font-family: frutigerLight;
}
.ui-widget-header.ui-widget-header {
background: none;
background-color: white;
border: none;
}
UPDATE: Solution works, but messes up spacing: The space between the "Starts" toggles on and off as well.
You can use an inline datepicker and control its visibility with JavaScript:
$(function() {
$('.dateParent').datepicker({ inline: true, altField: '#datepicker' });
$('#datepicker').focus(function(event) {
event.preventDefault();
$('.ui-datepicker').addClass('shown');
return false;
});
$(document).click(function(event) {
if(!$(event.target).is('.dateParent *'))
$('.ui-datepicker').removeClass('shown');;
});
});
.profileEdit {
text-align: center;
padding: 1.5rem;
margin: 3rem 1.5rem;
border: grey solid;
border-radius: 3px;
position: relative;
}
.ui-datepicker {
visibility: hidden;
height: 0;
margin: 1rem auto;
}
.ui-datepicker.shown {
visibility: visible;
height: initial;
}
.ui-widget-header.ui-widget-header {
background: none;
background-color: white;
border: none;
}
<script src="https://code.jquery.com/jquery-3.6.0.js" type="text/javascript"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js" type="text/javascript"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css" type="text/css">
<div class="profileEdit">
<div class="profilePic">
</div>
<input type="text" class="form-control" id="usernameEdit" placeholder="Damon">
<form class="habitForm">
<h2>MY EXERCISE HABIT</h2>
<div class="habitFormGroup">
<div class="custom-select">
<select>
<option value="0">Before</option>
<option value="1">After</option>
<option value="2">During</option>
<option value="3">Every time</option>
<option value="4">When</option>
</select>
</div>
<input type="text" class="form-control" id="triggerEdit" placeholder="breakfast">
<p class="punctuation">,</p>
</div>
<p class="helperText">trigger</p>
<div class="habitFormGroup lockedLesson">
<p>I will</p>
<div class="exerciseEdit"></div>
<p class="punctuation">.</p>
</div>
<p class="helperText lockedLesson" id="exerciseHelper">exercise</p>
<div class="habitFormGroup lockedLesson">
<div class="exerciseEdit"></div>
<p>is my reward.</p>
</div>
<p class="helperText lockedLesson">reward</p>
</form>
<div class="reminderSwitch">
<p>Remind me to perform habit</p>
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</div>
<div>
<form class="reminderControls">
<label for="startDate">Start:</label>
<!-- CALENDAR -->
<div class="dateParent">
<input type="text" id="datepicker" value="">
</div>
</form>
</div>
Save</button>
</div>
Try to remove height attr from calendar element. If it doesnt work check this jQuery UI inline Datepicker auto-resize to parent container
As a UX designer I'd think that you want to either make the containing DIV larger (personally think a popup like the calendar shouldn't extend outside it's container) or possibly change the direction that the calendar control opens in relative to the mouse position. If your trigger control is at the bottom of it's container you have the calendar pop upwards instead of down.

Toggle CSS class depending on the radio button status

I'm working on a better user interface and I tried to achieve a way to visualize radio buttons. I got the following code to the point where the radio button input will be checked and the class highlightedBox added on color click.
How can I manage to toggle the class highlightedBox depending on the radio button status? Now toggle get triggered on click but this solution wont work if the user decides to deselect the color button by selecting another color.
I know the current status of the code only works for a single change per color. If you want to select the same color again the checked value wont be set. But this is another problem and I'll try to fix this later on.
$('#wireColorSelect #wireBox').click(function(){
var checkbox = $(this).parent().find(".cbox");
var wireDOM = $(this).parent().find("#wireBox");
checkbox.attr('checked', !checkbox.attr('checked'));
wireDOM.toggleClass('highlightedBox');
});
.wireBox{
border: 1px solid;
height:50px;
width:50px;
opacity: 0.5;
}
.white{
background-color: White;
}
.red{
background-color: red;
}
.blue{
background-color: blue;
}
.yellow{
background-color: yellow;
}
.highlightedBox {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wireColorSelect">
<div class="flex-row flex-xs-3">
<div class="flex-xs-3 no-padding">
<div id="wireBox" class=" white wireBox"></div>
<input class="cbox" type="radio" id="whiteWireBox" name="wireBox" value="whiteWireBox" />
</div>
<div class="flex-xs-3 no-padding">
<div id="wireBox" class="red wireBox"></div>
<input class="cbox" type="radio" id="redWireBox" name="wireBox" value="redWireBox" />
</div>
<div class="flex-xs-3 no-padding">
<div id="wireBox" class="yellow wireBox"></div>
<input class="cbox" type="radio" id="yellowWireBox" name="wireBox" value="yellowWireBox" />
</div>
<div class="flex-xs-3 no-padding">
<div id="wireBox" class="blue wireBox"></div>
<input class="cbox" type="radio" id="blueWireBox" name="wireBox" value="blueWireBox" />
</div>
</div>
</div>
You can use .not() to exclude element i.e : div which is not currently clicked by user and removeClass from them .
Demo Code :
$('#wireColorSelect .wireBox').click(function() {
var checkbox = $(this).parent().find(".cbox");
var wireDOM = $(this)
checkbox.prop('checked', checkbox.is(":checked") ? false : true);
wireDOM.toggleClass('highlightedBox');
//remove checked from other checkboxes
$(".cbox").not(checkbox).prop('checked', false);
//remove highlight class from other
$(".wireBox").not(wireDOM).removeClass("highlightedBox")
});
.wireBox {
border: 1px solid;
height: 50px;
width: 50px;
opacity: 0.5;
}
.white {
background-color: White;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
.highlightedBox {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wireColorSelect">
<div class="flex-row flex-xs-3">
<div class="flex-xs-3 no-padding">
<div class=" white wireBox"></div>
<input class="cbox" type="radio" id="whiteWireBox" name="wireBox" value="whiteWireBox" />
</div>
<div class="flex-xs-3 no-padding">
<div class="red wireBox"></div>
<input class="cbox" type="radio" id="redWireBox" name="wireBox" value="redWireBox" />
</div>
<div class="flex-xs-3 no-padding">
<div class="yellow wireBox"></div>
<input class="cbox" type="radio" id="yellowWireBox" name="wireBox" value="yellowWireBox" />
</div>
<div class="flex-xs-3 no-padding">
<div class="blue wireBox"></div>
<input class="cbox" type="radio" id="blueWireBox" name="wireBox" value="blueWireBox" />
</div>
</div>
</div>

How to set all flex elements with the same width which adapts to the longest text?

I have two groups of checkboxes, each checkbox with a "ring" when mouse hover (i just simplified this in the code below, the ring shows directly, anyway it's not that much important.)
the thing is I need to keep all the checkbox row with the same width, which the width should adapt to the longest text one as well, so all "ring" looks same. (in this case, all the width of the 4 rings the width should be the same as the checkbox1)
.group {
display: flex;
flex-direction: column;
}
.checkbox {
border: 2px solid red;
border-radius: 6px;
width: fit-content;
}
<div class="group">
<h2>Group 1</h2>
<div class="checkbox"><input type="checkbox" id="checkbox1"><label for="checkbox1">checkbox1 super super long texttexttexttexttexttexttexttexttexttext</label></div>
<div class="checkbox"><input type="checkbox" id="checkbox2"><label for="checkbox2">checkbox2</label></div>
</div>
<div class="group">
<h2>Group 2</h2>
<div class="checkbox"><input type="checkbox" id="checkbox3"><label for="checkbox3">checkbox3 abcdabcdabcd abcdabcdabcdabcd</label></div>
<div class="checkbox"><input type="checkbox" id="checkbox4"><label for="checkbox4">checkbox4 abcdabcdabcd</label></div>
</div>
Is there anyway to implement it? (can't set a fixed value, the text length is dynamic)
You should assign width: fit-content to the parent container, not the children.
Also I changed all the inline styles into external styles for better visualization:
.group {
display: flex;
flex-direction: column;
width: fit-content;
}
.input-group {
border: 2px solid red;
border-radius: 6px;
}
<div class="group">
<h2>Group 1</h2>
<div class="input-group">
<input type="checkbox" id="checkbox1" />
<label for="checkbox1">checkbox1 super super long texttexttexttexttexttexttexttexttexttext</label>
</div>
<div class="input-group">
<input type="checkbox" id="checkbox2" />
<label for="checkbox2">checkbox2</label>
</div>
</div>
<div class="group">
<h2>Group 2</h2>
<div class="input-group">
<input type="checkbox" id="checkbox3" />
<label for="checkbox3">checkbox3 abcdabcdabcd abcdabcdabcdabcd</label>
</div>
<div class="input-group">
<input type="checkbox" id="checkbox4" />
<label for="checkbox4">checkbox4 abcdabcdabcd</label>
</div>
</div>

Twitter Bootstrap Button Group Control Radio Buttons/Checkboxes

I am trying to use the Twitter Bootstrap button group as an actual set of form input controls. By default, these button groups can be made to function like a radio button or checkbox group, but since they use the <button> element, they cannot actually be used like a radio button or checkbox.
In my research, I found this site which uses CSS to make these bootstrap buttons actually control radio buttons and checkboxes. The only issue is they use rather recent features of CSS to work, and therefore, require IE9 or above to work.
I would like to extend support to IE8. Is there another (perhaps JS controlled) solution which would offer the same features as the above link without the steep CSS requirements?
Thank you for your time.
Bootstrap 3 has a "native" solution...
There now is a "true" Bootstrap solution for this problem, which appears to work fine also on older browsers. Here's what it looks like:
// get selection
$('.colors input[type=radio]').on('change', function() {
console.log(this.value);
});
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="btn-group colors" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" value="red" autocomplete="off" checked> Red
</label>
<label class="btn btn-primary">
<input type="radio" name="options" value="orange" autocomplete="off"> Orange
</label>
<label class="btn btn-primary">
<input type="radio" name="options" value="yellow" autocomplete="off"> Yellow
</label>
</div>
<!-- jQuery and Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
See the relevant Bootstrap documentation for more information.
Bootstrap 4
Bootstrap 4 supports component the same way as Bootstrap 3, but Bootstrap 4 does not support IE9. You might want to check out the Bootstrap IE8 project.
Bootstrap 2
Try this fiddle
HTML:
<div class="btn-group" data-toggle="buttons-radio">
<button type="button" class="btn btn-primary">Left</button>
<button type="button" class="btn btn-primary">Middle</button>
<button type="button" class="btn btn-primary">Right</button>
</div>
<input type="hidden" id="buttonvalue"/>
Script:
$(".btn-group button").click(function () {
$("#buttonvalue").val($(this).text());
});
then get buttonvalue server side
With Bootstrap 3.2 put the hidden input in the middle of your button group container. Instead of the text content we take the value of th data-value field.
<div id="test" class="btn-group checkit" data-toggle="buttons-radio">
<button type="button" data-value="1" class="btn btn-default active">Yes</button>
<input type='hidden' name="testfield" value='1'>
<button type="button" data-value="0" class="btn btn-default ">No</button>
</div>
Now insert a little javascript snippet into the onload part of your template.
$('.checkit .btn').click(function() {
$(this).parent().find('input').val($(this).data("value"));
});
So you only need to add .checkit to your button group and insert a hidden input field.
With bootstrap 3.2 you can use button groups directly with radio- or checkbox-inputs
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default">
<input type="radio" name="options" id="option1" value="1" /> Yes
</label>
<label class="btn btn-default">
<input type="radio" name="options" id="option2" value="0" /> No
</label>
<label class="btn btn-default">
<input type="radio" name="options" id="option3" value="42" /> Whatever
</label>
</div>
See here:
http://jsfiddle.net/DHoeschen/gmxr45hh/1/
You can use hidden form elements and javascript to use the button state to trigger the form element states.
CSS-only solution:
HTML:
<div class="btn-group">
<label class="btn btn-primary"><input type="checkbox"><span>Button 1</span></label>
<label class="btn btn-primary"><input type="checkbox"><span>Button 2</span></label>
</div>
SCSS/LESS:
label.btn {
margin-bottom: 0;
padding: 0;
overflow: hidden;
span {
display: block;
padding: 10px 15px;
}
input[type=checkbox] {
display: none;
}
input:checked + span {
display: block;
color: #fff;
background-color: #285e8e;
}
}
JSfiddle here
If you don't want to add JS code you can use this pure CSS solution:
HTML:
<div class="btn-group colors">
<label class="btn btn-primary">
<input type="radio" name="g1" value="red" autocomplete="off" checked>
<span class='active'></span>
<span class='label'>RED</span>
<span></span>
</label>
<label class="btn btn-primary">
<input type="radio" name="g1" value="orange" autocomplete="off">
<span class='active'></span>
<span class='label'>ORANGE</span>
</label>
<label class="btn btn-primary">
<input type="radio" name="g1" value="yellow" autocomplete="off">
<span class='active'></span>
<span class='label'>YELLOW</span>
</label>
</div>
CSS:
input {
display:none;
}
input:checked + .active{
background-color: #ff0000;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index:10;
}
.label{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
}
You may need to set a height and width for the buttons in CSS since the spans are positioned absolute.
See here JSFiddle example

Categories

Resources