I'm currently building a Twitter clone for my portfolio using Web Component's template feature. However, my template isn't rendering on screen when the tweet button is clicked. I'm currently getting an error 'Uncaught TypeError: Cannot set property 'innerHTML' of null at HTMLButtonElement.postTweetButton.onclick'.
I have attempted moving the 'tweetText.innerHTML = tweetBoxInput;' line around to no avail. My tweetText variable's value is correct so I'm not sure why the property cannot set. I suspect it's to do with the template not importing correctly.
JS FIDDLE: https://jsfiddle.net/manoj1234/mty68qng/13/
Help greatly appreciated. Thanks.
JS:
window.onload = () => {
const createTweetContainer = document.getElementById("createTweetContainer");
const createTweetButton = document.getElementById("createTweetButton");
const backArrow = document.getElementById("backArrow");
const tweetBox = document.getElementById("tweetBox");
let tweetBoxInput;
const pinnedTweet = document.getElementById("pinnedTweet");
const tweetContainer = document.getElementById("tweetContainer");
const tweetSentContainer = document.getElementById("tweetSentContainer");
createTweetButton.onclick = () => {
createTweetContainer.style.display = "block";
tweetBox.value = "";
}
backArrow.onclick = () => {
createTweetContainer.style.display = "none";
}
postTweetButton.onclick = () => {
var tweetText = document.getElementById("tweetText");
console.log(tweetBox.value);
tweetBoxInput = tweetBox.value;
if (tweetBoxInput == "") {
console.log("please write tweet");
} else {
createTweetContainer.style.display = "none";
tweetSentContainer.style.display = "flex";
var tweetTemplate = document.getElementById("tweet-template");
var tweetInstance = document.importNode(tweetTemplate.content, true);
tweetText.innerHTML = tweetBoxInput;
pinnedTweet.after(tweetInstance);
/* Show Tweet Sent container*/
setTimeout(() => {
tweetSentContainer.style.height = "30px";
}, 1000);
setTimeout(() => {
tweetSentContainer.style.opacity = "1";
}, 1300);
/* End of Show Tweet Sent container */
/* Hide Tweet Sent container */
setTimeout(() => {
tweetSentContainer.style.opacity = "0";
}, 5000);
setTimeout(() => {
tweetSentContainer.style.height = "0";
tweetSentContainer.style.marginBottom = "0";
}, 5300);
setTimeout(() => {
tweetSentContainer.style.display = "none";
tweetSentContainer.style.marginBottom = "12px";
}, 8000);
/*End of Hide Tweet Sent container */
}
}
}
CSS:
* {
margin: 0;
padding: 0;
transition: ease 0.2s;
box-sizing: border-box;
-webkit-user-drag: none;
appearance: none;
outline: none;
font-family: 'Roboto';
}
body {
display: flex;
justify-content: center;
align-items: center;
}
body main {
width: 480px;
/*background-color: $blueBackground;
*/
}
.globalWrap {
padding-left: 25px;
padding-right: 25px;
}
.greyText {
color: #8997a2;
font-weight: normal;
}
.bodyText {
font-size: 15px;
}
#bottomFixed {
width: 100%;
position: fixed;
bottom: 0;
z-index: 4;
display: flex;
align-items: flex-end;
flex-direction: column;
}
#bottomFixed #createTweetButton {
width: 65px;
height: 65px;
font-size: 1.2em;
display: flex;
justify-content: center;
align-items: center;
color: white;
border-radius: 360px;
background-color: #1da1f2;
margin-bottom: 12px;
margin-right: 10px;
}
#bottomFixed #navBar {
height: 50px;
width: 100%;
background-color: #15202b;
border-top: solid 1px #38444d;
}
#bottomFixed #tweetSentContainer {
height: 30px;
height: 0px;
bottom: 20;
z-index: 6;
background-color: #1da1f2;
width: 80%;
display: flex;
align-self: center;
display: none;
opacity: 0;
justify-content: space-between;
align-items: center;
padding-left: 25px;
padding-right: 25px;
margin-bottom: 12px;
border-radius: 5px;
transition: ease-in-out 0.3s;
}
#coverImgContainer {
height: 125px;
width: 100%;
}
#coverImgContainer img {
height: 100%;
width: 100%;
position: relative;
object-fit: cover;
}
#userProfile {
width: 100%;
background-color: #15202b;
color: white;
}
#userProfile #userImgContainer {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
#userProfile #userImgContainer button {
margin-top: 12px;
background-color: transparent;
border: solid 1px #1da1f2;
padding-left: 12px;
padding-right: 12px;
padding-top: 6px;
padding-bottom: 6px;
border-radius: 25px;
color: #1da1f2;
font-size: 0.8em;
}
#userProfile #userImgContainer h2 {
font-size: 1em;
}
#userProfile #userImgContainer #profileImgName {
position: relative;
bottom: 25;
}
#userProfile #profilePicContainer {
height: 80px;
width: 80px;
}
#userProfile #profilePicContainer img {
width: 100%;
border-radius: 100%;
border: solid 4px #15202b;
}
#userProfile #profileNav {
display: flex;
justify-content: space-between;
margin-top: 16px;
}
#userProfile #profileNav h4 {
padding-left: 10px;
padding-right: 10px;
padding-bottom: 12px;
font-size: 16px;
color: #8997a2;
}
#userProfile #profileNav h4:nth-child(1) {
color: #1da1f2;
border-bottom: solid 2px #1da1f2;
padding-left: 25px;
padding-right: 25px;
}
#userProfile #profileNav h4:nth-child(4) {
padding-right: 25px;
}
#userProfile #userInfo p:nth-child(1) {
position: relative;
bottom: 12.5;
}
#userProfile #userInfo p:nth-child(2) {
position: relative;
bottom: 6.25;
display: flex;
}
#userProfile #userInfo p:nth-child(3) {
font-weight: bold;
margin-top: 4px;
font-size: 14px;
}
#userProfile #userInfo span {
font-weight: normal;
}
#userProfile #userInfo span:nth-child(1) {
margin-right: 6px;
}
#userProfile #userInfo svg {
width: 5%;
color: #8997a2;
fill: #8997a2;
margin-right: 5px;
display: none;
}
#timelineContainer {
background-color: #12161e;
height: 100vh;
width: 100%;
}
.tweetContainer {
display: flex;
padding-top: 12px;
padding-bottom: 12px;
padding-left: 25px;
padding-right: 25px;
width: 100%;
background-color: #15202b;
border-top: solid 1px #38444d;
transition: ease-in-out 0.3s;
}
.tweetContainer .tweetName {
color: white;
}
.tweetContainer .tweetText {
color: white;
margin-bottom: 12px;
}
.tweetContainer #tweetText {
color: white;
margin-bottom: 12px;
}
.tweetContainer .tweetImgContainer {
width: 100%;
height: 200px;
display: flex;
border-radius: 12px;
overflow: hidden;
/*Add this to main container so the Border-Radius also rounds child elements*/
border: solid 1px #38444d;
}
.tweetContainer .tweetImgContainer #col-1ImgContainer {
width: 100%;
overflow: hidden;
}
.tweetContainer .tweetImgContainer #col-1ImgContainer img {
height: 100%;
width: 100%;
object-fit: cover;
border-right: solid 5px #12161e;
}
.tweetContainer .tweetImgContainer .col-2ImgContainer {
height: 50%;
overflow: hidden;
}
.tweetContainer .tweetImgContainer .col-2ImgContainer:nth-child(1) {
border-bottom: solid 5px #12161e;
}
.tweetContainer .tweetImgContainer .col-2ImgContainer img {
transform: scale(1.5, 1.5);
height: 100%;
width: 100%;
object-fit: cover;
}
.tweetProfileImgContainer {
min-width: 55px;
min-height: 55px;
max-width: 55px;
max-height: 55px;
padding-right: 12px;
}
.tweetProfileImgContainer .tweetProfileImg {
width: 100%;
border-radius: 100%;
}
/* Create Tweet Page */
#createTweetContainer {
height: 100vh;
width: 100%;
background-color: #15202b;
position: fixed;
z-index: 5;
display: none;
}
#createTweetContainer img {
margin-right: 12px;
margin-left: 25px;
}
#createTweetContainer #createTweetHeader {
height: 45px;
border-bottom: solid 1px #38444d;
color: white;
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 25px;
padding-right: 25px;
}
#createTweetContainer #createTweetHeader i {
color: #1da1f2;
}
#createTweetContainer #createTweetHeader button {
background-color: #1da1f2;
border: solid 1px #1da1f2;
padding-left: 24px;
padding-right: 24px;
padding-top: 6px;
padding-bottom: 6px;
border-radius: 25px;
color: white;
font-size: 0.8em;
font-weight: bold;
opacity: 0.5;
}
#profileTweetBoxContainer {
display: flex;
justify-content: space-between;
padding-top: 12px;
}
textarea {
margin-left: 25px;
width: 100%;
resize: none;
background-color: #15202b;
border: 0;
color: white;
outline: none;
padding-right: 25px;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
position: relative;
top: 10;
caret-color: #1da1f2;
}
HTML:
<script src="https://kit.fontawesome.com/cd801faa65.js" crossorigin="anonymous"></script>
<div id="bottomFixed">
<div id="createTweetButton">
<i class="fas fa-feather"></i>
</div>
<div id="tweetSentContainer">
<p><i class="fas fa-check-circle"></i>Your Tweet was sent.</p>
<p>View</p>
</div>
<div id="navBar">
</div>
</div>
<section id="createTweetContainer">
<div id="createTweetHeader">
<i id="backArrow" class="fas fa-arrow-left"></i>
<button id="postTweetButton">Tweet</button>
</div>
<div id="profileTweetBoxContainer">
<figure class="tweetProfileImgContainer">
<img class="tweetProfileImg" src="https://cdn.pixabay.com/photo/2016/11/08/15/21/user-1808597_1280.png">
</figure>
<textarea id="tweetBox" cols="500" rows="10" placeholder="What's Happening?"></textarea>
</div>
</section>
<section id="timelineContainer">
<div id="pinnedTweet" class="tweetContainer">
<figure class="tweetProfileImgContainer">
<img class="tweetProfileImg" src="https://cdn.pixabay.com/photo/2016/11/08/15/21/user-1808597_1280.png">
</figure>
<div>
<h4 class="tweetName bodyText">Name <span class="greyText">#username</span></h4>
<p class="tweetText bodyText">Tweet Text Here</p>
<div class="tweetImgContainer">
<div id="col-1ImgContainer">
<img src="https://cdn.getyourguide.com/img/tour/5ac513c518061.jpeg/146.jpg">
</div>
</div>
</div>
</div>
<template id="tweet-template">
<div id="tweetContainer" class="tweetContainer">
<figure class="tweetProfileImgContainer">
<img class="tweetProfileImg" src="images/profilepicture.jpg">
</figure>
<div>
<h4 class="tweetName">Emmanuel</h4>
<p id="tweetText"></p>
</div>
</div>
</template>
</section>
I realised I was attempting to change the original template's p tag rather than the imported node. I added tweetInstance.querySelectorAll(‘p’)[0].innerHTML = tweetBoxInput; which changes the text of the new node.
Related
I'm trying to put some links in a footer next to each other, separated by the character "|". But I have a navbar whose styles interferes with the footer's links.
I need something like this :
This is my code (it doesn't display perfectly, but you get the gist):
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#200;300;400;500&display=swap');
* {
box-sizing: border-box;
scroll-behavior: smooth;
font-family: 'Poppins', sans-serif;
}
body {
/*background-color: #e0eafc;*/
background: linear-gradient( to right,#ff0000,#0000ff);
margin: 0;
}
p {
color:#ffffff;
font-size:20px;
padding: 10px;
}
.heading {
margin: 20px;
font-size: 50px;
text-align: center;
color: black;
}
a {
text-decoration: none;
}
.favcolorcontainer {
border: 2px solid black;
border-radius: 4px;
width: auto;
padding: 5px;
background: white;
display: inline-flex;
}
.colorpicker {
border:none;
background: white;
display: inline-flex;
}
.favcolor {
font-family: verdana;
margin-top: 3px;
}
.slideshow-container {
display: block;
width: 80%;
position: relative;
margin: 10px;
margin-left: auto;
margin-right: auto;
}
.mySlides {
display: none;
}
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover, .next:hover {
background-color: #a6a6a650;
}
.slide-name {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
.slide-number {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
.fade {
animation-name: fade;
animation-duration: 1.5s;
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
.progress-bar {
width: 100%;
border: none;
border-radius: 100px;
background-color: #FFFFFF;
padding: 3px;
}
.progress-tag {
color: #DDDDDD;
margin-left: 10px;
}
.fill-html {
width: 75%;
background-color: #FA3200;
border-radius: 100px;
}
.fill-css {
width: 60%;
background-color: #0000C8;
border-radius: 100px;
}
.fill-js {
width: 10%;
background-color: #C80000;
border-radius: 100px;
}
.fill-php {
width: 3%;
background-color: #00C832;
border-radius: 100px;
}
.fill-rwpd {
width: 100%;
background-color: #450099;
border-radius: 100px;
}
#return {
display: none;
position: fixed;
bottom: 30px;
right: 35px;
z-index: 99;
border: none;
outline: none;
background-color: #0000d1;
color: white;
cursor: pointer;
border-radius: 100px;
font-size: 45px;
width: 60px;
height: 60px;
}
#return:hover {
background-color: #0101bb;
}
.progress-container {
padding: 10px;
}
.header-logo {
margin: 10px;
float: left;
}
.header {
background-color: #303030;
overflow: hidden;
width: 100%;
}
.desktop-nav {
float: right;
margin-right: 20px;
}
.desktop-nav a {
margin: 20px 30px 0 30px;
padding: 0 0 20px;
display: block;
color: white;
}
.desktop-nav a:hover {
color: #b4b4b4;
transition: 0.2s all ease;
}
.desktop-nav li {
float: left;
list-style: none;
}
.menu-button {
display: block;
margin: 15px;
font-size:25px;
cursor:pointer;
color:white
}
.menu-button:hover {
cursor: pointer;
}
.copyright {
color: #b4b4b4;
font-size: 15px;
}
footer {
background: #303030;
padding: 25px 0;
text-align: center;
bottom: 0;
width: 100%;
height: auto;
display: block;
}
.hyperlink {
display: inline-block;
position: relative;
color: #b4b4b4;
}
.hyperlink:after {
content: '';
position: absolute;
width: 100%;
transform: scaleX(0);
height: 2px;
bottom: 15px;
left: 0;
background-color: #b4b4b4;
transform-origin: bottom right;
transition: transform 0.25s ease-out;
}
.hyperlink:hover:after {
transform: scaleX(1);
transform-origin: bottom left;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: #111111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 35px;
margin-left: 50px;
}
.recipe-container {
margin: 0px;
padding: 10px;
display: grid;
grid-template-columns: auto auto auto;
justify-content: center;
}
.recipe-window {
margin: 10px;
padding: 10px;
border: 1px solid #ffffff;
background-color: #ffffff;
word-break: break-word;
width: min-content;
border-radius: 10px;
}
.recipe-title {
color: black;
margin-top: 5px;
padding: 0px;
font-size: 25px;
}
:root {
color-scheme: dark;
}
<html>
<head>
<title>Home</title>
<link rel="icon" type="image/x-icon" href="https://imgur.com/dFEoiLv">
<link rel="stylesheet" href="main.css">
<link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet">
</head>
<body>
<div class="header">
<img src="https://imgur.com/JntIYPP" width="150px" title="Aeron" alt="logo" class="header-logo">
<ul class="desktop-nav">
<li>Home</li>
<li>Portfolio</li>
<li>Contact</li>
<li>Demo</li>
<li>Recipes</li>
<li>Progress</li>
<li>PC Setup Designer</li>
<li>Gallery</li>
<li><span class="menu-button" onclick="openNav()">☰</span></li>
</ul>
<div id="mySidenav" class="sidenav">
×
</div>
</div>
<h1 class="heading">Welcome to Aeron</h1>
<div style="height:100%"></div>
<footer>
<img src="./images/logo.png" width="150px" title="Aeron" alt="logo" class="footer-logo">
<p class="copyright">Copyright © 2022 Aeron Corporation</p>
About Us
<p>|</p>
Policy
<p>|</p>
Contact Us
</footer>
<button onclick="topFunction()" id="return" title="Return To Top">^</button>
<script>
let mybutton = document.getElementById("return");
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
function topFunction() {
document.body.scrollTop = 0;
}
function openNav() {
document.getElementById("mySidenav").style.width = "25%";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
</script>
</body>
</html>
As you can see the links aren't displaying inline. How can I fix this?
Wrap the links in a div with a class (I gave it footer-links) and give it the following styles:
.footer-links {
display: flex;
justify-content: center;
align-items: center;
}
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#200;300;400;500&display=swap');
* {
box-sizing: border-box;
scroll-behavior: smooth;
font-family: 'Poppins', sans-serif;
}
body {
/*background-color: #e0eafc;*/
background: linear-gradient( to right,#ff0000,#0000ff);
margin: 0;
}
p {
color:#ffffff;
font-size:20px;
padding: 10px;
}
.heading {
margin: 20px;
font-size: 50px;
text-align: center;
color: black;
}
a {
text-decoration: none;
}
.favcolorcontainer {
border: 2px solid black;
border-radius: 4px;
width: auto;
padding: 5px;
background: white;
display: inline-flex;
}
.colorpicker {
border:none;
background: white;
display: inline-flex;
}
.favcolor {
font-family: verdana;
margin-top: 3px;
}
.slideshow-container {
display: block;
width: 80%;
position: relative;
margin: 10px;
margin-left: auto;
margin-right: auto;
}
.mySlides {
display: none;
}
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover, .next:hover {
background-color: #a6a6a650;
}
.slide-name {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
.slide-number {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
.fade {
animation-name: fade;
animation-duration: 1.5s;
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
.progress-bar {
width: 100%;
border: none;
border-radius: 100px;
background-color: #FFFFFF;
padding: 3px;
}
.progress-tag {
color: #DDDDDD;
margin-left: 10px;
}
.fill-html {
width: 75%;
background-color: #FA3200;
border-radius: 100px;
}
.fill-css {
width: 60%;
background-color: #0000C8;
border-radius: 100px;
}
.fill-js {
width: 10%;
background-color: #C80000;
border-radius: 100px;
}
.fill-php {
width: 3%;
background-color: #00C832;
border-radius: 100px;
}
.fill-rwpd {
width: 100%;
background-color: #450099;
border-radius: 100px;
}
#return {
display: none;
position: fixed;
bottom: 30px;
right: 35px;
z-index: 99;
border: none;
outline: none;
background-color: #0000d1;
color: white;
cursor: pointer;
border-radius: 100px;
font-size: 45px;
width: 60px;
height: 60px;
}
#return:hover {
background-color: #0101bb;
}
.progress-container {
padding: 10px;
}
.header-logo {
margin: 10px;
float: left;
}
.header {
background-color: #303030;
overflow: hidden;
width: 100%;
}
.desktop-nav {
float: right;
margin-right: 20px;
}
.desktop-nav a {
margin: 20px 30px 0 30px;
padding: 0 0 20px;
display: block;
color: white;
}
.desktop-nav a:hover {
color: #b4b4b4;
transition: 0.2s all ease;
}
.desktop-nav li {
float: left;
list-style: none;
}
.menu-button {
display: block;
margin: 15px;
font-size:25px;
cursor:pointer;
color:white
}
.menu-button:hover {
cursor: pointer;
}
.copyright {
color: #b4b4b4;
font-size: 15px;
}
footer {
background: #303030;
padding: 25px 0;
text-align: center;
bottom: 0;
width: 100%;
height: auto;
display: block;
}
.hyperlink {
display: inline-block;
position: relative;
color: #b4b4b4;
}
.hyperlink:after {
content: '';
position: absolute;
width: 100%;
transform: scaleX(0);
height: 2px;
bottom: 15px;
left: 0;
background-color: #b4b4b4;
transform-origin: bottom right;
transition: transform 0.25s ease-out;
}
.hyperlink:hover:after {
transform: scaleX(1);
transform-origin: bottom left;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: #111111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 35px;
margin-left: 50px;
}
.recipe-container {
margin: 0px;
padding: 10px;
display: grid;
grid-template-columns: auto auto auto;
justify-content: center;
}
.recipe-window {
margin: 10px;
padding: 10px;
border: 1px solid #ffffff;
background-color: #ffffff;
word-break: break-word;
width: min-content;
border-radius: 10px;
}
.recipe-title {
color: black;
margin-top: 5px;
padding: 0px;
font-size: 25px;
}
:root {
color-scheme: dark;
}
.footer-links {
display: flex;
justify-content: center;
align-items: center;
}
.footer-links p {
margin: 0;
}
<html>
<head>
<title>Home</title>
<link rel="icon" type="image/x-icon" href="https://imgur.com/dFEoiLv">
<link rel="stylesheet" href="main.css">
<link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet">
</head>
<body>
<div class="header">
<img src="https://imgur.com/JntIYPP" width="150px" title="Aeron" alt="logo" class="header-logo">
<ul class="desktop-nav">
<li>Home</li>
<li>Portfolio</li>
<li>Contact</li>
<li>Demo</li>
<li>Recipes</li>
<li>Progress</li>
<li>PC Setup Designer</li>
<li>Gallery</li>
<li><span class="menu-button" onclick="openNav()">☰</span></li>
</ul>
<div id="mySidenav" class="sidenav">
×
</div>
</div>
<h1 class="heading">Welcome to Aeron</h1>
<div style="height:100%"></div>
<footer>
<img src="./images/logo.png" width="150px" title="Aeron" alt="logo" class="footer-logo">
<p class="copyright">Copyright © 2022 Aeron Corporation</p>
<div class="footer-links">
About Us
<p>|</p>
Policy
<p>|</p>
Contact Us
</div>
</footer>
<button onclick="topFunction()" id="return" title="Return To Top">^</button>
<script>
let mybutton = document.getElementById("return");
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
function topFunction() {
document.body.scrollTop = 0;
}
function openNav() {
document.getElementById("mySidenav").style.width = "25%";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
</script>
</body>
</html>
I'm a javascript novice, and I have a problem that bothers me~
I often need to write a function to click a button to pop up a modal. The interaction logic of this function is repeated, but sometimes the UI or copywriting needs to be adjusted~
So I want to know How can such a repetitive function be packaged into a component, and other pages need to use modal-like functions in the future, which can be directly referenced and only need to change the copy without rewriting CSS / HTML / JavaScript?
// 匯出 excel 彈窗 JS
$("*[data-modal]").on("click", Modeal);
function Modeal() {
$(".excel_popup").css("display", "flex");
$("body").css("overflow", "hidden");
// 關閉彈窗
$(document).on("click", function(e) {
if (
e.target.className == "close" ||
e.target.className == "excel_popup" ||
e.target.className == "btn_confirm" ||
e.target.className == "btn_consider"
) {
$("#js-job_excel_popup").css("display", "none");
$("body").css("overflow", "auto");
}
});
}
.excel_popup {
position: fixed;
z-index: 999999999;
width: 100%;
height: 100vh;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: rgba(0, 0, 0, 0.3);
justify-content: center;
align-items: center;
display: none;
}
.excel_popup .excel_close_wrap {
width: 360px;
background-color: #fff;
padding: 16px 24px;
border-radius: 8px;
margin: 0 8px;
}
.excel_popup .excel_close_wrap header {
position: relative;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #222;
padding-bottom: 16px;
}
.excel_popup .excel_close_wrap header h2 {
font-size: 18px;
line-height: 1.5;
font-weight: 500;
text-align: center;
}
.excel_popup .excel_close_wrap header .close {
position: absolute;
right: 0;
display: inline-block;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-size: contain;
cursor: pointer;
}
.excel_popup .excel_close_wrap .txt {
font-size: 16px;
font-weight: 400;
line-height: 1.5;
text-align: center;
padding: 32px 0px;
color: #222;
}
.excel_popup .excel_close_wrap .btn_group {
display: flex;
justify-content: space-between;
font-size: 14px;
line-height: 1.5;
letter-spacing: 0.15px;
}
.excel_popup .excel_close_wrap .btn_group .btn_consider {
width: 132px;
text-align: center;
padding: 8px;
border-radius: 4px;
border: 1px solid #222;
margin-right: 4px;
cursor: pointer;
}
.excel_popup .excel_close_wrap .btn_group .btn_consider:hover {
border: 1px solid #222;
}
.excel_popup .excel_close_wrap .btn_group .btn_confirm {
width: 132px;
text-align: center;
padding: 8px;
border-radius: 4px;
border: 1px solid #222;
background-color: #222;
margin-left: 4px;
cursor: pointer;
color: #fff;
}
.excel_popup .excel_close_wrap .btn_group .btn_confirm:hover {
background-color: yellow;
border: 1px solid #222;
color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="excel_export" id="js-excel_export" href="javascript:;" data-modal="js-job_excel_popup">
<figure></figure>
<p>Click the popup</p>
</a>
<div class="excel_popup" id="js-job_excel_popup">
<div class="excel_close_wrap">
<header>
<h2>TITLE</h2>
<div class="close" id="js-close"></div>
</header>
<p class="txt">Hello World!!!</p>
<div class="btn_group">
<a class="btn_consider">Cancel</a>
<a class="btn_confirm">Send</a>
</div>
</div>
</div>
I am trying to figure out why my list of results is looking the way it does after I clear my input field, It seems an extra list item with a comma as its value is being to my list of search results. When I clear my input field, I would like My search results to display the way they do when the user first opens the modal
let results = document.querySelector(".result-list")
let listItems = results.getElementsByTagName('li')
$('button').click(function() {
$('#school-popup-modal').attr('style', 'display:flex')
$('#select-buttons').attr('style', 'display:none')
})
$('#cancel-btn').click(function(e) {
$('#school-popup-modal').attr('style', 'display:none')
$('#select-buttons').attr('style', 'display:flex')
$('li').attr('style', 'display:flex')
$("#search-input").val("")
$("#undo").attr('style', 'display:none')
})
let dummyData = [{
name: 'gables',
id: 111
}, {
name: 'palmetto',
id: 222
}, {
name: 'southwest',
id: 333
}, {
name: 'killian',
id: 444
}]
dummyData.forEach((school) => {
let schoolName = school.name
$('.result-list').append(`
<ul><li id="list-item">${schoolName}</li><ul>
`)
})
$('li').click(function(e) {
let elem = e.target
$("#undo").attr('style', 'display:inline')
$("#search-input").val($(elem).text())
$('li').attr('style', 'display:none')
$('#school-popup-content').attr('style', 'padding-bottom:20px')
})
// $('#search-input').keyup(function(){
// let schoolsArr = []
// const searchString = $("#search-input").val().toLowerCase()
// dummyData.forEach((school)=>{
// schoolsArr.push(school.name)
// })
// for(let school of schoolsArr){
// if(school.includes(searchString)){
// results.innerHTML = `<ul><li>${school}</li></ul>`
// }
// else if(searchString === "") {
// console.log('empty')
// }
// }
// })
document.querySelector("#search-input").addEventListener("keyup", (e) => {
const searchString = e.target.value.toLowerCase()
const filteredSchools = dummyData.filter((school) => {
return school.name.toLowerCase().includes(searchString)
})
console.log(filteredSchools)
let filtered = filteredSchools.map((school) => {
return `
<ul>
<li>${school.name}</li>
</ul>
`
})
results.innerHTML = filtered
})
body {
margin: 0;
padding: 0;
font-family: 'itc-avant-garde-gothic-pro', sans-serif;
}
p {
font-size: 15px;
margin-right: 230px;
margin-top: 20px;
margin-bottom: 0px;
}
button {
text-align: center;
margin-bottom: 30px;
padding: 30px;
display: flex;
text-transform: uppercase;
letter-spacing: 4px;
padding: 16px 50px 14px;
border-radius: 2px;
min-width: 297px;
font-size: 14px;
text-align: center;
background: #000;
color: #fff;
line-height: normal;
border: 1px solid #000;
transition: all ease-in-out .3s;
-webkit-transition: all ease-in-out .3s;
-ms-transition: all ease-in-out .3s;
-o-transition: all ease-in-out .qs;
}
#popup-buttons {
margin-top: 70px;
margin-right: 30px;
display: flex;
padding-bottom: 5px;
}
#cancel-btn {
min-width: 217px;
font-size: 10px;
background-color: #ffffff;
color: #000000;
border: red;
}
a {
text-decoration: none;
color: #000000;
}
#cancel-btn: hover {
color: #000;
}
#popup-btn {
font-size: 10px;
min-width: 67px;
padding-top: 5px;
width: 180px;
}
#popup-btn a {
display: flex;
justify-content: space-between;
color: white;
}
button:hover {
color: #000;
background: transparent;
}
#school-popup-modal {
position: fixed;
z-index: 100000;
top: 0;
display: none;
justify-content: center;
background-color: rgba(0, 0, 0, 0.4);
width: 100vw;
height: 100vh;
}
#school-popup-content {
background-color: #ffffff;
border: 1px solid black;
border-radius: 16px;
display: flex;
flex-direction: column;
align-items: center;
max-width: 440px;
height: 400px;
padding: 14px;
width: 400px;
margin-top: 30px;
margin-bottom: 10px;
padding-bottom: 80px;
}
input {
width: 250px;
padding: 10px;
margin-top: 4px;
margin-left: 5px;
margin-bottom: 0px;
}
ul {
margin-left: 0px;
display: flex;
padding-left: 0px;
flex-direction: column;
justify-content: flex-start;
padding-right: 50px;
}
li {
display: flex;
justify-content: flex-start;
align-items: left;
margin-right: 20px;
font-size: 10px;
margin-top: 0px;
padding-top: 15px;
border-bottom: 1px solid #e8e8e8;
padding-right: 10px;
width: 253px;
padding-left: 10px;
padding-bottom: 10px;
}
li:hover {
background-color: #e8e8e8;
}
#search-results {
border: 1px solid #e1e1e1;
border-radius: 4px;
position: relative;
width: 272px;
margin-left: 5px;
}
input span {}
input[value=undo] {
color: grey;
text-align: right;
}
#undo {
position: absolute;
display: none;
top: 10;
color: grey;
font-size: 12px;
margin-top: 18px;
right: 25px;
}
.fas fa-check {
height: 5%;
}
#undo:hover {
color: black;
border-bottom: 1px solid black;
transition: .2s
}
#span-container {
position: relative;
overflow: hidden;
display: inline-block;
}
.popup-header {
font-family: 'itc-avant-garde-gothic-pro', sans-serif;
font-style: normal;
font-weight: bold;
font-size: 20px;
line-height: 28px;
align-items: left;
color: #000000;
margin-right: 120px;
}
#select-buttons {
display: flex;
flex-direction: column;
width: 5%;
}
#select-buttons button {}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="school-popup-modal">
<div id="school-popup-content">
<div class="popup-header">
<span>Find your School</span>
</div>
<p>School</p>
<form>
<div id="span-container">
<input autocomplete="off" id="search-input" placeholder='Start typing...' type="text">
<span id="undo">undo
<span style="font-size: 10px; color: green;">
<i class="fas fa-check"></i>
</span>
</span>
</div>
<div id="#search-results">
<div class="result-list">
</div>
</div>
</form>
<div id="popup-buttons">
<button id="cancel-btn">Cancel</button>
<button id="popup-btn">Start Testing</button>
</div>
</div>
</div>
<div id="select-buttons">
<button>Test for School</button>
<button>Test for work</button>
</div>
Your are putting an array in your HTML.
Try delete the line results.innerHTML = filtered from your JavaScript, and add:
// clear the results
results.innerHTML = '';
// insert the filtered results
filtered.forEach((filteredSchool) => {
results.innerHTML += filteredSchool;
});
Guys need some help im trying to figure out how can i execute multiple events on single click i am able to change the image on my gallery but i wanted to add some text label on each Img click i need to change each H3 and replace whenever i click the other image, i need to do a multiple event on single click
const current = document.querySelector('#current');
const imgs = document.querySelectorAll('.imgs img');
const main = document.querySelector('#main-info h3');
const info = document.querySelector('.info');
imgs.forEach(img => img.addEventListener('click', imgClick));
function imgClick(e) {
current.src = e.target.src;
}
body {
font-family: Arial, Helvetica, sans-serif;
font: 15px/1.5;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 90%;
margin: auto;
overflow: hidden;
}
header {
display: flex;
justify-content: space-between;
padding-top: 5px;
background-color: #567890;
min-height: 130px;
border-bottom: 3px #e0480c solid;
padding: 0 20px 0 0;
}
header #branding {
float: left;
margin: 0;
}
header #branding img {
margin: 0;
padding: 0;
}
header ul {
margin: 0;
padding: 0;
}
header li {
display: inline;
float: left;
padding: 0 20px 0 20px;
margin-top: 50px;
}
header a {
text-decoration: none;
color: #ffffff;
text-transform: uppercase;
font-size: 16px;
}
header a:hover {
color: #b9b8b9;
opacity: 1;
}
header nav {
float: right;
padding-bottom: 50px;
}
.current a {
color: #e0480c;
font-weight: bold;
}
#showcase {
min-height: 400px;
background: linear-gradient(rgba(0, 0, 50, 0.5), rgba(0, 0, 50, 0.5)),
url(/img/enseymada.jpg) no-repeat 0 -400px;
text-align: center;
background-size: cover;
opacity: 0.9;
}
#showcase .main-info {
margin-top: 100px;
margin-bottom: 10px;
justify-content: center;
font-size: 50px;
font-weight: 600;
color: #fffcff;
}
#showcase p {
font-size: 20px;
font-weight: 200;
color: #ccc;
}
.topinfo {
text-align: center;
justify-content: center;
}
.info2 {
text-align: center;
justify-content: center;
}
footer {
width: 100%;
bottom: 0;
position: relative;
}
.foot {
background: #e24305;
color: #fff;
height: 10px;
margin: 0;
width: 100%;
text-align: center;
padding: 7px 10px;
justify-content: center;
align-items: center;
}
.main-img img,
.imgs img {
margin: auto;
width: 100%;
background: cover;
border-radius: 10%;
}
.imgs {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 5px;
background: cover;
cursor: pointer;
}
.wrapper {
border: #444 solid 3px;
max-width: 800px;
margin: auto;
height: 100%;
padding: 5px;
align-items: center;
justify-content: center;
overflow: hidden;
}
.newsletter {
margin-bottom: 100px;
padding: 0;
width: 100%;
height: 80px;
align-items: center;
justify-content: center;
background-color: #567890;
}
.newsletter h1 {
float: left;
color: #ffffff;
}
.newsletter .btn {
display: inline;
margin: 20px 5px;
padding: 10px;
background-color: #444;
color: #fff;
border: none;
}
.newsletter #subscribe {
padding: 10px;
margin-left: 10px;
border: none;
}
<div class="wrapper">
<div class="main-img">
<h3 id="main-info">Classic Enseymada</h3>
<img src="img/image2.jpg" id="current">
</div>
<div class="imgs">
<img src="img/image2.jpg">
<div class="info">
<img src="img/image3.jpg">
<h3>Nuttela</h3>
</div>
<img src="img/image4.jpg">
<img src="img/image6.jpg">
<img src="img/image7.jpg">
<img src="img/image8.jpg">
</div>
</div>
<footer><div class="foot">Copyright © Abby Cook's 2020</div></footer>
<script src="./js/main.js"></script>
</body>
</html>
I am assuming that you want to pass more arguments to your imgClick function.
One way to do it is to use anonymous functions, something like this should do the trick :
imgs.forEach(img => img.addEventListener('click', function(e){
imgClick(e, 'param1', 'param2',);
}));
function imgClick(e, param1, param2,) {
current.src = e.target.src;
// your code
}
Add then your code in the function.
I have a problem in the layout of a horizontal stepper form that I made, basically when I press TAB on any of the steps, the focus ends up going to the next tab that should not be visible and bugs the form, the same happens when I press the down key that would be the equivalent and see the history in an input.
const $ = document.querySelector.bind(document),
$$ = document.querySelectorAll.bind(document)
const tabs = [ ...$$('.tab') ]
$('.total-steps').innerText = tabs.length
let currentTab = 0
showTab(currentTab)
function showTab(n) {
tabs[n].classList.remove('hidden')
tabs[n].classList.add('with-dalay')
/* const currentInput = dec => tabs[n - dec].querySelector('input:not([type=number])')
if (currentInput(0)) {
console.log(currentInput(0))
if (tabs[n - 1] && currentInput(1) && n >= 1) currentInput(1).blur()
currentInput(0).focus()
} */
if (n == 0) {
$('#prevBtn').disabled = true
$('#prevBtn').innerText = ''
}
else {
$('#prevBtn').disabled = false
$('#prevBtn').innerText = 'voltar'
}
if (n == tabs.length - 1) {
$('#nextBtn').innerText = 'concluir'
}
else {
$('#nextBtn').innerText = 'próximo'
}
}
function nextPrev(n, e) {
if (tabs.length - 1 !== n) e.preventDefault()
const currentStep = currentTab + n
if (currentStep <= tabs.length)
$('.current-step').innerText = currentStep + 1
if (n == 1 && validateForm()) return
tabs[currentTab].classList.add('hidden')
tabs[currentTab].classList.remove('with-dalay')
currentTab = currentStep
if (currentTab >= tabs.length) {
$('#regForm').submit()
return false
}
showTab(currentTab)
}
function validateForm() {
const inputs = [ ...tabs[currentTab].querySelectorAll('input') ]
let valid = false
inputs.forEach(input => {
input.classList.remove('invalid')
input.classList.add('valid')
if (!input.value) {
input.classList.add('invalid')
input.classList.remove('valid')
valid = true
}
})
return valid
}
$('#prevBtn').addEventListener('click', e => nextPrev(-1, e))
$('#nextBtn').addEventListener('click', e => nextPrev(1, e))
;[ ...$$('input') ].forEach(input => {
input.addEventListener('change', ({ target }) =>
target.classList.add('valid')
)
})
$('.add').addEventListener('click', () => {
const product = document.createRange().createContextualFragment($('.product').outerHTML)
// const product = new DOMParser().parseFromString($('.product').outerHTML, 'text/html').body.firstChild
$('.loading-wrapper').classList.remove('loading-hide')
$('#nextBtn').disabled = true
setTimeout(() => {
$('.loading-wrapper').classList.add('loading-hide')
$('.products-list').insertBefore(product, $('.products-list').childNodes[2])
$('#nextBtn').disabled = false
}, 3000)
})
function removeItem({ parentNode }) {
const willRemoved = confirm('Tem certeza que deseja remover este item?')
if (willRemoved) $('.products-list').removeChild(parentNode.parentNode)
}
const amount = $('.amount')
function removeAmount({ parentNode }) {
const input = parentNode.children[1]
if (input.value > 1) {
input.value = input.value - 1
}
}
function addAmount({ parentNode }) {
const input = parentNode.children[1]
input.value = parseInt(input.value) + 1
}
* {
box-sizing: border-box;
outline: 0;
}
button:hover,
button:active,
button:focus {
outline: 0;
}
h1 {
margin: 0;
padding: 40px 0 20px;
}
body {
font-family: 'Roboto', sans-serif;
background-color: #5b5b5b;
color: #323232;
margin: 0;
padding: 0;
}
.App {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
height: 100vh;
width: 100vw;
}
.App:before {
content: '';
background-image: url('https://www.jotform.com/uploads/anil/form_files/bryan-minear-315773.901.jpg');
filter: sepia(65%) brightness(.5);
width: 100vw;
height: 100vh;
overflow: hidden;
background-size: cover;
position: fixed;
background-repeat: no-repeat;
background-position: center center;
pointer-events: none;
z-index: 0;
}
#regForm {
width: 57%;
min-width: 250px;
border-radius: 6px;
overflow: hidden;
z-index: 1;
}
.tabs-wrapper {
display: flex;
position: relative;
overflow: hidden;
background-color: #fff;
}
h1 {
text-align: center;
background-color: #fff;
}
input {
padding: 10px;
width: 100%;
font-size: 17px;
background-color: transparent;
border: 1px solid #aaaaaa;
border-radius: 3px;
transition: border .2s linear;
z-index: 1;
}
input:focus,
input:active {
border-color: #4a85ef;
box-shadow: 0 0 0 2px rgba(72, 130, 239, .3);
}
input.valid {
border-color: #00af00;
box-shadow: 0 0 0 2px rgba(0, 175, 0, .3);
}
/* Mark input boxes that gets an error on validation: */
input.invalid {
border-color: #e34343;
box-shadow: 0 0 0 2px rgba(227, 68, 68, .3);
}
/* Hide all steps by default: */
.tab {
display: flex;
flex-direction: column;
padding: 40px 0;
background-color: #fff;
width: 100%;
transition: all 0.6s;
opacity: 1;
}
.tab > * {
padding: 0 40px;
}
.long-tab {
overflow-y: auto;
/* margin-bottom: 25px; */
max-height: 85vh;
}
.tab p {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.tab p input + input {
margin-left: 2%;
}
.hidden {
position: absolute;
transform: translateX(100%);
opacity: 0;
}
.with-dalay {
transition-delay: 0.5s;
}
.buttons-wrapper {
display: flex;
width: 100%;
background-color: #fff;
}
button {
background-color: #ffff00;
color: #000;
border: none;
padding: 15px 40px;
font-size: 1.2em;
font-weight: 400;
letter-spacing: 0.13em;
text-transform: uppercase;
width: 100%;
cursor: pointer;
transition: all .2s linear;
}
button:hover {
background-color: #d9d900;
color: white;
}
button:disabled {
background-color: #dfdf00;
}
#prevBtn {
text-align: left;
}
#nextBtn {
text-align: right;
}
.steps-wrapper {
text-align: center;
color: #d2d2d2;
z-index: 1;
font-size: 16px;
background-color: rgba(0, 0, 0, .35);
padding: 10px;
border-radius: 4px;
min-width: 130px;
letter-spacing: 1px;
}
.steps-wrapper span {
color: #fff;
opacity: 0.7;
}
.steps-wrapper span:first-child {
opacity: 1;
}
.question-wrapper {
margin: 10px 0 0;
}
.question-wrapper .question {
font-size: 15px;
}
.question-wrapper .required {
color: #e34343;
font-size: 1em;
}
.question-description {
font-size: 12px;
color: #7c7c7c;
}
.warning {
font-size: 10pt;
}
.warning p {
line-height: 1.5em;
}
.warning ol {
padding: 0 40px 0 53px;
}
.warning ol li {
text-align: justify;
line-height: 1.5em;
}
.warning ol li:first-child {
margin-bottom: 25px;
}
.warning ol li span {
text-decoration: underline;
}
.flex-container input.short-input {
width: 30%;
}
.add {
font-size: 26px;
width: 35px;
height: 35px;
text-align: center;
border: 1px solid gainsboro;
border-radius: 50px;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
margin-left: 10px;
cursor: pointer;
transition: all .2s ease;
}
.add:hover {
background-color: gainsboro;
}
.place-holder {
position: absolute;
font-size: 14px;
left: 52px;
color: #9f9f9f;
transition: all .5s ease;
top: 14px;
}
input[name=aLink]:focus + span.place-holder {
top: 50px;
font-size: 12px;
}
input[name="aLink"]:not(:placeholder-shown) + span.place-holder {
top: 50px;
font-size: 12px;
}
#cart {
padding: 1.5em 0;
}
div.cart-header {
display: flex;
padding-bottom: 10px;
border-bottom: 2px solid gainsboro;
flex-wrap: wrap;
}
.cart-header span:first-child {
flex: 1 300px;
}
.cart-header span:first-child span {
color: #16b451;
font-size: 1.1em;
}
.cart-header span:last-child {
font-size: small;
text-align: justify;
font-style: italic;
flex: 1 55%;
}
.products-list {
overflow-y: auto;
max-height: 45vh;
border-bottom: 1px solid gainsboro;
}
.product {
width: 100%;
overflow-y: hidden;
padding: 20px 0;
border-bottom: 1px solid #e6e9ed;
display: block;
transition: 0.3s;
}
.product:last-child {
border-bottom: none;
}
.product .product-header {
display: flex;
align-items: center;
justify-content: center;
}
.product .remove {
color: tomato;
cursor: pointer;
font-size: 26px;
margin-left: 10px;
transition: color .2s linear;
}
.product .remove:hover {
color: #ce2000;
}
.products-list .description {
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
font-size: 13px;
}
.products-list img {
width: 100px;
}
.products-list .description > div:last-child {
display: flex;
flex-direction: column;
}
.description > div:nth-child(2) {
display: flex;
flex-direction: column;
}
.description .remove:hover {
color: tomato;
}
.products-list .description .dolar-price {
font-weight: bold;
}
.products-list .description .from-amazon {
color: gray;
text-decoration: line-through;
}
.products-list .description .from-glin {
color: #16b451;
font-size: 1.2em;
font-weight: bold;
}
.products-list .description .economy {
color: #16b451;
}
.products-list .description .shippment {
margin-top: 15px;
}
.products-list .description .amount-wrapper {
display: flex;
align-items: center;
margin: 5px 0;
}
.products-list .description .amount-controls {
display: flex;
flex-direction: row;
justify-content: center;
margin-left: 10px;
align-items: center;
border: 1px solid #ccc;
}
.products-list .description .controls {
padding: 0 10px;
cursor: pointer;
}
.products-list .description .amount {
width: 45px;
font-size: 13px;
-moz-appearance: textfield;
border-radius: 0;
text-align: center;
border: none;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 5px 10px;
}
.products-list .description .arrives {
font-weight: bold;
}
.loading {
margin: 30px auto 0;
border: 5px solid #d9d9d9;
border-radius: 50%;
border-top: 5px solid yellow;
width: 100px;
height: 100px;
animation: spin 2s linear infinite;
}
.loading-wrapper p {
color: #959595;
}
.loading-hide {
display: none;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#media (max-width: 575.98px) {
.tab > * {
padding: 0 20px;
}
.place-holder {
top: 10px;
left: 32px;
}
input[name=aLink]:focus + span.place-holder {
top: 45px;
}
input[name=aLink]:not(:placeholder-shown) + span.place-holder {
top: 45px;
}
button {
font-size: 14px;
}
.flex-container input {
font-size: 12px;
}
}
#media (max-width: 855px) {
#regForm {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 100%;
border-radius: 0;
background-color: #fff;
}
.products-list {
max-height: 75vh;
height: 55vh;
}
.steps-wrapper {
width: 100%;
margin-top: 0;
background-color: #5b5b5b;
}
}
#media (max-width: 487px) {
input {
font-size: 12px;
}
}
#media (max-width: 414px) {
#regForm {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 100%;
border-radius: 0;
background-color: #fff;
}
.tab p:not(.flex-container) {
flex-wrap: wrap;
}
.tab p:not(.flex-container) input[name=email] {
margin: 10px 0;
}
.loading-wrapper p {
font-size: 15px
}
.steps-wrapper {
width: 100%;
margin-top: 0;
background-color: #5b5b5b;
}
}
<div class="App">
<form id="regForm">
<div class="tabs-wrapper">
<div class="tab">
<label class="question-wrapper">
<span class="question">Como você gostaria de ser chamado(a)?</span>
<span class="required"> *</span>
</label>
<span class="question-description">Assim fica mais legal conversarmos :)</span>
<p><input placeholder="Seu nome" name="fname"></p>
</div>
<div class="tab hidden with-dalay">
<label class="question-wrapper">
<span class="question">Legal, {fulano}. E qual o seu e-mail para contato?</span>
<span class="required"> *</span>
</label>
<span class="question-description">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Natus, officia.</span>
<p>
<input placeholder="e-mail" name="email">
<input placeholder="confirmar e-mail" name="email">
</p>
</div>
<div class="tab hidden with-dalay">
<label class="question-wrapper">
<span class="question">Lorem ipsum dolor sit amet.</span>
</label><span class="question-description">
Lorem ipsum dolor sit.
</span>
<p><input placeholder="lorem ipsum" name="cupomCode"></p>
</div>
</div>
<div class="buttons-wrapper">
<button type="button" class="btn" id="prevBtn">voltar</button>
<button type="submit" class="btn" id="nextBtn">próximo</button>
</div>
</form>
</div>
You could add keydown event listener for document and use event.preventDefault() to stop tab event and focus on desired element:
document.addEventListener("keydown", (event) => {
console.log($(":focus"), event.which);
if (event.target.name == "fname" && event.keyCode == 9) {
event.preventDefault();
$("#nextBtn").focus();
}
});
const $ = document.querySelector.bind(document),
$$ = document.querySelectorAll.bind(document);
const tabs = [...$$('.tab')];
//$('.total-steps').innerText = tabs.length;
let currentTab = 0;
document.addEventListener("keydown", (event) => {
console.log($(":focus"), event.which);
if (event.target.name == "fname" && event.keyCode == 9) {
event.preventDefault();
$("#nextBtn").focus();
}
});
showTab(currentTab);
function showTab(n) {
tabs[n].classList.remove('hidden')
tabs[n].classList.add('with-dalay')
/* const currentInput = dec => tabs[n - dec].querySelector('input:not([type=number])')
if (currentInput(0)) {
console.log(currentInput(0))
if (tabs[n - 1] && currentInput(1) && n >= 1) currentInput(1).blur()
currentInput(0).focus()
} */
if (n == 0) {
$('#prevBtn').disabled = true
$('#prevBtn').innerText = ''
} else {
$('#prevBtn').disabled = false
$('#prevBtn').innerText = 'voltar'
}
if (n == tabs.length - 1) {
$('#nextBtn').innerText = 'concluir'
} else {
$('#nextBtn').innerText = 'próximo'
}
}
function nextPrev(n, e) {
if (tabs.length - 1 !== n) e.preventDefault()
const currentStep = currentTab + n
if (currentStep <= tabs.length)
$('.current-step').innerText = currentStep + 1
if (n == 1 && validateForm()) return
tabs[currentTab].classList.add('hidden')
tabs[currentTab].classList.remove('with-dalay')
currentTab = currentStep
if (currentTab >= tabs.length) {
$('#regForm').submit()
return false
}
showTab(currentTab)
}
function validateForm() {
const inputs = [...tabs[currentTab].querySelectorAll('input')]
let valid = false
inputs.forEach(input => {
input.classList.remove('invalid')
input.classList.add('valid')
if (!input.value) {
input.classList.add('invalid')
input.classList.remove('valid')
valid = true
}
})
return valid
}
$('#prevBtn').addEventListener('click', e => nextPrev(-1, e))
$('#nextBtn').addEventListener('click', e => nextPrev(1, e));
[...$$('input')].forEach(input => {
input.addEventListener('change', ({
target
}) =>
target.classList.add('valid')
)
})
/*$('.add').addEventListener('click', () => {
const product = document.createRange().createContextualFragment($('.product').outerHTML)
// const product = new DOMParser().parseFromString($('.product').outerHTML, 'text/html').body.firstChild
$('.loading-wrapper').classList.remove('loading-hide')
$('#nextBtn').disabled = true
setTimeout(() => {
$('.loading-wrapper').classList.add('loading-hide')
$('.products-list').insertBefore(product, $('.products-list').childNodes[2])
$('#nextBtn').disabled = false
}, 3000)
});*/
function removeItem({
parentNode
}) {
const willRemoved = confirm('Tem certeza que deseja remover este item?')
if (willRemoved) $('.products-list').removeChild(parentNode.parentNode)
}
const amount = $('.amount')
function removeAmount({
parentNode
}) {
const input = parentNode.children[1]
if (input.value > 1) {
input.value = input.value - 1
}
}
function addAmount({
parentNode
}) {
const input = parentNode.children[1]
input.value = parseInt(input.value) + 1
}
* {
box-sizing: border-box;
outline: 0;
}
button:hover,
button:active,
button:focus {
outline: 0;
}
h1 {
margin: 0;
padding: 40px 0 20px;
}
body {
font-family: 'Roboto', sans-serif;
background-color: #5b5b5b;
color: #323232;
margin: 0;
padding: 0;
}
.App {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
height: 100vh;
width: 100vw;
}
.App:before {
content: '';
background-image: url('https://www.jotform.com/uploads/anil/form_files/bryan-minear-315773.901.jpg');
filter: sepia(65%) brightness(.5);
width: 100vw;
height: 100vh;
overflow: hidden;
background-size: cover;
position: fixed;
background-repeat: no-repeat;
background-position: center center;
pointer-events: none;
z-index: 0;
}
#regForm {
width: 57%;
min-width: 250px;
border-radius: 6px;
overflow: hidden;
z-index: 1;
}
.tabs-wrapper {
display: flex;
position: relative;
overflow: hidden;
background-color: #fff;
}
h1 {
text-align: center;
background-color: #fff;
}
input {
padding: 10px;
width: 100%;
font-size: 17px;
background-color: transparent;
border: 1px solid #aaaaaa;
border-radius: 3px;
transition: border .2s linear;
z-index: 1;
}
input:focus,
input:active {
border-color: #4a85ef;
box-shadow: 0 0 0 2px rgba(72, 130, 239, .3);
}
input.valid {
border-color: #00af00;
box-shadow: 0 0 0 2px rgba(0, 175, 0, .3);
}
/* Mark input boxes that gets an error on validation: */
input.invalid {
border-color: #e34343;
box-shadow: 0 0 0 2px rgba(227, 68, 68, .3);
}
/* Hide all steps by default: */
.tab {
display: flex;
flex-direction: column;
padding: 40px 0;
background-color: #fff;
width: 100%;
transition: all 0.6s;
opacity: 1;
}
.tab>* {
padding: 0 40px;
}
.long-tab {
overflow-y: auto;
/* margin-bottom: 25px; */
max-height: 85vh;
}
.tab p {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.tab p input+input {
margin-left: 2%;
}
.hidden {
position: absolute;
transform: translateX(100%);
opacity: 0;
}
.with-dalay {
transition-delay: 0.5s;
}
.buttons-wrapper {
display: flex;
width: 100%;
background-color: #fff;
}
button {
background-color: #ffff00;
color: #000;
border: none;
padding: 15px 40px;
font-size: 1.2em;
font-weight: 400;
letter-spacing: 0.13em;
text-transform: uppercase;
width: 100%;
cursor: pointer;
transition: all .2s linear;
}
button:hover {
background-color: #d9d900;
color: white;
}
button:disabled {
background-color: #dfdf00;
}
#prevBtn {
text-align: left;
}
#nextBtn {
text-align: right;
}
.steps-wrapper {
text-align: center;
color: #d2d2d2;
z-index: 1;
font-size: 16px;
background-color: rgba(0, 0, 0, .35);
padding: 10px;
border-radius: 4px;
min-width: 130px;
letter-spacing: 1px;
}
.steps-wrapper span {
color: #fff;
opacity: 0.7;
}
.steps-wrapper span:first-child {
opacity: 1;
}
.question-wrapper {
margin: 10px 0 0;
}
.question-wrapper .question {
font-size: 15px;
}
.question-wrapper .required {
color: #e34343;
font-size: 1em;
}
.question-description {
font-size: 12px;
color: #7c7c7c;
}
.warning {
font-size: 10pt;
}
.warning p {
line-height: 1.5em;
}
.warning ol {
padding: 0 40px 0 53px;
}
.warning ol li {
text-align: justify;
line-height: 1.5em;
}
.warning ol li:first-child {
margin-bottom: 25px;
}
.warning ol li span {
text-decoration: underline;
}
.flex-container input.short-input {
width: 30%;
}
.add {
font-size: 26px;
width: 35px;
height: 35px;
text-align: center;
border: 1px solid gainsboro;
border-radius: 50px;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
margin-left: 10px;
cursor: pointer;
transition: all .2s ease;
}
.add:hover {
background-color: gainsboro;
}
.place-holder {
position: absolute;
font-size: 14px;
left: 52px;
color: #9f9f9f;
transition: all .5s ease;
top: 14px;
}
input[name=aLink]:focus+span.place-holder {
top: 50px;
font-size: 12px;
}
input[name="aLink"]:not(:placeholder-shown)+span.place-holder {
top: 50px;
font-size: 12px;
}
#cart {
padding: 1.5em 0;
}
div.cart-header {
display: flex;
padding-bottom: 10px;
border-bottom: 2px solid gainsboro;
flex-wrap: wrap;
}
.cart-header span:first-child {
flex: 1 300px;
}
.cart-header span:first-child span {
color: #16b451;
font-size: 1.1em;
}
.cart-header span:last-child {
font-size: small;
text-align: justify;
font-style: italic;
flex: 1 55%;
}
.products-list {
overflow-y: auto;
max-height: 45vh;
border-bottom: 1px solid gainsboro;
}
.product {
width: 100%;
overflow-y: hidden;
padding: 20px 0;
border-bottom: 1px solid #e6e9ed;
display: block;
transition: 0.3s;
}
.product:last-child {
border-bottom: none;
}
.product .product-header {
display: flex;
align-items: center;
justify-content: center;
}
.product .remove {
color: tomato;
cursor: pointer;
font-size: 26px;
margin-left: 10px;
transition: color .2s linear;
}
.product .remove:hover {
color: #ce2000;
}
.products-list .description {
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
font-size: 13px;
}
.products-list img {
width: 100px;
}
.products-list .description>div:last-child {
display: flex;
flex-direction: column;
}
.description>div:nth-child(2) {
display: flex;
flex-direction: column;
}
.description .remove:hover {
color: tomato;
}
.products-list .description .dolar-price {
font-weight: bold;
}
.products-list .description .from-amazon {
color: gray;
text-decoration: line-through;
}
.products-list .description .from-glin {
color: #16b451;
font-size: 1.2em;
font-weight: bold;
}
.products-list .description .economy {
color: #16b451;
}
.products-list .description .shippment {
margin-top: 15px;
}
.products-list .description .amount-wrapper {
display: flex;
align-items: center;
margin: 5px 0;
}
.products-list .description .amount-controls {
display: flex;
flex-direction: row;
justify-content: center;
margin-left: 10px;
align-items: center;
border: 1px solid #ccc;
}
.products-list .description .controls {
padding: 0 10px;
cursor: pointer;
}
.products-list .description .amount {
width: 45px;
font-size: 13px;
-moz-appearance: textfield;
border-radius: 0;
text-align: center;
border: none;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 5px 10px;
}
.products-list .description .arrives {
font-weight: bold;
}
.loading {
margin: 30px auto 0;
border: 5px solid #d9d9d9;
border-radius: 50%;
border-top: 5px solid yellow;
width: 100px;
height: 100px;
animation: spin 2s linear infinite;
}
.loading-wrapper p {
color: #959595;
}
.loading-hide {
display: none;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#media (max-width: 575.98px) {
.tab>* {
padding: 0 20px;
}
.place-holder {
top: 10px;
left: 32px;
}
input[name=aLink]:focus+span.place-holder {
top: 45px;
}
input[name=aLink]:not(:placeholder-shown)+span.place-holder {
top: 45px;
}
button {
font-size: 14px;
}
.flex-container input {
font-size: 12px;
}
}
#media (max-width: 855px) {
#regForm {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 100%;
border-radius: 0;
background-color: #fff;
}
.products-list {
max-height: 75vh;
height: 55vh;
}
.steps-wrapper {
width: 100%;
margin-top: 0;
background-color: #5b5b5b;
}
}
#media (max-width: 487px) {
input {
font-size: 12px;
}
}
#media (max-width: 414px) {
#regForm {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 100%;
border-radius: 0;
background-color: #fff;
}
.tab p:not(.flex-container) {
flex-wrap: wrap;
}
.tab p:not(.flex-container) input[name=email] {
margin: 10px 0;
}
.loading-wrapper p {
font-size: 15px
}
.steps-wrapper {
width: 100%;
margin-top: 0;
background-color: #5b5b5b;
}
}
<div class="App">
<form id="regForm">
<div class="tabs-wrapper">
<div class="tab">
<label class="question-wrapper">
<span class="question">Como você gostaria de ser chamado(a)?</span>
<span class="required"> *</span>
</label>
<span class="question-description">Assim fica mais legal conversarmos :)</span>
<p><input placeholder="Seu nome" name="fname"></p>
</div>
<div class="tab hidden with-dalay">
<label class="question-wrapper">
<span class="question">Legal, {fulano}. E qual o seu e-mail para contato?</span>
<span class="required"> *</span>
</label>
<span class="question-description">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Natus, officia.</span>
<p>
<input placeholder="e-mail" name="email">
<input placeholder="confirmar e-mail" name="email">
</p>
</div>
<div class="tab hidden with-dalay">
<label class="question-wrapper">
<span class="question">Lorem ipsum dolor sit amet.</span>
</label><span class="question-description">
Lorem ipsum dolor sit.
</span>
<p><input placeholder="lorem ipsum" name="cupomCode"></p>
</div>
</div>
<div class="buttons-wrapper">
<button type="button" class="btn" id="prevBtn">voltar</button>
<button type="submit" class="btn" id="nextBtn">próximo</button>
</div>
</form>
</div>