I have a Vue app with a HTML Form with multiple sets of radio buttons.
I customized their appearance using the SO answer written here
However, when I click on any of the radio buttons, only the first set of radio buttons are affected, even when clicking a different set's radio button.
This is the html and css (JSFiddle link)
Any idea why this is happening?
Update: The problem was with the label tags - their for attribute was still set to the first set of radio buttons!
<div class="time_input" >
<div class="time_input__radio_group">
<div class="radio_group">
<input type="radio" name="start" id="am" :value="true" v-model="startInMorning">
<label class="radio_label" for="am">AM</label>
</div>
<div class="radio_group">
<input type="radio" name="start" id="pm" :value="false" v-model="startInMorning">
<label class="radio_label" for="pm">PM</label>
</div>
</div>
</div>
<div class="days_open_input">
<div class="radio_group" >
<input type="radio" name="days_open" id="one_day" :value="1" v-model="days_open" checked>
<label class="radio_label" for="am">1</label>
</div>
<div class="radio_group">
<input type="radio" name="days_open" id="two_days" :value="2" v-model="days_open">
<label class="radio_label" for="pm">2</label>
</div>
<div class="radio_group">
<input type="radio" name="days_open" id="three_days" :value="3" v-model="days_open">
<label class="radio_label" for="pm">3</label>
</div>
</div>
<div class="tracks_limit_input">
<div class="radio_group">
<input type="radio" name="tracks_limit" id="eight_songs" value="8" v-model="tracks_limit" >
<label class="radio_label " for="am">8</label>
</div>
<div class="radio_group">
<input type="radio" name="tracks_limit" id="sixteen_songs" value="16" v-model="tracks_limit" checked class="tracks_limit_input__margin">
<label class="radio_label" for="pm">16</label>
</div>
</div>
/* completely hiding radio button */
input[type="radio"] {
display: none;
}
/* simulate radiobutton appearance using pseudoselector */
input[type="radio"] + *::before {
content: "";
/* create custom radiobutton appearance */
display: inline-block;
width: 15px;
height: 15px;
padding: 3px;
margin-right: 5px;
/* background-color only for content */
background-clip: content-box;
border: 1px solid #bbbbbb;
background-color: #e7e6e7;
border-radius: 50%;
}
/* appearance of checked radiobutton */
input[type="radio"]:checked + label::before {
background-color: black;
}
/* resetting default box-sizing */
*,
*:before,
*:after {
box-sizing: border-box;
}
/* optional styles for centering radiobuttons */
.radio-group label {
display: inline-flex;
align-items: center;
}
I think there is no mistake with the css
The code you are using for the HTML is the one causes problem:
1st it is Vue code not pure HTML code
I will take the 1st group - the time example:
<div class="time_input" >
<div class="time_input__radio_group">
<div class="radio_group">
<input type="radio" name="start" id="am" :value="true" v-model="startInMorning">
<label class="radio_label" for="am">AM</label>
</div>
<div class="radio_group">
<input type="radio" name="start" id="pm" :value="false" v-model="startInMorning">
<label class="radio_label" for="pm">PM</label>
</div>
</div>
</div>
Both of inputs is set to the same model startInMorning so if it is true both checked and vice versa.
So the fix is:
first remove the v-model="startInMorning" for both
next change the :value
for the first one :value="startInMorning",
for the second one :value="!startInMorning"
Do similar for others
The problem seemed to be with the HTML!
The for attribute on the label tags was set to the wrong radio buttons
ie
<input type="radio" name="days_open" id="two_days" :value="2" v-model="days_open">
<label class="radio_label" for="pm">2</label>
<input type="radio" name="days_open" id="two_days" :value="2" v-model="days_open">
<label class="radio_label" for="pm">2</label>
Related
This is my selector:
<div class="text-center col-lg-6"><h4><strong><FONT COLOR="red">choose the color of your new shoes:</FONT></strong></h4>
<input type="image" src="https://glarza.com/img/black-shoes.webp" name="color" value="1" onclick="...">
<input type="image"src="https://glarza.com/img/red-shoes.webp" name="color" value="2" onclick="...">
</div>
Database: id:1 BLACK ...
id: 2 RED ...
This is my form:
<form action="https://glarza.com/color.php" class="omb_loginForm" autocomplete="off" method="POST" accept-charset="ISO-8859-1">
<div class="input-group col-lg-12">
<span class="input-group-addon">Color..<i class="fa fa-user"></i></span>
<input type="text" class="form-control" name="color" placeholder="color" />
</div>
How to populate the color input inside my form ?
Please if anyone can help me
You should change your input type to radio.
After the user selected a radio button you detect the input change and submit the form with js.
Css code for the image radio group:
/* HIDE RADIO */
[type=radio] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
/* IMAGE STYLES */
[type=radio] + img {
cursor: pointer;
}
/* CHECKED STYLES */
[type=radio]:checked + img {
outline: 2px solid #f00;
}
HTML for the radio image input group:
<label>
<input type="radio" name="color" value="red">
<img src="http://placehold.it/40x60/0bf/fff&text=A">
</label>
<label>
<input type="radio" name="color" value="black">
<img src="http://placehold.it/40x60/b0f/fff&text=B">
</label>
Submit the form on radio group change:
$('input[type=radio][name=color]').change(function() {
document.forms[myFormName].submit()
});
I'm having css issues with a second label on a radio button, when this radio button is checked. I already found out that a second (and a third) label is possible using 'for' in the label-tag. It's not possible to group everything in a single label-tag.
How can I change the background for the second label when a radio button is checked?
My (simplified) code is below, for the first label it works, second label it doesn't.
.radioclass:checked + label {
background-color: cyan;
}
<div class="row">
<div class="col-sm-4">
<input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
<label for="id_radiobtn1">first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn1">second label</label>
</div>
</div>
The + selector in css means "immediate sibling", i.e. the very next element after the input must be a label. This will only select the immediate sibling.
An alternative is ~ which means "any sibling" and targets any label after the input.
In both of these cases, the elements (input and label) are on the same dom level. There is no way to traverse up the dom, grab the sibling and then the label - which is what you are trying to do with the html supplied.
If you are able to change the html, then either place the input outside the two divs or place both labels inside the same div (after the input).
.radioclass:checked ~ div label {
background-color: cyan;
}
<div class="row">
<input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
<div class="col-sm-4">
<label for="id_radiobtn1">first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn1">second label</label>
</div>
</div>
.radioclass:checked ~ label {
background-color: cyan;
}
<div class="row">
<div class="col-sm-4">
<input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
<label for="id_radiobtn1">first label</label>
<label for="id_radiobtn1">second label</label>
</div>
</div>
If you cannot alter the html, then JS is the only other approach (I've changed the input to a checkbox for demonstration purposes):
$('input').on('change', function(){
var func = 'removeClass';
if($(this).is(':checked')) {
func = 'addClass';
}
$('label[for="'+$(this).attr('id')+'"]')[func]('checked');
});
label.checked {
background-color: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-4">
<input class="radioclass" id="id_radiobtn1" type="checkbox" name="radiobtn1" value="1">
<label for="id_radiobtn1">first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn1">second label</label>
</div>
</div>
Using just CSS this is possible, although it does require a rearrangement of your HTML, effectively moving the radio <input> ahead of the elements in which the <label> elements are contained; this removes the (impossible in CSS) requirement of traversing to the parent of the <input> in order to style the non-sibling <label> elements.
/* selects the element with the id of 'id_radiobtn1' when it is
checked, uses the general sibling combinator (~) to select
all sibling <div> elements with the class of 'col-sm-4'
and then finds the descendant <label> elements within
that/those <div> elements whose 'for' attribute-value is
equal to 'id_radiobtn1': */
#id_radiobtn1:checked ~ div.col-sm-4 label[for=id_radiobtn1] {
background-color: cyan;
}
<div class="row">
<input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1" />
<div class="col-sm-4">
<label for="id_radiobtn1">first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn1">second label</label>
</div>
</div>
Now, if you must have a visible radio <input> besides the first of the <label> elements, you can use a pseudo-element to effectively pretend, while also hiding the real radio <input>:
*,
::before,
::after {
/* to include border and padding in the calculated
dimensions (width/height) of the elements: */
box-sizing: border-box;
}
.row>input[type=radio] {
/* hiding the radio <input> elements: */
display: none;
}
/* selecting the <input> elements whose type is
equal to 'radio', which is checked and then
finding all (subsequent) sibling elements
(using the '~' combinator) which <div>
elements with a class of 'col-sm-4', and
traversing to the <label> elements within: */
input[type=radio]:checked~div.col-sm-4 label {
background-color: cyan;
}
label {
/* in order to ensure that the descendant
pseudo-elements are positioned relative
to their parent element: */
position: relative;
/* making room for the pseudo-elements: */
margin-left: 2em;
}
input[type=radio]+.col-sm-4 label::before {
/* the content property is required, even
if only an empty string, to have the
pseudo-element show up: */
content: '';
display: inline-block;
/* positioning absolutely, in relation to
the closest ancestor with a non 'static'
position, in this case the parent
<label> element: */
position: absolute;
/* moving it outside of the <label> element's
left border, to avoid the background-color: */
left: -2em;
/* purely aesthetic: */
width: 0.8em;
height: 0.8em;
/* arbitrary positioning, adjust to taste: */
top: 50%;
transform: translateY(-40%);
/* making the pseudo-element circular in shape: */
border-radius: 50%;
/* colouring the faux 'border': */
box-shadow: 0 0 0 2px #ccc;
}
/* adjusting the colours of the faux radio: */
input[type=radio]:checked+.col-sm-4 label::before {
box-shadow: 0 0 0 2px #000, inset 0 0 0 3px #fff;
background-color: limegreen;
}
<div class="row">
<input class="radioclass" id="id_radiobtn1" type="radio" name="group1" value="1" />
<div class="col-sm-4">
<label for="id_radiobtn1">row one first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn1">row one second label</label>
</div>
</div>
<div class="row">
<input class="radioclass" id="id_radiobtn2" type="radio" name="group1" value="2" />
<div class="col-sm-4">
<label for="id_radiobtn2">row two first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn2">row two second label</label>
</div>
</div>
You can do with Jquery on change event.
$(document).ready(function() {
$('#id_radiobtn1').on('change',function(){
$( "label:contains('second')" ).css( "background-color", "red" );
});
});
.radioclass:checked + label {
background-color: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-4">
<input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
<label for="id_radiobtn1">first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn1">second label</label>
</div>
You can't do it with pure css, because backward in css is impossible.You can help of Jquery:
Note: I insert lab2 class to label.
$(document).ready(function(){
$('input[type=radio]').on('change',function(){
if($('.radioclass').is(':checked'))
$('.lab2').addClass('sel');
else
$('.lab2').removeClass('sel');
})
})
$(document).ready(function(){
$('input[type=radio]').on('change',function(){
if($('.radioclass').is(':checked'))
$('.lab2').addClass('sel');
else
$('.lab2').removeClass('sel');
})
})
#id_radiobtn1:checked + label {
background-color: green;
}
.sel {
background-color: red;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-4">
<input class="radioclass" id="id_radiobtn1" type="radio" name="radiobtn1" value="1">
<label for="id_radiobtn1">first label</label>
</div>
<div class="col-sm-4">
<label for="id_radiobtn1" class="lab2">second label</label>
</div>
</div>
I want to simply uncheck radio button upon clicking the other one in the list. (that's how radio is supposed to work ?)
Here's my code:
<div class="row">
<div class="col-sm-2">
<label>Payment methods:</label>
<input type="radio" name="pp" id="pp" checked>
<label for="pp">
<img src="../img/pp-icon.png">
<div>Paypal</div>
</label>
</div>
<div class="col-sm-2">
<label style="visibility: hidden;">Payment methods:</label>
<input type="radio" name="skrill" id="skrill">
<label for="skrill">
<img src="../img/skrill-icon.png">
<div>Skrill</div>
</label>
</div>
</div>
CSS:
input[type=radio]{ /* HIDE RADIO */
visibility: hidden; /* Makes input not-clickable */
position: absolute; /* Remove input from document flow */
}
input[type=radio] + label>img{ /* IMAGE STYLES */
border-radius: 50%;
border: 1px solid #fff;
padding: 20px;
width: 100px;
cursor: pointer;
transition: 0.2s linear;
}
input[type=radio]:checked + label>img{ /* (RADIO CHECKED) IMAGE STYLES */
background-color: rgba(255, 255, 255, 0.8);
}
PROBLEM DEMO: https://jsfiddle.net/gsda8s6r/ (radio buttons not hidden)
Live photo:
Thanks for your help!
The radio buttons must have same name, you can place the image inside the label tag
here is update fiddle https://jsfiddle.net/gsda8s6r/1/
<div class="col-sm-2">
<label>
<input type="radio" name="payment" id="pp" checked>
<img style="max-height: 100px; width: auto;" src="http://www.aganis.it/siti-web-trento-blog/wp-content/uploads/2015/09/img-logo-paypal.png">
<div>Paypal</div>
</label>
</div>
<div class="col-sm-2">
<label>
<input type="radio" name="payment" id="skrill">
<img style="max-height: 100px; width: auto;" src="https://content.skrill.com/fileadmin/content/images/business/global_coverage_icon.png">
<div>Skrill</div>
</label>
</div>
Check this fiddle: JSFiddle
I have changed some of your CSS, but I think you'll get the trick.
As others told, name of the radio button should be same. And you need to hide your default radio buttons with the following CSS.
input[type=radio].custom {
display: none;
}
Add "custom" class to your radio input tag.
That's it. This is a trick! ;-)
Could anyone give new ideas how to realize the following? If it generally possible).
The content of Left panel will be changed dynamically with Angular. So, we can have several items or, for example, 50 items on the panel. In accordance with that, the height of panel will be shorter or overflow hidden will be displayed.
Here is fiddle draft https://jsfiddle.net/b9on9gup/7/
First of all the div class="filter-title" should fill 100% height.
The second, title container shouldn't be in scrolling area. Scroll should be inside div class="radio-container". You could add class .shown on
div class="main-container" to display bottom panel.
Additional condition is good displaying with and without scroll (different quantity of items, different screen resolutions etc).
in fiddle I was trying different ways, so some css properties can be odd.
<body>
<div class = "main-container">
<div class="left-panel">
<div class="filter-container">
<div class="table">
<div class="table-row">
<div class="radio-container">
<div class="overflow">
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm" />
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm" />
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm" />
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm" />
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
<div>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button
</label>
</div>
</div>
</div>
<div class="filter-title">
<span>
Filter title
</span>
</div>
</div>
</div>
</div>
</div>
<div class="bottom-panel"></div>
</div>
</body>
html, body {
height: 100%;
padding: 0;
position: relative;
margin: 0;
}
.main-container {
position: relative;
overflow: hidden;
height: 100%;
width: 100%;
.left-panel {
top: 0;
left: 0;
bottom: 0;
width: 300px;
background: #fff;
position: absolute;
transition: bottom 0.5s ease;
.filter-container {
position: absolute;
background: #F6F6F6;
top: 50%;
transform: translateY(-50%);
width: 100%;
.table {
display: table;
width: 100%;
.table-row {
display: table-row;
height: 100%;
.radio-container {
display: table-cell;
padding: 25px 25px;
display: table-cell;
vertical-align: middle;
.overflow {
overflow-y: scroll;
max-height: 100%;
}
}
}
.filter-title {
display: table-cell;
width: 20px;
background: #539ACC;
vertical-align: middle;
span {
-webkit-writing-mode: vertical-lr;
white-space: nowrap;
}
}
}
}
}
.bottom-panel {
height: 200px;
position: absolute;
bottom: -200px;
background: #F6F6F1;
width: 80%;
left: 0;
right: 0;
margin: auto;
transition: bottom 0.5s ease;
}
&.shown {
.left-panel {
bottom: 200px;
}
.bottom-panel {
bottom: 0;
}
}
}
UPDATE
It's a simple piece of javascript that you can edit to better fill your needs...
it changes the title height if necessary (it actually changes the element's width since the it's rotated 90deg)
var ftitle = document.querySelector('.filter-title');
var radiocont = document.querySelector('.radio-container');
var w = ftitle.clientWidth;
var h = radiocont.clientHeight;
if (h > w) { ftitle.style.width = h + 'px';}
.left-panel {
position: relative;
width: 150px;
}
/*
.radio-container {
height: 100px;
overflow: auto;
}
*/
.radio-container label {
display: block;
}
.filter-title {
background: #ddd;
text-align: center;
position: absolute;
top: 0; left: 0;
transform: translateX(170px) rotate(90deg);
transform-origin: 0 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class = "main-container">
<div class="left-panel">
<div class="radio-container">
<label>
<input type="radio" name="filterFieldsForm"/>
radio button1
</label>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button2
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button3
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button4
</label>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button5
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button6
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button7
</label>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button8
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button9
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button10
</label>
<label>
<input type="radio" name="filterFieldsForm"/>
radio button11
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button12
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button13
</label>
<label>
<input type="radio" name="filterFieldsForm" />
radio button14
</label>
</div>
<div class="filter-title">
<span>Filter title</span>
</div>
</div>
</div>
</body>
</html>
http://jsbin.com/wiyuhu/edit?css,js,output
The best decision I've found in my case is using max-height for div class= "overflow" and media-queries min-height.
I noticed scroll is displayed if to set max-height for div class= "overflow". But max-height should be at least in 'px', not in '%'.
Also max-height should be different for different resolutions. I set some breakpoints for max-height using media queries. Something like this:
#media(min-height:520px) {
max-height: 170px;
}
#media(min-height:600px) {
max-height: 250px;
}
#media(min-height:768px) {
max-height: 400px;
}
#media(min-height:900px) {
max-height: 500px;
}
.....
It allows me having panel's height shorter than browser view's height in any resolutions and having or not having scroll inside panel (depends on quantity of items)
The same approach is applied to filter title + text-overflow
Here is video - http://take.ms/WBDcy
and here is code - http://plnkr.co/edit/SbMa9Ece2eOPJ2C0Lt5U?p=preview
When I was writing this post I've understood that using of max-height: 80vh maybe was even better than media queries. It should be tested.
I'm using the following mark up and styles (Bootstrap). It shows my checkbox but it is paralysed, that is, it cannot be checked. here is my mark up:
I want something more Bootstrap-ish. I know there are other options to make the checkbox look fancy but that do not solve the problem.
<div class="form-group">
<div class="checkbox">
1.
<input type="checkbox" name="options" id="chk2" />
<label class="checkbox-label">Option 2</label>
</div>
</div>
Here is how it looks.
What exactly is the issue?
If I put the input element inside label I get this ugly thing:
<input type="checkbox" name="options" id="chk2" />
<label class="checkbox-label">Option 2</label>
The problem is with your label. The for attribute must match with the name attribute of your label
Looks need to tweak bootstrap styling for custom checkbox.
Check this
HTML
<div class="form-group">
<div class="checkbox">
<label for="check">
<input type="checkbox" id="check"/>
<span class="fake-input"></span>
<span class="fake-label">Option 2</span>
</label>
</div>
</div
CSS
.fake-input {
float: left;
width: 20px;
height: 20px;
border: 1px solid #9f9f9f;
background: #fff;
vertical-align: middle;
position: relative;
margin-right: 10px;
border-radius: 4px;
}
input[type="checkbox"] {
position: fixed;
top: -9999px;
left: -9999px;
}
input[type="checkbox"]:checked + .fake-input:before {
content:"\2713";
position: absolute;
color: #000;
text-align: center;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
Check in Fiddle
Reading around it looks like you have to style the checked version and the unchecked version.
input[type=checkbox]:checked {
}
Styling with this tag should solve your problems.
Use "for" attribute to solve this issue.
<div class="form-group">
<div class="checkbox">
1.
<input type="checkbox" name="options" id="chk2" />
<label for="chk2" class="checkbox-label">Option 2</label>
</div>
</div>
<div class="col-md-3">
<input class="form-check-input" type="checkbox" id="" asp-for="">
<label class="form-check-label" for="" asp-for="">
</label>
</div>
It's not due to Bootstrap but to Wordpress. The checkboxes became visible after I added "display:block;" to the css of the checkbox input tag.
<input class="form-check-input" type="checkbox" id="">
input.form-check-input {
display:block;
}