I built a page that has three payment plans. There is also a Toggle switch, to change between Monthly and Annually. I have the price set to ex. $19.99 for monthly and when I click the toggle button to switch to annually I want the price to change to $199.99. Here is the code I have so far. All HTML and CSS so now my JS isn't working for it. What's wrong?
function myFunction() {
var x = document.getElementsByClassName("switch");
if (x.innerHTML === "$19.99") {
x.innerHTML = "$199.99";
} else {
x.innerHTML = "$19.99";
}
}
input.cmn-toggle-round:checked+label:after {
margin-left: 32px;
}
.switch {
position: relative;
left: 47.5%;
}
.cmn-toggle {
position: absolute;
margin-left: -9999px;
visibility: hidden;
}
.cmn-toggle+label {
display: block;
position: relative;
cursor: pointer;
outline: none;
user-select: none;
}
input.cmn-toggle-round+label {
padding: 2px;
width: 50px;
height: 20px;
background-color: #dddddd;
border-radius: 60px;
}
input.cmn-toggle-round+label:before,
input.cmn-toggle-round+label:after {
display: block;
position: absolute;
top: 1px;
left: 1px;
bottom: 1px;
content: "";
}
input.cmn-toggle-round+label:before {
right: 1px;
background-color: #f1f1f1;
border-radius: 60px;
transition: background 0.4s;
}
input.cmn-toggle-round+label:after {
width: 20px;
background-color: #fff;
border-radius: 100%;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
transition: margin 0.4s;
}
input.cmn-toggle-round:checked+label:before {
background-image: Linear-Gradient( to left, hsl(236, 72%, 79%), hsl(237, 63%, 64%)
);
}
<div class="switch" onclick="myFunction()">
<input id="cmn-toggle-1" class="cmn-toggle cmn-toggle-round" type="checkbox" />
<label for="cmn-toggle-1"></label>
</div>
There are several problem with your code. First you compare against the innerHTML property which isn't initially set this can not work until you have a default value.
The next is that you want to set the wrapper containers innerHTML which will remove the button.
In the solution below I introduced an paragraph with an initialValue of 199.95 and then toggle on it.
Also I replaced the incline scripting and used instead an eventListener.
let inp = document.getElementById("cmn-toggle-1");
inp.addEventListener("click", myFunction);
function myFunction() {
var x = document.getElementById("par");
if(x.innerHTML === "$199.99"){
x.innerHTML = "$19.99";
}else{
x.innerHTML = "$199.99";
}
}
input.cmn-toggle-round:checked+label:after {
margin-left: 32px;
}
.switch {
position: relative;
left: 47.5%;
}
.cmn-toggle {
position: absolute;
margin-left: -9999px;
visibility: hidden;
}
.cmn-toggle+label {
display: block;
position: relative;
cursor: pointer;
outline: none;
user-select: none;
}
input.cmn-toggle-round+label {
padding: 2px;
width: 50px;
height: 20px;
background-color: #dddddd;
border-radius: 60px;
}
input.cmn-toggle-round+label:before,
input.cmn-toggle-round+label:after {
display: block;
position: absolute;
top: 1px;
left: 1px;
bottom: 1px;
content: "";
}
input.cmn-toggle-round+label:before {
right: 1px;
background-color: #f1f1f1;
border-radius: 60px;
transition: background 0.4s;
}
input.cmn-toggle-round+label:after {
width: 20px;
background-color: #fff;
border-radius: 100%;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
transition: margin 0.4s;
}
input.cmn-toggle-round:checked+label:before {
background-image: Linear-Gradient( to left, hsl(236, 72%, 79%), hsl(237, 63%, 64%));
}
<div class="switch">
<input id="cmn-toggle-1" class="cmn-toggle cmn-toggle-round" type="checkbox" />
<label for="cmn-toggle-1"></label>
<p id="par">$199.99</p>
</div>
Having just read the comment about using the code to manipulate prices for several elements you need a different approach as using an ID will no longer work - ID attributes must be unique so unless you get tricky with numerically incremented indices and the like ( messy ) you can inspect the target attribute of any click event ( or other type ) and use parent/child/sibling selectors to identify and manipulate nodes of interest.
The HTML below was slightly modified by adding dataset attributes and ignoring any ID attributes present. The CSS was hastily fudged to facilitate the display.... but I think it shows how you might do it.
An event listener is assigned to each parent DIV (.switch) and the currentTarget property of the event is used to find the label which actually receives the click. Using the combination of parentNode and querySelector we can identify the nodes we need to make the logic work
document.querySelectorAll('div.switch').forEach( div=>{
div.addEventListener('click',e=>{
if( e.target === e.target.parentNode.lastElementChild ) {
let span=e.target.parentNode.querySelector('span');
document.documentElement.style.setProperty('--currency','$')
span.dataset.price=e.currentTarget.dataset.state == 1 ? e.currentTarget.dataset.annual : e.currentTarget.dataset.month;
span.dataset.period=e.currentTarget.dataset.state == 1 ? 'Monthly:' : 'Annually:';
span.dataset.currency=document.documentElement.style.getPropertyValue('--currency');
e.currentTarget.dataset.state = 1 - Number( e.currentTarget.dataset.state );
}
})
})
input.cmn-toggle-round:checked + label:after {
margin-left: 32px;
}
.switch {
--left:47.5%;
position: relative;
left: var(--left);
margin:1rem 0 1.5rem 0;
width:calc(80% - var(--left));
}
.cmn-toggle {
position: absolute;
margin-left: -9999px;
visibility: hidden;
}
.cmn-toggle+label {
display: block;
position: relative;
cursor: pointer;
outline: none;
user-select: none;
}
input.cmn-toggle-round+label {
padding: 2px;
width: 50px;
height: 20px;
background-color: #dddddd;
border-radius: 60px;
}
input.cmn-toggle-round+label:before,
input.cmn-toggle-round+label:after {
display: block;
position: absolute;
top: 1px;
left: 1px;
bottom: 1px;
content: "";
}
input.cmn-toggle-round+label:before {
right: 1px;
background-color: #f1f1f1;
border-radius: 60px;
transition: background 0.4s;
}
input.cmn-toggle-round + label:after {
width: 20px;
background-color: #fff;
border-radius: 100%;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
transition: margin 0.4s;
}
input.cmn-toggle-round:checked + label:before {
background-image: Linear-Gradient( to left, hsl(236, 72%, 79%), hsl(237, 63%, 64%) );
}
span:after{
display:inline-block;
float:right;
clear:none;
margin:0;
content:attr(data-period)' 'attr(data-currency)attr(data-price)!important;
}
<div class='switch' data-state=0 data-month='199.99' data-annual='19.99'>
<span></span>
<input id='cmn-toggle-1' class='cmn-toggle cmn-toggle-round' type='checkbox' />
<label for='cmn-toggle-1'></label>
</div>
<div class='switch' data-state=0 data-month='259.99' data-annual='23.99'>
<span></span>
<input id='cmn-toggle-2' class='cmn-toggle cmn-toggle-round' type='checkbox' />
<label for='cmn-toggle-2'></label>
</div>
<div class='switch' data-state=0 data-month='150.00' data-annual='75.00'>
<span></span>
<input id='cmn-toggle-3' class='cmn-toggle cmn-toggle-round' type='checkbox' />
<label for='cmn-toggle-3'></label>
</div>
<div class='switch' data-state=0 data-month='652.50' data-annual='480.50'>
<span></span>
<input id='cmn-toggle-4' class='cmn-toggle cmn-toggle-round' type='checkbox' />
<label for='cmn-toggle-4'></label>
</div>
<div class='switch' data-state=0 data-month='40.00' data-annual='19.99'>
<span></span>
<input id='cmn-toggle-5' class='cmn-toggle cmn-toggle-round' type='checkbox' />
<label for='cmn-toggle-5'></label>
</div>
<div class='switch' data-state=0 data-month='300.00' data-annual='14.99'>
<span></span>
<input id='cmn-toggle-6' class='cmn-toggle cmn-toggle-round' type='checkbox' />
<label for='cmn-toggle-6'></label>
</div>
Related
I need to make that switch slider move to the word user has clicked on (medium or large). I don't know if I can track movement of switch slider with JavaScript or maybe it is possible to do with css. For now, I have only created simple toggle switcher with changing color. The problem is that slider was customised a lot with :before, :checked, input and etc so I don't realise even where to start to make it happen.
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.row-inputs-radio {
display: flex;
justify-content: space-between;
}
.item-size {
margin-left: 10px;
}
.item-size-eg {
font-size: 15px;
color: rgb(155, 154, 154);
}
.continue-btn button {
outline: none;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 10px;
margin-top: 15px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: -74px;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
width: 187px;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: -3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
border: 1px solid grey;
}
input:checked + .slider {
background-color: #13985C;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(120px);
-ms-transform: translateX(120px);
transform: translateX(162px);
}
<div class="column-input">
<div class="row-inputs row-inputs-radio">
<div class="row-input">
<div class="item-size"><bold>Medium</bold></div>
</div>
<div class="row-input">
<label class="switch">
<input type="checkbox" checked />
<span class="slider round"></span>
</label>
</div>
<div class="row-input">
<div class="item-size"><bold>Large</bold></div>
</div>
</div>
Let's go step by step:
We get the medium, large, and input elements
Add onclick eventListeners to them for toggling
Add cursor: pointer to show they're clickable
var medium = document.querySelector('.medium'),
large = document.querySelector('.large'),
slider = document.querySelector('.switch input');;
medium.onclick = function() {
slider.checked = false;
}
large.onclick = function() {
slider.checked = true;
}
.medium, .large {
cursor: pointer;
}
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.row-inputs-radio {
display: flex;
justify-content: space-between;
}
.item-size {
margin-left: 10px;
}
.item-size-eg {
font-size: 15px;
color: rgb(155, 154, 154);
}
.continue-btn button {
outline: none;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 10px;
margin-top: 15px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: -74px;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
width: 187px;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: -3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
border: 1px solid grey;
}
input:checked+.slider {
background-color: #13985C;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(120px);
-ms-transform: translateX(120px);
transform: translateX(162px);
}
<div class="column-input">
<div class="row-inputs row-inputs-radio">
<div class="row-input">
<div class="item-size medium">
<bold>Medium</bold>
</div>
</div>
<div class="row-input">
<label class="switch">
<input type="checkbox" checked />
<span class="slider round"></span>
</label>
</div>
<div class="row-input">
<div class="item-size large">
<bold>Large</bold>
</div>
</div>
</div>
Using addEventListener()
The wanted behavior can be achieved by adding an event-listener to the labels to (un-)check the checkbox.
We can use Event delegation to only add one event-listener to the parent. We can use a boolean that tells us if the clicked label is the "on"-label (meaning, the label that should check the checkbox).
This boolean can immediately be used as the value the .checked-attribute should now have. Quick explanation:
Is the label the "on"-label? If yes, do check
Is the label the "on"-label? If no, do not check
In pseudo-code, it would look like this:
checkbox.checked = isOnLabel
We can check if the clicked label is the "on"-label by looking if the .row-input-div it is inside of is the last one.
Note:
Only adding a click-listener to an element which isn't clickable by default doesn't make it accessible.
To make an element accessible clickable, one would have to:
Add all the appropriate listeners (click-listener, key-listener; specific elements listen for specific keys, e.g. a button for 'space', an anchor for 'enter', a radio-group for the arrow-keys)
Make the element ARIA-conform (use semantically meaningful HTML, e.g. specific HTML-elements, aria-role, aria-label)
This can be quite a lot of work, so unless there is a good reason to create an element from new, one should stick to what is currently given in the HTML-specification (though it is easier to read up on HTML-elements on MDN).
Here is the snippet to show the result:
Note: The code also works for multiple .column-inputs.
for (let ci of document.querySelectorAll('.column-input')) {
ci.addEventListener('click', evt => {
let ri = evt.target.closest('.row-input'); // Get the '.row-input'-div
if (ri.querySelector('.item-size')) { // If `ri` contains '.item-size' / a label, continue
// '!ri.nextElementSibling' is true if `ri` is the last element
ci.querySelector('input').checked = !ri.nextElementSibling;
}
});
}
.slider.round {border-radius: 34px}
.slider.round:before {border-radius: 50%}
.row-inputs-radio {
display: flex;
justify-content: space-between;
}
.item-size {margin-left: 10px}
.item-size-eg {
font-size: 15px;
color: rgb(155, 154, 154);
}
.continue-btn button {outline: none}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 10px;
margin-top: 15px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: -74px;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
width: 187px;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: -3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
border: 1px solid grey;
}
input:focus + .slider {box-shadow: 0 0 1px #2196F3}
input:checked + .slider {background-color: #13985C}
input:checked + .slider:before {
-webkit-transform: translateX(120px);
-ms-transform: translateX(120px);
transform: translateX(162px);
}
<div class="column-input">
<div class="row-inputs row-inputs-radio">
<div class="row-input">
<div class="item-size"><bold>Medium</bold></div>
</div>
<div class="row-input">
<label class="switch">
<input type="checkbox" checked />
<span class="slider round"></span>
</label>
</div>
<div class="row-input">
<div class="item-size"><bold>Large</bold></div>
</div>
</div>
</div>
<div class="column-input">
<div class="row-inputs row-inputs-radio">
<div class="row-input">
<div class="item-size"><bold>Mayo</bold></div>
</div>
<div class="row-input">
<label class="switch">
<input type="checkbox" checked />
<span class="slider round"></span>
</label>
</div>
<div class="row-input">
<div class="item-size"><bold>Ketchup</bold></div>
</div>
</div>
</div>
HTML/CSS only
One could also make a slider-like element using radio-groups, where the radio-group would consist of two elements: "on" and "off".
In combination with labels, the user (sighted or tool-assisted) knows what both options of the sliders are, and can select one accordingly, either by using the mouse or by using the keyboard.
You can try it yourself! Tab to the radio-group, and press the arrow-keys.
Associating a label with an input-element has the following advantages:
It correctly labels its input-element for tools (e.g. screen-readers)
Clicking a label behaves the same way as clicking its input-element itself
(the effect we achieved before using addEventListener() is implemented for associated labels by default)
It doesn't require any JavaScript
For graphics, instead of misusing an HTML-element, I used SVG in combination with CSS.
Having multiple input-elements has the advantage of being able to give each one an individual value. This might be useful for submitting a <form>, so that the back-end would have an easier time figuring out what the values mean (e.g. a radio-groups' "Mayo" / "Ketchup" versus a checkbox' "Mayo or Ketchup" = (true | false)). This also makes maintenance easier, and the back-end wouldn't have to look into front-end code to understand the meaning of a value.
Notice the aria-hidden="true"-attribute for the <label>s inside the <svg>. That tells the browser to ignore those tags for building the Accessibility Tree, meaning only the labels with the labelling content will be associated with their input-elements.
As far as I know, this should be one way to make the slider-mechanic you want fully accessible, for both mouse- and keyboard-users, as well as sighted and tool-assisted users.
/* OPTIONAL
*
* HTML-element can be used without JS.
* However, one would need to manually add
* the radio-names in these places:
* - as <input>'s names
* - prepend <input>'s id
* - prepend <label>'s for
*/
for (var rs of document.querySelectorAll('.radio-slider')) {
var rsName = rs.getAttribute('data-name') || 'broken';
for (var rsInput of rs.querySelectorAll('input')) {
rsInput.id = rsName + rsInput.id;
rsInput.name = rsName;
}
for (var rsLabel of rs.querySelectorAll('label')) {
rsLabel.setAttribute('for', rsName + rsLabel.getAttribute('for'));
}
}
/* Tool-classes (TC); DO NOT CHANGE */
/* TC: '.sr-only' */
.sr-only {
position: absolute;
margin: -1px;
padding: 0;
clip: rect(0,0,0,0);
width: 1px;
height: 1px;
border: 0;
overflow: hidden;
}
/* TC: '.radio-slider' */
.radio-slider svg { /* Dimension of 8:5 */
width: 2rem;
height: 1.25rem;
}
.radio-slider > div {display: flex}
.radio-slider input:focus-visible ~ div {outline: auto}
.radio-slider input:focus-visible ~ div svg rect {fill: #2196F3}
.radio-slider circle,
.radio-slider rect {transition: 0.5s}
.radio-slider foreignObject > label {
width: 100%;
height: 18px;
display: block;
}
.radio-slider .on:checked ~ div svg foreignObject:last-child {display: none}
.radio-slider .on:checked ~ div svg rect {fill: #13985C}
.radio-slider .on:checked ~ div svg circle {transform: translateX(calc(2rem - 16px))}
<div class="radio-slider" data-name="radio1">
<input id="-off" class="sr-only off" type="radio">
<input id="-on" class="sr-only on" type="radio">
<div>
<label for="-off">Medium</label>
<svg viewBox="0 0 32 20" xmlns="xmlns=http://www.w3.org/1999/xhtml" stroke="black" fill="lightgray" stroke-width="0.5">
<rect x="4" y="4" rx="4" width="24" height="8" />
<circle cx="8" cy="8" r="6" fill="white" />
<foreignObject width="100%" height="100%"><label for="-off" aria-hidden="true"></label></foreignObject>
<foreignObject width="100%" height="100%"><label for="-on" aria-hidden="true"></label></foreignObject>
</svg>
<label for="-on">Large</label>
</div>
</div>
<div class="radio-slider" data-name="radio2">
<input id="-off" class="sr-only off" type="radio">
<input id="-on" class="sr-only on" type="radio">
<div>
<label for="-off">Mayo</label>
<svg viewBox="0 0 32 20" xmlns="xmlns=http://www.w3.org/1999/xhtml" stroke="black" fill="lightgray" stroke-width="0.5">
<rect x="4" y="4" rx="4" width="24" height="8" />
<circle cx="8" cy="8" r="6" fill="white" />
<foreignObject width="100%" height="100%"><label for="-off"></label></foreignObject>
<foreignObject width="100%" height="100%"><label for="-on"></label></foreignObject>
</svg>
<label for="-on">Ketchup</label>
</div>
</div>
In my example, I did not assign a unique class to each side. And so I used the forEach() method.
let select = document.querySelectorAll('.row-input .item-size');
let checked_pos = document.querySelector('.row-input .switch input[type="checkbox"]');
Array.from(select).forEach(function(selectCurrent, index) {
selectCurrent.onclick = function() {
if (index == 0) {
checked_pos.checked = false;
}
if (index == 1) {
checked_pos.checked = true;
}
}
});
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.row-inputs-radio {
display: flex;
justify-content: space-between;
}
.item-size {
margin-left: 10px;
}
.item-size-eg {
font-size: 15px;
color: rgb(155, 154, 154);
}
.continue-btn button {
outline: none;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 10px;
margin-top: 15px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: -74px;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
width: 187px;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: -3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
border: 1px solid grey;
}
input:checked + .slider {
background-color: #13985C;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(120px);
-ms-transform: translateX(120px);
transform: translateX(162px);
}
<div class="column-input">
<div class="row-inputs row-inputs-radio">
<div class="row-input">
<div class="item-size"><bold>Medium</bold></div>
</div>
<div class="row-input">
<label class="switch">
<input type="checkbox" checked/>
<span class="slider round"></span>
</label>
</div>
<div class="row-input">
<div class="item-size"><bold>Large</bold></div>
</div>
</div>
I doing a tshirt designing website for my college project.I have added preview option where when the user types it get displayed on the tshirt present in the iframe..I have also added a proceed button, when the user clicks on it,I want the text to get stored in database but for some reason I cant get it to work.I am using ajax and php for the database part.But the javascript part with ajax is not working.Even alert function is not working for onclick funtction..
Any help is appreciated..
$(document).ready(function)() {
$("#btn").click( function() {
var tshirt-text =$('#tshirt-text').val();
var size =$('#size').val();
alert("tshirt-text");
$.ajax ({
type :'POST',
data :{tshirt-text:tshirt-text,size:size},
url :"storeinfo.inc.php",
success :function(result)
})
});
});
var $text = $( '.tshirt-text' );
var $demoText = $( '.demo-tshirt-text' );
$text.on( 'keyup', function ( e ) {
$demoText.text( $text.val() );
} );
body{
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
padding: 0px;
overflow-x: hidden;
font-family: sans-serif;
}
header{
padding: 8px;
height:155px;
color: white;
background-color:#6495ED;
clear: left;
width:100%;
}
footer
{ padding: 4px;
color: white;
background-color:#6495ED;
width:100%;
text-align:center;
font-size:20px;
font-family:Arial;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
width:100%;
}
li {
float: left;
}
li a,.dropbtn {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-family: Arial;
font-size: 20px;
}
li a:hover:not(.active), .dropdown:hover .dropbtn {
background-color: #111;
}
li a.active {
background-color: royalblue;
}
li.dropdown {
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: royalblue;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {
display: block;
}
h2.tagline
{
text-align:center;
font-size:35px;
font-style:italic;
font-family: "Florence", cursive;
margin-top:-100px;
margin-left:-80px;
}
iframe {
width: 700px;
height: 700px;
margin: -590px 90px 20px 650px;
display: inline-block;
position: relative;
border:none;
}
.designcontainer {
display: inline-block;
margin:0 0 0 10px;
}
.colorbutton {
background-color: #4CAF50; /* Green */
border: none;
color: black;
padding: 15px 30px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
margin: 4px 2px;
cursor: pointer;
border-radius: 14px;
transition-duration: 0.4s;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
}
.colorbutton:active {
background-color: #3e8e41;
box-shadow: 0 5px #666;
transform: translateY(4px);
}
.buttonw {background-color: white; color:black;} /* White */
.buttonb {background-color: blue; color:white;} /* Blue */
.buttonr {background-color: #f44336; color:white;} /* Red */
.buttony {background-color: yellow; } /* Yellow */
#keyframes click-wave {
0% {
height: 40px;
width: 40px;
opacity: 0.35;
position: relative;
}
100% {
height: 200px;
width: 200px;
margin-left: -80px;
margin-top: -80px;
opacity: 0;
}
}
.option-input {
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
position: relative;
top: 5.33333px;
right: 0;
bottom:0;
left: 0;
height: 25px;
width: 25px;
transition: all 0.15s ease-out 0s;
background: #cbd1d8;
border: none;
color: #fff;
cursor: pointer;
display: inline-block;
margin-right: 0.5rem;
outline: none;
position: relative;
z-index: 1000;
line-height: 50px;
}
.option-input:hover {
background: #9faab7;
}
.option-input:checked {
background: royalblue;
}
.option-input:checked::before {
height: 15px;
width: 15px;
position: absolute;
content: '\2714';
display: inline-block;
font-size: 26.66667px;
text-align: center;
line-height: 28px;
}
.option-input:checked::after {
-webkit-animation: click-wave 0.65s;
-moz-animation: click-wave 0.65s;
animation: click-wave 0.65s;
background: royalblue;
content: '';
display: block;
position: relative;
z-index: 100;
}
.option-input.radio {
border-radius: 50%;
}
.option-input.radio::after {
border-radius: 50%;
}
.labelname
{
font-size: 20px;
}
span {
position: relative;
display: inline-block;
margin: 30px 10px;
}
.gate {
display: inline-block;
width: 500px;
height: 100px;
padding: 10px 0 10px 15px;
font-family: "Open Sans", sans;
font-weight: 400;
color: royalblue;
background: #c6c6c6;
border: 0;
border-radius: 10px;
outline: 0;
text-indent: 65px;
transition: all .3s ease-in-out;
}
.gate::-webkit-input-placeholder {
color: #c6c6c6;
text-indent: 0;
font-weight: 300;
font-size:18px;
}
.gate + label {
display: inline-block;
position: absolute;
top: 0;
left: 0;
padding: 10px 15px;
text-shadow: 0 1px 0 rgba(19, 74, 70, 0.4);
background: royalblue;
transition: all .4s ease-in-out;
border-radius:5px;
transform-origin: left bottom;
z-index: 99;
color:white;
size:18px;
}
.gate + label:before, .gate + label:after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border-radius: 10px;
background: royalblue;
transform-origin: left bottom;
transition: all .4s ease-in-out;
pointer-events: none;
z-index: -1;
font-size:18px;
}
.gate + label:before {
background: rgba(3, 36, 41, 0.2);
z-index: -2;
right: 20%;
font-size:18px;
}
span:nth-child(2) .gate {
text-indent: 85px;
}
span:nth-child(2) .gate:focus,
span:nth-child(2) .gate:active {
text-indent: 0;
}
.gate:focus,
.gate:active {
color: ;
text-indent: 0;
background:#c6c6c6;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
.gate:focus::-webkit-input-placeholder,
.gate:active::-webkit-input-placeholder {
color: floralwhite;
}
.gate:focus + label,
.gate:active + label {
transform: rotate(-66deg);
border-radius: 3px;
}
.gate:focus + label:before,
.gate:active + label:before {
transform: rotate(10deg);
}
.demo-tshirt {
position: relative;
width: 200px;
height: 100px;
margin: 0 0 0 890px;
z-index:999;
}
.demo-tshirt-text {
position: absolute;
top: 30%;
left: 45%;
width: 60%;
transform: translateX( -45%);
font-size:25px;
color: black;
font-family: Arial, sans-serif;
}
.spacereducer101{
margin-top:-80px;
}
<!DOCTYPE html>
<html>
<head>
<title>
T-shirtinator-PERSONALIZE
</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="jquery-1.5.min.js"></script>
<LINK REL="icon" HREF="image/favicon.ico">
<link rel="stylesheet" type="text/css" href="css/pshirts.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<header>
<br>
<img src="image/logo.png" >
<h2 class=tagline>"The T-shirt you design <br>
at your doorstep"</h2>
</header>
<ul>
<li>Home</li>
<li><a class="active" href="#ptshirts">Personalized T-shirts</a></li>
<li class="dropdown">
Buy From Us
<div class="dropdown-content">
Quotes printed T-shirts
Graphic printed T-shirts
Memes printed T-shirts
</div>
</li>
<li>Help</li>
<li>Contact Us</li>
<li onclick="document.getElementById('id02').style.display='block'"style="float:right">Sign Up</li>
<li onclick="document.getElementById('id01').style.display='block'" style="float:right">Login</li>
</ul>
<div class="designcontainer">
<h1>Select Colour</h1>
<button class="colorbutton buttonw">White</button>
<button class="colorbutton buttonr">Red</button>
<button class="colorbutton buttonb">Blue</button>
<button class="colorbutton buttony">Yellow</button>
<h1>Select Size</h1>
<div>
<label class="labelname">
<input type="radio" class="option-input radio" id="size" name="size" value="small" checked />
Small(S)
</label>
<label class="labelname">
<input type="radio" class="option-input radio" id="size" name="size" value="medium" />
Medium(M)
</label>
<label class="labelname">
<input type="radio" class="option-input radio" id="size" name="size" value="large"/>
Large(L)
</label>
</div>
<div class=spacereducer101> </div>
<div class="demo-tshirt">
<div class="demo-tshirt-text"></div>
</div>
<h1>Enter the Text you want on your T-shirt</h1>
<span>
<input type="text" name="tshirt-text" class="tshirt-text gate" id="tshirt-text" placeholder="Max 10 letters.." />
<label for="tshirt-text">Enter</label>
</span>
<br>
<input type="button" id="btn" name="Proceed" value="Proceed" class="colorbutton" style="margin-top:20px; margin-left:200px;">
<iframe name="myiframe" src="iframetshirtwhite.html"></iframe>
</div>
<footer >
Copyright © 2017 www.DAJ.com
</footer>
</body>
</html>
PHP code:
<?php
$connection =mysqli_connect('localhost','root','','textstorage');
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if($_POST['tshirt-text']){
$tshirt-text =$_POST['tshirt-text'];
$size =$_POST['size'];
$q = "insert into information values('','tshirt-text','size')";
$query = mysqli_query($connection,$q);
if ($query) {
echo"data inserted";
}
}
?>
If you check the console, you'll see that the problem is the first line inside of the javascript click function...
var tshirt-text = $('#tshirt-text').val();
... because '-' is not a valid character for javascript variable names. Just change it by tshirttext (in all your code), and you will see the alert and should be able to go on.
I hope it helps
You've got some errors with you JavaScript. Try running your JavaScript through a validator (for example, http://beautifytools.com/javascript-validator.php) to see where your errors are. In addition to the one A. Iglesias found, you've got an extra clothes parenthesis on line 1, the same tshirt-text error from line 3 is repeated on line 9, and your syntax for an event handler for success on line 13 isn't right, but I can't tell what you're trying to do.
You've also got a conceptual problem. Lines 17 through 22 should be inside your $(document).ready handler. The ready event runs after the initial HTML is loaded into the browser and ready to go, so any reference to HTML elements outside of that event handler may be referring to them before they're ready.
I wanted to make this a comment to your question, but it's too long, so hopefully it's okay an answer. Perhaps once you've fixed some of these JavaScript issues, post an update to your question in the form of an edit and we can then see what else is going on if it's not working.
edit: I reformatted your JavaScript and tried to resolve any syntax errors. If you open up your browser developer tools and run this JS Fiddle (with comments and without comments), you'll see there are no syntax errors in the console. That doesn't mean it works, just that it's syntactically valid. In fact, this shouldn't work, because the AJAX success handler I wrote simply logs the response.
$(document).ready ( // When function parameters and code blocks are big, I like to
// put the opening ( or { at the end of line and put the the
// closing } or ) in the same column way at the end. I find it
// is easier to keep track of openings and closings.
function() { // no extra close parenthesis right after "function"
$("#btn").click(
function()
{
var tshirtText = $('#tshirt-text').val(); // Variable names can only be
// letters, numbers, dollar symbols,
// and underscores. They cannot start
// with numbers.
var size = $('#size').val();
alert("tshirt-text");
$.ajax(
{ // For clarity, I'll separate out the opening ( and opening {
// and the closing } and closing ) when they are one after the other.
type: 'POST'
// I like to put my commas on the next line rather than the previous line.
// I think it makes it more clear that you're moving on to the next thing.
, data: { "tshirt-text": tshirtText, size: size } // You can specify names in
// this JSON-style syntax that
// aren't valid JavaScript
// identifiers, but you have
// to put them in quotes.
, url: "storeinfo.inc.php"
, success: function(data, textStatus, jqXhr)
{
console.log(data);
}
}
);
}
);
var $text = $('.tshirt-text');
var $demoText = $('.demo-tshirt-text');
$text.on(
'keyup'
, function (e) {
$demoText.text($text.val());
}
);
}
);
I have a page that I need to convert to rtl.
The active tab & tab arrow position doesn't match.
I need to change the tab arrow position from TAB 1 to TAB 2 and vice versa.
I already changed some js value but in vain
HTML :
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="main-search-container">
<form class="main-search-form">
<div class="search-type">
<label class="active"><input class="first-tab" name="tab" checked="checked" type="radio">TEXT</label>
<label><input name="tab" type="radio">TEXT</label>
<label><input name="tab" type="radio">TEXT</label>
<div class="search-type-arrow"></div>
</div>
<div class="main-search-box">
<div class="main-search-input larger-input">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
CSS :
body {
direction:rtl;
color: #707070;
background-color: #cccccc;
}
.parallax {
background-repeat: no-repeat;
background-position: 50% 50%;
position: relative;
z-index: 99;
}
.parallax-overlay {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
z-index: 101;
background-color: #333;
opacity: 0.4;
}
.parallax-content {
position: relative;
z-index: 999;
padding: 105px 0;
}
.main-search-container {
transform: translate3d(0,-12px,0);
}
.main-search-form {
width: 660px;
display: block;
margin: 0 auto;
position: relative;
margin-top: 35px;
}
.search-type {
display: inline-block;
padding-bottom: 35px;
position: relative;
}
.search-type input[type="radio"] { display: none; }
.search-type label {
background-color: #fff;
color: #333;
cursor: pointer;
display:inline-block;
text-align: center;
padding: 9px 18px;
margin: 0 0 0 15px;
float: right;
transition: all 0.2s;
border-radius: 3px;
}
.search-type label:hover,
.search-type label.active {
background-color: #66676b;
color: #fff;
}
.search-type-arrow {
width: 0;
height: 0;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid #fff;
position: absolute;
bottom: 0;
right: 0;
transform: translate3d(-3px,0,0);
}
.main-search-box {
background-color: #fff;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.12);
padding: 30px;
padding-bottom: 20px;
margin-top: -9px;
border-radius: 3px;
}
.main-search-box.no-shadow {
box-shadow: none;
padding: 0;
margin: 0;
}
.search-container .main-search-input input {
font-weight: 500;
font-size: 17px;
height: 57px !important;
float: right;
box-sizing: border-box;
border: none;
float: right;
height: auto;
}
.search-container .main-search-input button.button {
width: initial;
min-width: 100px;
max-width: 100px;
margin: 0;
font-size: 18px;
position: relative;
margin-right: 20px;
flex: 0 auto;
height: 57px;
}
.search-container .main-search-input button.button i {
position: relative;
right: 2px;
}
JS :
(function($){
"use strict";
$(document).ready(function(){
function searchTypeButtons() {
// Radio attr reset
$('.search-type label.active input[type="radio"]').prop('checked',true);
// Positioning indicator arrow
var buttonWidth = $('.search-type label.active').width();
var arrowDist = $('.search-type label.active').position().left;
$('.search-type-arrow').css('right', arrowDist + (buttonWidth/2) );
$('.search-type label').on('change', function() {
$('.search-type input[type="radio"]').parent('label').removeClass('active');
$('.search-type input[type="radio"]:checked').parent('label').addClass('active');
// Positioning indicator arrow
var buttonWidth = $('.search-type label.active').width();
var arrowDist = $('.search-type label.active').position().left;
$('.search-type-arrow').css({
'right': arrowDist + (buttonWidth/2),
'transition':'right 0.4s cubic-bezier(.87,-.41,.19,1.44)'
});
});
}
// Init
if ($(".main-search-form").length){
searchTypeButtons();
$(window).on('load resize', function() { searchTypeButtons(); });
}
// ------------------ End Document ------------------ //
});
})(this.jQuery);
I'm using bootstrap, bootstrap rtl flipped & jquery 2.2.0 as external ressources.
Here's the snippet:
https://jsfiddle.net/s3hy37nd/5/
Can someone help with that?
So many errors... I can only say I tried to comment them all inside the code so... yeah it's all there:
"use strict";
jQuery(function($) { // DOM ready and $ alias secured
// Radio attr reset (on DOM ready... makes sense?)
$('.search-type label.active input[type="radio"]').prop('checked', true);
function repositionArrow() { // Use a meaningful fn name
// Positioning indicator arrow
// Width? No. You need .outerWidth! you have paddings!!
var buttonWidth = $('.search-type label.active').outerWidth();
// Again use meaningful names
// If you do console.log( $('.search-type label.active').position() );
// you'll see no `.right` property. So yeah, use .left
var posLeft = $('.search-type label.active').position().left;
$('.search-type-arrow').css({
left: posLeft + (buttonWidth / 2)
// No need for transition here - move it to Stylesheet instead
});
}
// Init
if ($(".main-search-form").length) {
// You might want this too inside the "if"
$('.search-type label').on('change', function() {
$('.search-type input[type="radio"]').parent('label').removeClass('active');
$('.search-type input[type="radio"]:checked').parent('label').addClass('active');
repositionArrow(); // Now you have such function
});
repositionArrow();
$(window).on('load resize', repositionArrow);
}
});
body {
direction: rtl;
color: #707070;
background-color: #cccccc;
}
.parallax {
background-repeat: no-repeat;
background-position: 50% 50%;
position: relative;
z-index: 99;
}
.parallax-overlay {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
z-index: 101;
background-color: #333;
opacity: 0.4;
}
.parallax-content {
position: relative;
z-index: 999;
padding: 105px 0;
}
.main-search-container {
transform: translate3d(0, -12px, 0);
}
.main-search-form {
width: 660px;
display: block;
margin: 0 auto;
position: relative;
margin-top: 35px;
}
.search-type {
display: inline-block;
padding-bottom: 35px;
position: relative;
}
.search-type input[type="radio"] {
display: none;
}
.search-type label {
position: relative;
/* YOU NEED SOME POSITION! */
background-color: #fff;
color: #333;
cursor: pointer;
display: inline-block;
text-align: center;
padding: 9px 18px;
margin: 0 0 0 15px;
/*float: right; WHY? you use rtl already */
transition: all 0.2s;
border-radius: 3px;
}
.search-type label:hover,
.search-type label.active {
background-color: #66676b;
color: #fff;
}
.search-type-arrow {
width: 0;
height: 0;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid #fff;
position: absolute;
bottom: 0;
/*right: 0; ...Nope. See JS, we need left */
left: calc(100% - 30px);
/* calc to the rescue */
/*transform: translate3d(-3px,0,0); but why */
transition: left 0.4s cubic-bezier(.87, -.41, .19, 1.44);
/* Moved from JS */
}
.main-search-box {
background-color: #fff;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.12);
padding: 30px;
padding-bottom: 20px;
margin-top: -9px;
border-radius: 3px;
}
<div class="parallax-content">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="main-search-container">
<form class="main-search-form">
<div class="search-type">
<label class="active"><input class="first-tab" name="tab" checked="checked" type="radio">TAB 1</label>
<label><input name="tab" type="radio">TAB 2</label>
<label><input name="tab" type="radio">TAB 3</label>
<div class="search-type-arrow"></div>
</div>
<div class="main-search-box">
<div class="main-search-input larger-input">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
Updated jsFiddle
I have a specific situation where we nest tooltip in <label> (which we use for to implement custom radio button design).
event.preventDefault() works fine with 'click' on the tooltip but fails on 'mousedown' where it triggers :active state of the hidden <input> field. Thus changing the styling of fake radio button.
I made a small example to demonstrate what is happening.
const $tooltipElement = $('.tooltip');
$tooltipElement.on('click', (event) => {
event.preventDefault();
})
label {
position: relative;
display: inline-block;
margin-right: 10px;
}
input {
opacity: 0;
left: 0;
position: absolute;
overflow: hidden;
pointer-events: none;
}
.box {
width: 15px;
height: 15px;
border-radius: 50%;
border: 1px solid gray;
display: inline-block;
cursor: pointer;
}
input:checked+.box {
background: blue;
}
input:active+.box {
background: red;
}
.text {
cursor: pointer;
}
.tooltip {
display: inline-block;
width: 8px;
height: 8px;
border: 2px solid red;
}
.tooltip:active {
background: gray;
}
.tooltip:active::before {
content: attr(data-content);
position: absolute;
width: 100px;
height: 80px;
background-color: #fff;
text-align: center;
top: 100%;
left: 50%;
transform: translateX(-50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>
<input type="radio" name="radio">
<span class="box"></span>
<span class="text">Option 1</span>
<span class="tooltip" data-content="Message 1" tab-index="0"></span>
</label>
<label>
<input type="radio" name="radio">
<span class="box"></span>
<span class="text">Option 2</span>
<span class="tooltip" data-content="Message 2" tab-index="0"></span>
</label>
This is how it looks when holding mousedown on tooltip. Radio circle, must remain the same, but it changes to red bg color...
jsFiddle here
How is this: instead of putting the tooltip in the label, put it in a span the wraps the label and tooltip (moving your label styles to this span):
const $tooltipElement = $('.tooltip');
$tooltipElement.on('click', (event) => {
event.preventDefault();
})
.wrapper {
position: relative;
display: inline-block;
margin-right: 10px;
}
input {
opacity: 0;
left: 0;
position: absolute;
overflow: hidden;
pointer-events: none;
}
.box {
width: 15px;
height: 15px;
border-radius: 50%;
border: 1px solid gray;
display: inline-block;
cursor: pointer;
}
input:checked+.box {
background: blue;
}
input:active+.box {
background: red;
}
.text {
cursor: pointer;
}
.tooltip {
display: inline-block;
width: 8px;
height: 8px;
border: 2px solid red;
}
.tooltip:active {
background: gray;
}
.tooltip:active::before {
content: attr(data-content);
position: absolute;
width: 100px;
height: 80px;
background-color: #fff;
text-align: center;
top: 100%;
left: 50%;
transform: translateX(-50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="wrapper">
<label>
<input type="radio" name="radio">
<span class="box"></span>
<span class="text">Option 1</span>
</label>
<span class="tooltip" data-content="Message 1" tab-index="0"></span>
</span>
<span class="wrapper">
<label>
<input type="radio" name="radio">
<span class="box"></span>
<span class="text">Option 2</span>
</label>
<span class="tooltip" data-content="Message 2" tab-index="0"></span>
</span>
I have CSS tabs:
.tabs {
width: 100%;
height: 100%;
margin: 0 0 30px;
}
.tabs label {
float: left;
display: inline;
margin: 0 1px -1px 0;
padding: 0 13px 1px;
color: #777;
cursor: pointer;
background: #F9F9F9;
border: 1px solid #E4E4E4;
border-bottom: 1px solid #F9F9F9;
position: relative;
line-height: 25px;
z-index: 1;
}
.tabs label:hover {
color: #F70;
padding: 0 13px;
background: #FFFFDF;
border: 1px solid #FFCA95;
}
.tabs input {
position: absolute;
left: -9999px;
}
#tab_1:checked ~ #tab_l1,
#tab_2:checked ~ #tab_l2 {
color: #444;
background: #EFEFEF;
padding: 0 13px 2px;
border: 1px solid #D4D4D4;
border-bottom: 1px solid #EFEFEF;
z-index: 3
}
.tabs_cont {
position: relative;
height: 552px;
border: 1px solid #DDD;
border-width: 1px;
background: #EFEFEF;
padding: 0 12px;
z-index: 2;
}
.tabs_cont > div {
position: absolute;
left: -9999px;
top: 0;
opacity: 0;
-moz-transition: opacity .2s ease-in-out;
-webkit-transition: opacity .2s ease-in-out;
transition: opacity .2s ease-in-out;
}
#tab_1:checked ~ .tabs_cont #tab_c1,
#tab_2:checked ~ .tabs_cont #tab_c2 {
position: static;
left: 0;
opacity: 1;
}
and html:
<section class="tabs">
<input id="tab_1" type="radio" name="tab" checked="checked" />
<input id="tab_2" type="radio" name="tab" />
<label for="tab_1" id="tab_l1">Изображения</label>
<label for="tab_2" id="tab_l2">Текст</label>
<div style="clear:both"></div>
<div class="tabs_cont">
<div id="tab_c1"> </div>
<div id="tab_c2">
<div class="add_element" id="add_text">добавить текст </div>
<div id="text_inputs_wrapper"> </div>
</div>
</div>
</section>
And JS:
$("div#add_text").click(function () //on add input button click
{
alert( "Handler for .click() called." );
});
When the page is in the upper position, the event is running. If I`m use scroll and page move - event is not running.
The problem occurs in all browsers.
Has anyone encountered this problem? Help please.
UPDATE.
Please see picture
in this case the event is running
http://1drv.ms/1wg73ak
in this case the event is not running
http://1drv.ms/1mt24JS
As Vector said, you can only click on the #add_text div to trigger the event. The #add_text div is only has a height of one line so you have to click right on the text.
Add a height: 100% to your tab_c2 and to the #add_text then you can click anywhere on the 2nd tab page to trigger the event.
Append this code to your css, your div#add_text will fill the entire container area and the click is works in all position
#add_text {
background-color: red; //remove this later
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
}