I have 2 pricing plan boxes with toggles for monthly and annual pricing. When i click Pay monthly on the Core box, all the numbers change correctly, but what i would like to do is to click either core or pro, and then both move. At the moment, only the Core toggle moves. See the code below, and link to the demo on my staging site.
jQuery
$(document).ready(function() {
var checkBoxes = $("input[name='toggle']");
toggle();
$("#toggle").click(function() {
toggle();
});
function toggle() {
if (checkBoxes.prop("checked")) {
$('#coreMonthlyText,#coreMonthlyPrice,#proMonthlyText,#proMonthlyPrice').show();
$('#coreAnnuallyText,#coreAnnuallyPrice,#proAnnuallyText,#proAnnuallyPrice').hide();
} else {
$('#coreMonthlyText,#coreMonthlyPrice,#proMonthlyText,#proMonthlyPrice').hide();
$('#coreAnnuallyText,#coreAnnuallyPrice,#proAnnuallyText,#proAnnuallyPrice').show();
}
}
});
HTML
<div class="pricing-box" id="core-box">
<div class="row">
<div class="column">
<div class="core">
<h2>Core Plan</h2>
</div>
</div>
<div class="column">
<div id="coreAnnuallyPrice" class="coreAnnuallyPrice">
<h2>$2,399/yr</h2> Normally $3,588/yr
</div>
<div id="coreMonthlyPrice" class="coreMonthlyPrice">
<h2>$99/pm</h2> first 2 months free
</div>
</div>
</div><div class="center_text">
<label for="toggle" class="toggle-switch"><input class="toggle-button" id="toggle" type="checkbox" name="toggle" data-checked="coreAnnuallyPrice,coreAnnuallyText" data-not-checked="coreMonthlyPrice,coreMonthlyText"><span>Pay annually</span><span>Pay monthly</span>
</label>
</div></div>
<div class="pricing-box" id="pro-box">
<div class="row">
<div class="column">
<div class="pro">
<h2>Pro Plan</h2>
</div>
</div>
<div class="column">
<div id="proAnnuallyPrice" class="proAnnuallyPrice">
<h2>$4,199/yr</h2> Normally $5,988/yr
</div>
<div id="proMonthlyPrice" class="proMonthlyPrice">
<h2>$299/pm</h2> first 2 months free
</div>
</div>
</div><div class="center_text">
<label for="toggle" class="toggle-switch"><input class="toggle-button" id="toggle" type="checkbox" name="toggle" data-checked="proAnnuallyPrice,proAnnuallyText" data-not-checked="proMonthlyPrice,proMonthlyText"><span>Pay annually</span>.
<span>Pay monthly</span>
</label>
</div>
</div>
CSS
.toggle-switch {
cursor: pointer;
background-color: #F8F8F9;
display: inline-block;
border: 0;
padding-left: 0;
padding-right: 0;
}
.toggle-switch input {
display: none;
}
.toggle-switch,
.toggle-switch span {
border-radius: 35px;
border-style: solid;
border-color: transparent;
padding-top: 20px;
padding-bottom: 20px;
}
.toggle-switch span {
border-width: 2px;
padding-left: 20px;
padding-right: 20px;
}
.toggle-switch input:checked+span+span,
.toggle-switch input+span {
border: 1px solid #00AEEF !important;
background-color: white !important;
}
.toggle-switch input+span+span,
.toggle-switch input:checked+span {
background-color: #F8F8F9 !important;
border-color: transparent !important;
}
#coreMonthlyText,
#coreMonthlyPrice,
#coreAnnuallyText,
#coreAnnuallyPrice {
display: none;
}
#proMonthlyText,
#proMonthlyPrice,
#proAnnuallyText,
#proAnnuallyPrice {
display: none;
}
Link to webpage
You have duplicate IDs, which will cause problems. You can have duplicate name="toggle" but you likely need to distinguish them somehow.
The main problem is that the state of the toggle changes automatically and you never set the state of the other. It is important to know which one was clicked.
Hence, to keep them "in sync", you can set both toggles to the state of the one that was clicked:
$(document).ready(function() {
var checkBoxes = $("input[name='toggle']");
toggle(checkBoxes.el(0)); // pass first checkbox for initial state
checkBoxes.click(function(event) {
toggle(event.target);
});
function toggle(target) {
var checked = $(target).prop('checked')
// set all checkboxes to the same state
checkBoxes.prop('checked', checked)
// set other properties based on checked state
$('#coreMonthlyText,#coreMonthlyPrice,#proMonthlyText,#proMonthlyPrice')
.toggle(checked)
$('#coreAnnuallyText,#coreAnnuallyPrice,#proAnnuallyText,#proAnnuallyPrice')
.toggle(!checked)
}
});
Related
Currently when I click the 1st button both hidden divs are showing. My goal is when I click the 1st button it only shows the hidden div on its group. And if I click the 2nd button it only shows the hidden div on its group.
Can anyone help me with how to achieve it?
$(document).ready(function () {
$(".btn").on("click", function () {
$(".hidden").addClass("active");
});
$(".closed").on("click", function (){
$(".hidden").removeClass("active")
})
})
.btn {
background: blue;
color: #ffffff;
font-weight: 600;
padding: 20px;
}
.hidden {
width: 100px;
height: 100px;
background: yellow;
display: none;
}
.hidden.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="con">
<div class="btn">Show</div>
<div class="hidden">
<div class="closed">Click to hide</div>
</div>
</div>
</div>
<br>
<div class="container">
<div class="con">
<div class="btn">Show</div>
<div class="hidden">
<div class="closed">Click to hide</div>
</div>
</div>
</div>
Your code
$(".hidden").addClass("active");
selects all .hidden elements (hence your issue).
Within the click event you need to use this to refer to the element being clicked and then use relative DOM navigation to find the element you do want.
In your case it's the next sibling, so .next() will suffice for show, but hide/close will need to find its parent .hidden
$(document).ready(function () {
$(".show").on("click", function () {
$(this).next().addClass("active");
});
$(".close").on("click", function (){
$(this).closest(".hidden").removeClass("active")
})
})
.show {
background: blue;
color: #ffffff;
font-weight: 600;
padding: 20px;
}
.hidden {
width: 100px;
height: 100px;
background: yellow;
display: none;
}
.hidden.active {
display: block;
}
.close { background-color:#ccc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="con">
<div class="show">Show</div>
<div class="hidden">
<div class="close">Click to hide</div>
</div>
</div>
</div>
<br>
<div class="container">
<div class="con">
<div class="show">Show</div>
<div class="hidden">
<div class="close">Click to hide</div>
</div>
</div>
</div>
How it should work:
Open (toggle .show class) on div.user, and displays the .userSub div.
If I click on another div.user, close (remove .show class) and opens the clicked div.userSub
If I click on the already .show-ed div.user (NOT .userSub), it'd close the target div.user.
Almost works but the problem:
when .userSub div is .show-ed, I can only click to close on the .userSub div, not the .user div. However that would be goal. :)
I've tried to eliminate the problem. Probably the .user selection is wrong and I should use stopPropagation() somewhere, or I should be more specific with the child elements, but I can't figure it out.
let $active
$(document).ready(() => {
$(".user").click(function(e) {
if ($active != null) {
$active.toggleClass("show")
}
$(e.target).children().toggleClass("show")
$active = $(e.target).children()
})
})
.user {
background-color: gray;
padding: 20px;
margin: 5px;
}
.userSub {
display: none;
padding: 20px;
background-color: lightgray;
color: black;
margin: 5px;
}
.show {
display: block;
}
button {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="user">
name 1
<div class="userSub">details 1<button>more 1</button></div>
</div>
<div class="user">
name 2
<div class="userSub">details 2<button>more 2</button></div>
</div>
<div class="user">
name 3
<div class="userSub">details 3<button>more 3</button></div>
</div>
To achieve your goal check that the clicked element was the .user element directly, not a child of it. To do that you can use the target property of the event.
Also note that you can simplify the logic by only applying the .show class to the parent .user and having the CSS rules apply the display: block rule to the child elements based on the class on a parent. Try this:
$(document).ready(() => {
let $users = $(".user").click(function(e) {
if (e.target !== this)
return;
$users.not(this).removeClass('show');
$(this).toggleClass("show")
})
})
.user {
background-color: gray;
padding: 20px;
margin: 5px;
}
.userSub {
display: none;
padding: 20px;
background-color: lightgray;
color: black;
margin: 5px;
}
.user.show .userSub {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="user">
name 1
<div class="userSub">details 1<button>more 1</button></div>
</div>
<div class="user">
name 2
<div class="userSub">details 2<button>more 2</button></div>
</div>
<div class="user">
name 3
<div class="userSub">details 3<button>more 3</button></div>
</div>
I'm fairly new to programming and this site but I've been studying different codes for vertical and horizontal tabs and there's a questions I want to ask regarding this one https://jsfiddle.net/eu81273/812ehkyf/ :
Basically, I've been trying to change the width of the tabs in order for them to occupy the whole width of the content block below, however I wasn't able to do it, what should i add/change? Adding width: 200px; in .tab or .tab label doesn't seem to work.
.tabs {
position: relative;
min-height: 200px; /* This part sucks */
clear: both;
margin: 35px 0 25px;
background: white;
}
.tab {
float: left;
}
.tab label {
background: #eee;
padding: 10px;
border: 1px solid #ccc;
margin-left: -1px;
position: relative;
left: 1px;
top: -29px;
-webkit-transition: background-color .17s linear;
}
It would be nice if a detailed explanation is provided on the changes or additions so I can understand it well.
A way with the use of javascript was found, however, is it possible to only uses css and html?
See first of your body padding is so high.
so may be i think you have to decrease it.
body {
background: #999;
padding: 20px 2px;
}
.tabs {
position: relative;
min-height: 200px; /* This part sucks */
clear: both;
margin: 35px 0 25px;
background: white;
width:100%;
}
you can set your tabs width to - 33%
function openTab(tabId) {
var i;
var x = document.getElementsByClassName("tab");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
document.getElementById(tabId).style.display = "block";
}
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet"/>
<div class="w3-bar w3-black">
<button class="w3-bar-item w3-button" onclick="openTab('TabA')">TabA</button>
<button class="w3-bar-item w3-button" onclick="openTab('TabB')">TabB</button>
<button class="w3-bar-item w3-button" onclick="openTab('TabC')">TabC</button>
</div>
<div id="TabA" class="w3-container tab">
<input type="radio" id="tab-1" name="tab-group-1" checked>
<label for="tab-1">Tab One</label>
<div class="content">
<p>Stuff for Tab One</p>
</div>
</div>
<div id="TabB" class="w3-container tab" style="display:none">
<input type="radio" id="tab-2" name="tab-group-1">
<label for="tab-2">Tab Two</label>
<div class="content">
<p>Stuff for Tab Two</p>
<img src="http://placekitten.com/200/100">
</div>
</div>
<div id="TabC" class="w3-container tab" style="display:none">
<input type="radio" id="tab-3" name="tab-group-1">
<label for="tab-3">Tab Three</label>
<div class="content">
<p>Stuff for Tab Three</p>
<img src="http://placedog.com/200/100">
</div>
</div>
<style> .w3-bar .w3-button{
width:33.3%;
}</style>
I am trying to understand, how a can label work in conjunction with elements states like input[type="type=""]:checked or input[type=""]:unchecked.I got a very basic example which I am trying to work out, but I cannot make the label a circle or square that can have a check mark or unchecked when clicked. What makes the label have that outlook and showing checked and unchecked state? Does the label need to have a width and height? If so do I need to make it a block level element.
input[type="checkbox"]{
width:0;
heigh:0;
/* or display:none? */
}
label{
position:relative;
width: 20px;
height: 20px;
cursor: pointer;
}
label:before,
label:after{
font-size:50px;
}
label:before{
content: '\f096'; /
//Can be some good example
}
label:after{
content: '\f00c';
//Can be some good example
}
input[type="checkbox"]:checked{
content:"check"
//Can be some good example
}
input[type="checkbox"]:unchecked{
content:"x"
//Can be some good example
}
Something achievable like this but without text next to labels as I want checkbox based on styling.
you need to make a relationship ( css wise ) between your checkbox and the clicked label and change it's content . use css selectors for that. for example + or ~
in the example below i used :before and :after . :after will appear only when the checkbox is :checked. i think this is what you want.
IMPORTANT ! : you set the same id to all checkboxes this is bad because
duplicate ID's are not a good practice when writing HTML
you link all labels to the same checkbox ( all are linked to the checkbox with id checkbox . in the below example all have different ids and so every label is linked with it's corresponding checkbox
see code below
.img-holder{
position:relative
}
.checkbox-holder{
position:absolute;
background: #fcfff4;
margin-top:5px;
margin-left:10px;
width:50px;
}
input[type="checkbox"]{
width:0;
height:0;
}
label{
position:relative;
width: 20px;
height: 20px;
cursor: pointer;
}
label:before,
label:after{
font-size:50px;
}
label:before{
border:2px solid red;
content:"";
height:20px;
width:20px;
border-radius:100%;
display:inline-block;
}
label:after {
content:'';
position:absolute;
width:10px;
height:10px;
border-radius:100%;
background:green;
top:-2px;
left:7px;
opacity:0;
}
input[type="checkbox"]:checked + label:after {
opacity:1;
}
input[type="checkbox"]:checked + label:before {
border-color:green;
}
<div class="container">
<div class="row">
<div class="col-3 img-holder">
<div class="checkbox-holder">
<input type="checkbox" id="checkbox">
<label for="checkbox">
</div>
<img src="https://placeimg.com/300/480/any/grayscale" alt="">
<!-- <div class="flex-column justify-content-center">
<h4 class="add">Added</h4>
<h4 class="remove">Removed</h4>
</div> -->
</div>
<div class="col-3 img-holder">
<div class="checkbox-holder">
<input type="checkbox" id="checkbox2">
<label for="checkbox2">
</div>
<img src="https://placeimg.com/300/480/any/sephia" alt="">
<!-- <div class="flex-column justify-content-center">
<h4 class="add">Added</h4>
<h4 class="remove">Removed</h4>
</div> -->
</div>
<div class="col-3 img-holder">
<div class="checkbox-holder">
<input type="checkbox" id="checkbox3">
<label for="checkbox3">
</div>
<img src="https://placeimg.com/300/480/nature/grayscale" alt="">
<!-- <div class="flex-column justify-content-center">
<h4 class="add">Added</h4>
<h4 class="remove">Removed</h4>
</div> -->
</div>
<div class="col-3 img-holder">
<div class="checkbox-holder">
<input type="checkbox" id="checkbox4">
<label for="checkbox4">
</div>
<img src="https://placeimg.com/300/480/arch/grayscale" alt="">
<!-- <div class="flex-column justify-content-center">
<h4 class="add">Added</h4>
<h4 class="remove">Removed</h4>
</div> -->
</div>
</div>
</div>
You cannot change the content the label itself, but you can control the content of the pseudo element after and before. You can add the logic of square/circle with something that can represent check and uncheck.
input[type='checkbox'] {
width: 0;
height: 0;
}
input[type='checkbox']:checked + label:after {
content: "checked";
}
Demo
To answer your question in the comment
How they make funky circle buttons and put a checkbox inside it when one clicks?
You can use CSS animations. The label will already have the check symbol in it but won't have shown in the unchecked state of the input box. And when the element is checked, it will change the opacity to 1, showing the checkbox in an animated way.
input[type='checkbox'] {
width: 0;
height: 0;
}
input[type='checkbox'] + label:after {
content: "checked";
opacity: 0;
-webkit-transition: all 0.50s;
-moz-transition: all 0.50s;
-o-transition: all 0.50s;
transition: all 0.50s;
}
input[type='checkbox']:checked + label:after {
opacity: 1;
}
Demo
If you want a custom look and behavior for your checkboxes, you'll have to use some trickery. This involves using CSS to hide your checkboxes and draw a stylable box instead + a ✔ character when your checkbox is selected.
Here's a pretty basic example :
var items = document.getElementsByClassName("item");
for (var i=0; i < items.length; i++) {
items[i].addEventListener("click", function(){
var checkbox = this.querySelector("input[type='checkbox']");
checkbox.checked = checkbox.checked ? false : true;
this.classList.toggle("selected", checkbox.checked);
});
}
.item {
padding: 5px 30px 5px 30px;
display: block;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
}
.item:hover {
cursor: pointer;
}
.checker {
border-color: #333;
position: absolute;
background: #fff;
width:14px;
height:14px;
border: 2px solid #999;
left: 10px;
z-index: -5;
display: block;
}
.selected .checker {
border-color: #2199cb;
}
.checker input {
height: 18px;
width: 18px;
opacity: 0;
border: none;
background: none;
}
.selected .checker:after {
color: #ef8730;
width: 16px;
z-index: 99;
font-size: 28px;
margin-top: -40px;
float: right;
content: "\2714";
}
<div class="item">
<label class="checker">
<input type="checkbox">
</label>
Item 1
</div>
<div class="item selected">
<label class="checker">
<input type="checkbox" checked>
</label>
Item 2
</div>
<div class="item">
<label class="checker">
<input type="checkbox">
</label>
Item 3
</div>
See also this JSFiddle demo
I have 3 divs. 2 of them change their color when focused. Can also an action be performed on another div when 2 of them get focused?
div {
border: 1px solid;
margin: 5px;
width: 300px;
height: 50px;
padding: 2px;
}
.myClass:focus {
background-color: yellow;
outline: none;
}
<div class="myClass" tabindex="-1">
Focus me!
</div>
<div class="myClass" tabindex="-1">
You can focus me too!
</div>
<hr />
<div class="anotherClass">
I cannot be focused, but want to change my color, when one of the other divs above me get focused.
</div>
So when 1 of the 2 upper divs get focused I want the 3rd div at the bottom to change its color.
Here you can have a look: https://jsfiddle.net/ogpvvwtg/
Sure, you can use the general sibling selector ~
.myClass:focus ~ .anotherClass {
background-color: red;
outline: none;
}
div {
border: 1px solid;
margin: 5px;
width: 300px;
height: 50px;
padding: 2px;
}
.myClass:focus {
background-color: yellow;
outline: none;
}
.myClass:focus ~ .anotherClass {
background-color: red;
outline: none;
}
<div class="myClass" tabindex="-1">
Focus me!
</div>
<div class="myClass" tabindex="-1">
You can focus me too!
</div>
<hr />
<div class="anotherClass">
I cannot be focused, but want to change my color, when one of the other divs above me get focused.
</div>
you can do this with a little bit of javascript which might give you more control of the things you want to color.
colorDiv3 = function() {
window.document.getElementById("div3").style.backgroundColor = "lightGreen";
}
div {
border: 1px solid;
margin: 5px;
width: 300px;
height: 50px;
padding: 2px;
}
.myClass:focus {
background-color: yellow;
outline: none;
}
<div class="myClass" tabindex="-1" onFocus="colorDiv3()">
Focus me!
</div>
<div class="myClass" tabindex="-1" onFocus="colorDiv3()">
You can focus me too!
</div>
<hr />
<div id="div3" class="anotherClass">
I cannot be focused, but want to change my color, when one of the other divs above me get focused.
</div>
You can also accomplish this using JavaScript:
First give the divs IDs:
<div id="topDiv" class="myClass" tabindex="-1">
etc...
Then you can find them with:
var top_div = document.getElementById('top_div');
var middle_div = document.getElementById('middle_div');
var bottom_div = document.getElementById('bottom_div');
Assign an event listener to the objects. This allows you to call a function when an element is focused:
top_div.addEventListener("focus", changeBottomDivColor);
middle_div.addEventListener("focus", changeBottomDivColor);
And finally, the function to actually change the color:
function changeBottomDivColor() {
bottom_div.style.backgroundColor = "red";
}