How to assign diffrent popup with same function with javascript? - javascript

so I have this program I am trying to type and I found different ways to write the code but the same popup screen comes how do I call the same function but show different headers when clicked? I have tried to use the same function with different classes called but IDK why everything disappears but I haven't coded javascript very much and still new to me. Please help me the way I am trying to am at is when Wedding button is clicked I want to show "you clicked wedding button" when the birthday is clicked "birthday button"..etc, problem is that the wedding functions is only showing how do I fix it?
/*wedding popup to fill */
const modal = document.querySelector(".modal");
const wedding_POPUP = document.querySelector(".wedding_POPUP");
const closeButton = document.querySelector(".close-button");
function toggleModal() {
modal.classList.toggle("show-modal");
}
function windowOnClick(event) {
if (event.target === modal) {
toggleModal();
}
}
wedding_POPUP.addEventListener("click", toggleModal);
closeButton.addEventListener("click", toggleModal);
window.addEventListener("click", windowOnClick);
/* Popup screen for each modal when pressed
buttons when pressed background changes
setup for when clicked*/
.modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
visibility: hidden;
transform: scale(1.1);
transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
}
/*center of page with padding and borders*/
.modal-content {
position: absolute;
top: 359px;
left: 624px;
transform: translate(-50%, -50%);
background-color: white;
padding: 1rem 1.5rem;
width: 34%;
border-radius: 0.5rem;
height: 122%;
}
/*close button layout with hover background*/
.close-button {
float: right;
width: 1.5rem;
line-height: 1.5rem;
text-align: center;
cursor: pointer;
border-radius: 0.25rem;
background-color: lightgray;
}
.close-button:hover {
background-color: darkgray;
}
/*style of modal when its open */
.show-modal {
opacity: 1;
visibility: visible;
transform: scale(1.0);
transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
<div id="occasion">
<button id="occassion_layout" class="wedding_POPUP">Wedding</button>
<button id="occassion_layout" class="Birthday_POPUP">Birthday</button>
<button id="occassion_layout" class="Party_POPUP">Holiday</button>
</div>
<div id="Wed_fill">
<span class="close">×</span>
<!--when the wedding button is pusehed what it will show show div boderline-->
<div class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<p>Wedding button clicked</p>
</div>
</div>
</div>
<div class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<!--form for birthday-->
<div class="Birth_fill">
<div class="Birthday_form">
<p>HAPPY BIRTHDAY button clicked</p>
</div>
</div>
</div>
</div>
<div class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<!--form for birthday-->
<div class="party_filled">
<div class="party_form">
<p>Party button clicked</p>
</div>
</div>
</div>
</div>

Add an attribute to the button that relates it to the corresponding modal, so you can toggle that modal.
/*wedding popup to fill */
const modal = document.querySelector(".modal");
const wedding_POPUP = document.querySelector(".wedding_POPUP");
const closeButton = document.querySelector(".close-button");
function closeModal() {
document.querySelectorAll(".modal").forEach(el => el.classList.remove("show-modal"));
}
function toggleModal(e) {
let modal = document.getElementById(e.target.dataset.rel);
if (modal) {
document.querySelectorAll(".modal").forEach(el => {
if (el == modal) {
el.classList.toggle("show-modal");
} else {
el.classList.remove("show-modal");
}
});
}
}
function windowOnClick(event) {
if (event.target === modal) {
toggleModal(event);
}
}
wedding_POPUP.addEventListener("click", toggleModal);
closeButton.addEventListener("click", closeModal);
window.addEventListener("click", windowOnClick);
/* Popup screen for each modal when pressed
buttons when pressed background changes
setup for when clicked*/
.modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
visibility: hidden;
transform: scale(1.1);
transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
}
/*center of page with padding and borders*/
.modal-content {
position: absolute;
top: 359px;
left: 624px;
transform: translate(-50%, -50%);
background-color: white;
padding: 1rem 1.5rem;
width: 34%;
border-radius: 0.5rem;
height: 122%;
}
/*close button layout with hover background*/
.close-button {
float: right;
width: 1.5rem;
line-height: 1.5rem;
text-align: center;
cursor: pointer;
border-radius: 0.25rem;
background-color: lightgray;
}
.close-button:hover {
background-color: darkgray;
}
/*style of modal when its open */
.show-modal {
opacity: 1;
visibility: visible;
transform: scale(1.0);
transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
<div id="occasion">
<button id="occassion_layout" class="wedding_POPUP" data-rel="wedding_modal">Wedding</button>
<button id="occassion_layout" class="Birthday_POPUP" data-rel="birthday_modal">Birthday</button>
<button id="occassion_layout" class="Party_POPUP" data-rel="holiday_modal">Holiday</button>
</div>
<div id="Wed_fill">
<span class="close">×</span>
<!--when the wedding button is pusehed what it will show show div boderline-->
<div id="wedding_modal" class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<p>Wedding button clicked</p>
</div>
</div>
</div>
<div id="birthday_modal" class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<!--form for birthday-->
<div class="Birth_fill">
<div class="Birthday_form">
<p>HAPPY BIRTHDAY button clicked</p>
</div>
</div>
</div>
</div>
<div id="party_modal" class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<!--form for birthday-->
<div class="party_filled">
<div class="party_form">
<p>Party button clicked</p>
</div>
</div>
</div>
</div>
This code isn't fully working, but I have to leave now.

I took liberty to format a bit using flex.
I suggest a "toggle" for display using data attribute so you only have to "change" it not add/remove it - and you can use that in the CSS (I used "show" and "hide" values.
To open a modal, I used a "target" data as a class and selected by that - it could be a number of values/combinations.
I set up a "close" event for the X and then triggered them all to close when a button was clicked so if one is already open we only have one at a time open.
I did away with all the "position" css and used flex instead of px this way and that etc. which is hard to maintain from my experience.
Something you can build upon I think.
const modals = document.querySelectorAll(".modal");
const actionButtons = document.querySelectorAll(".modal-activator");
const closeButtons = document.querySelectorAll(".close-button");
/* not used but could trigger the closeEvent etc. */
function windowOnClick(event) {
if (event.target === modal) {
toggleModal();
}
}
// create close event
const closeEvent = new Event('close-modal');
// Listen for the event.
closeButtons.forEach(btn => btn.addEventListener('close-modal', function(event) {
let myModal = event.target.closest(".modal");
myModal.dataset.showToggle = "hide";
}, false));
actionButtons.forEach(btn => btn.addEventListener('click', event => {
// console.log(event.target.getAttribute("data-target-modal"));
const dataAttrMap = event.target.dataset;
const modalSelector = ".modal." + dataAttrMap.targetModal;
// console.log(modalSelector);
closeAllModals(closeButtons);
const modalTarget = document.querySelector(modalSelector);
modalTarget.dataset.showToggle = "show";
}));
closeButtons.forEach(btn => btn.addEventListener('click', function(event) {
let myModal = event.target.closest(".modal");
myModal.dataset.showToggle = "hide";
}, false));
function closeAllModals(buttons) {
buttons.forEach(btn => btn.dispatchEvent(closeEvent));
}
.contaner {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: start;
}
.occasion.contaner {
flex-direction: row;
column-gap: 0.5em;
align-self: flex-start;
margin-bottom: 1rem;
}
.modal {
display: flex;
align-items: flex-start;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
}
.modal-content {
border-radius: 0.5rem;
background-color: white;
padding: 1rem 1.5rem;
margin-top: 1rem;
margin-left: 0.5rem;
margin-bottom: 1rem;
}
.close-button {
align-self: flex-start;
margin-left: auto;
width: 1.5rem;
line-height: 1.5rem;
cursor: pointer;
text-align: center;
border-radius: 0.25rem;
background-color: lightgray;
}
.close-button:hover {
background-color: darkgray;
}
/* not used
.show-modal {
opacity: 1;
visibility: visible;
transform: scale(1.0);
transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
*/
.modal[data-show-toggle="show"] {
opacity: 1;
display: flex;
transform: scale(1.0);
transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
.modal[data-show-toggle="hide"] {
display: none;
}
[data-target-modal]{padding: 0.5rem;border-radius: 0.5rem;}
[data-target-modal="wedding"]{background-color:pink;border-color:#ff8888;}
[data-target-modal="holiday"]{background-color:#AAAAFF;}
<div class="page container">
<div id="occasion" class="occasion contaner">
<button class="wedding_POPUP modal-activator" data-target-modal="wedding" type="button">Wedding</button>
<button class="Birthday_POPUP modal-activator" data-target-modal="birthday" type="button">Birthday</button>
<button class="Party_POPUP modal-activator" data-target-modal="holiday" type="button">Holiday</button>
</div>
<div class="container">
<div class="modal wedding" data-show-toggle="hide">
<div class="modal-content">
<p>Wedding button clicked</p>
</div>
<span class="close-button">×</span>
</div>
<div class="modal birthday" data-show-toggle="hide">
<div class="modal-content">
<div class="Birth_fill">
<div class="Birthday_form">
<p>HAPPY BIRTHDAY button clicked</p>
</div>
</div>
</div>
<span class="close-button">×</span>
</div>
<div class="modal holiday" data-show-toggle="hide">
<div class="modal-content">
<div class="party_filled">
<div class="party_form">
<p>Party button clicked</p>
</div>
</div>
</div>
<span class="close-button">×</span>
</div>
</div>
</div>

Related

Dynamically added form elements hides other elements until resize

I have a form with a button that when clicked adds a new input to the form.
While the input is added, the form does not expand so that any contend below the added form is no longer visible, however the form resizes and all content is viewable if a user resizes their window.
See below
Is this a CSS issue? If so what elements could it possibly be?
The HTML
<div id="single-form-next-prev" class="multisteps-form__panel shadow p-4 rounded bg-white" data-animation="scaleIn">
<h3 class="text-center multisteps-form__title">Skills</h3>
<div id="form-content-1" class="multisteps-form__content">
<div id="input-grp-single-1" class="form-row mt-4">
<div class="col-12"><input class="form-control multisteps-form__input" type="text" placeholder="Skill 1"></div>
</div>
<br>
<button id='addButton' class="btn btn-outline-primary text-truncate float-none float-sm-none add-another-btn" data-bss-hover-animate="pulse" type="button">Add Skill<i class="fas fa-plus-circle edit-icon"></i></button>
<div id="next-prev-buttons" class="button-row d-flex mt-4"><button class="btn btn btn-primary js-btn-prev" type="button" title="Prev">Prev</button><button class="btn btn btn-primary ml-auto js-btn-next" type="button" title="Next">Find Results</button></div>
</div>
</div>
The JQUERY
$(document).ready(function(){
let id = 1;
$('#addButton').click(function() {
$('#input-grp-single-'+id).after('<div id="input-grp-single-'+(id+1)+'" class="form-row mt-4"> <div class="col-12"><input class="form-control multisteps-form__input" type="text" placeholder="Skill '+(id+1)+'"></div></div>');
id++;
});
});
The CSS
.multisteps-form__form {
position: relative;
}
.multisteps-form__panel {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 0;
opacity: 0;
visibility: hidden;
}
.multisteps-form__panel.js-active {
height: auto;
opacity: 1;
visibility: visible;
}
.multisteps-form__panel[data-animation="scaleIn"] {
-webkit-transform: scale(0.9);
transform: scale(0.9);
}
.multisteps-form__panel[data-animation="scaleIn"].js-active {
transition-property: all;
transition-duration: 0.2s;
transition-timing-function: linear;
transition-delay: 0s;
-webkit-transform: scale(1);
transform: scale(1);
}
Codepen link added
https://codepen.io/jdog6652/pen/ExZJvaQ
Remove the overflow-hidden class on your #multple-step-form-n element:
$(document).ready(function() {
let id = 1;
$('[data-bss-hover-animate]')
.mouseenter(function() {
var elem = $(this);
elem.addClass('animated ' + elem.attr('data-bss-hover-animate'))
})
.mouseleave(function() {
var elem = $(this);
elem.removeClass('animated ' + elem.attr('data-bss-hover-animate'))
});
$('#addButton').click(function() {
$('#input-grp-single-' + id).after('<div id="input-grp-single-' + (id + 1) + '" class="form-row mt-4"> <div class="col-12"><input class="form-control multisteps-form__input" type="text" placeholder="Skill ' + (id + 1) + '"></div></div>');
id++;
});
});
//DOM elements
const DOMstrings = {
stepsBtnClass: 'multisteps-form__progress-btn',
stepsBtns: document.querySelectorAll(`.multisteps-form__progress-btn`),
stepsBar: document.querySelector('.multisteps-form__progress'),
stepsForm: document.querySelector('.multisteps-form__form'),
stepsFormTextareas: document.querySelectorAll('.multisteps-form__textarea'),
stepFormPanelClass: 'multisteps-form__panel',
stepFormPanels: document.querySelectorAll('.multisteps-form__panel'),
stepPrevBtnClass: 'js-btn-prev',
stepNextBtnClass: 'js-btn-next'
};
//remove class from a set of items
const removeClasses = (elemSet, className) => {
elemSet.forEach(elem => {
elem.classList.remove(className);
});
};
//return exect parent node of the element
const findParent = (elem, parentClass) => {
let currentNode = elem;
while (!currentNode.classList.contains(parentClass)) {
currentNode = currentNode.parentNode;
}
return currentNode;
};
//get active button step number
const getActiveStep = elem => {
return Array.from(DOMstrings.stepsBtns).indexOf(elem);
};
//set all steps before clicked (and clicked too) to active
const setActiveStep = activeStepNum => {
//remove active state from all the state
removeClasses(DOMstrings.stepsBtns, 'js-active');
//set picked items to active
DOMstrings.stepsBtns.forEach((elem, index) => {
if (index <= activeStepNum) {
elem.classList.add('js-active');
}
});
};
//get active panel
const getActivePanel = () => {
let activePanel;
DOMstrings.stepFormPanels.forEach(elem => {
if (elem.classList.contains('js-active')) {
activePanel = elem;
}
});
return activePanel;
};
//open active panel (and close unactive panels)
const setActivePanel = activePanelNum => {
//remove active class from all the panels
removeClasses(DOMstrings.stepFormPanels, 'js-active');
//show active panel
DOMstrings.stepFormPanels.forEach((elem, index) => {
if (index === activePanelNum) {
elem.classList.add('js-active');
setFormHeight(elem);
}
});
};
//set form height equal to current panel height
const formHeight = activePanel => {
const activePanelHeight = activePanel.offsetHeight;
DOMstrings.stepsForm.style.height = `${activePanelHeight}px`;
};
const setFormHeight = () => {
const activePanel = getActivePanel();
formHeight(activePanel);
};
//STEPS BAR CLICK FUNCTION
DOMstrings.stepsBar.addEventListener('click', e => {
//check if click target is a step button
const eventTarget = e.target;
if (!eventTarget.classList.contains(`${DOMstrings.stepsBtnClass}`)) {
return;
}
//get active button step number
const activeStep = getActiveStep(eventTarget);
//set all steps before clicked (and clicked too) to active
setActiveStep(activeStep);
//open active panel
setActivePanel(activeStep);
});
//PREV/NEXT BTNS CLICK
DOMstrings.stepsForm.addEventListener('click', e => {
const eventTarget = e.target;
//check if we clicked on `PREV` or NEXT` buttons
if (!(eventTarget.classList.contains(`${DOMstrings.stepPrevBtnClass}`) || eventTarget.classList.contains(`${DOMstrings.stepNextBtnClass}`))) {
return;
}
//find active panel
const activePanel = findParent(eventTarget, `${DOMstrings.stepFormPanelClass}`);
let activePanelNum = Array.from(DOMstrings.stepFormPanels).indexOf(activePanel);
//set active step and active panel onclick
if (eventTarget.classList.contains(`${DOMstrings.stepPrevBtnClass}`)) {
activePanelNum--;
} else {
activePanelNum++;
}
setActiveStep(activePanelNum);
setActivePanel(activePanelNum);
});
//SETTING PROPER FORM HEIGHT ONLOAD
window.addEventListener('load', setFormHeight, false);
//SETTING PROPER FORM HEIGHT ONRESIZE
window.addEventListener('resize', setFormHeight, false);
//changing animation via animation select !!!YOU DON'T NEED THIS CODE (if you want to change animation type, just change form panels data-attr)
const setAnimationType = newType => {
DOMstrings.stepFormPanels.forEach(elem => {
elem.dataset.animation = newType;
});
};
//selector onchange - changing animation
const animationSelect = document.querySelector('.pick-animation__select');
/*
====NOTICE====
The block of code below was giving an error not related to the question, so it was commented out
animationSelect.addEventListener('change', () => {
const newAnimationType = animationSelect.value;
setAnimationType(newAnimationType);
});
*/
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body a {
color: inherit;
text-decoration: none;
}
.multisteps-form__progress {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.multisteps-form__progress-btn {
transition-property: all;
transition-duration: 0.15s;
transition-timing-function: linear;
transition-delay: 0s;
position: relative;
padding-top: 20px;
color: rgba(108, 117, 125, 0.7);
text-indent: -9999px;
border: none;
background-color: transparent;
outline: none !important;
cursor: pointer;
}
#media (min-width: 500px) {
.multisteps-form__progress-btn {
text-indent: 0;
}
}
.multisteps-form__progress-btn:before {
position: absolute;
top: 0;
left: 50%;
display: block;
width: 13px;
height: 13px;
content: '';
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
transition: all 0.15s linear 0s, -webkit-transform 0.15s cubic-bezier(0.05, 1.09, 0.16, 1.4) 0s;
transition: all 0.15s linear 0s, transform 0.15s cubic-bezier(0.05, 1.09, 0.16, 1.4) 0s;
transition: all 0.15s linear 0s, transform 0.15s cubic-bezier(0.05, 1.09, 0.16, 1.4) 0s, -webkit-transform 0.15s cubic-bezier(0.05, 1.09, 0.16, 1.4) 0s;
border: 2px solid currentColor;
border-radius: 50%;
background-color: #fff;
box-sizing: border-box;
z-index: 3;
}
.multisteps-form__progress-btn:after {
position: absolute;
top: 5px;
left: calc(-50% - 13px / 2);
transition-property: all;
transition-duration: 0.15s;
transition-timing-function: linear;
transition-delay: 0s;
display: block;
width: 100%;
height: 2px;
content: '';
background-color: currentColor;
z-index: 1;
}
.multisteps-form__progress-btn:first-child:after {
display: none;
}
.multisteps-form__progress-btn.js-active {
color: #007bff;
}
.multisteps-form__progress-btn.js-active:before {
-webkit-transform: translateX(-50%) scale(1.2);
transform: translateX(-50%) scale(1.2);
background-color: currentColor;
}
.multisteps-form__form {
position: relative;
}
.multisteps-form__panel {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 0;
opacity: 0;
visibility: hidden;
}
.multisteps-form__panel.js-active {
height: auto;
opacity: 1;
visibility: visible;
}
.multisteps-form__panel[data-animation="scaleIn"] {
-webkit-transform: scale(0.9);
transform: scale(0.9);
}
.multisteps-form__panel[data-animation="scaleIn"].js-active {
transition-property: all;
transition-duration: 0.2s;
transition-timing-function: linear;
transition-delay: 0s;
-webkit-transform: scale(1);
transform: scale(1);
}
.edit-icon {
margin-left: 10px;
font-size: 15px;
}
.add-another-btn {
border: 2px solid #5C99C7;
color: #5C99C7;
font-size: 14px;
line-height: 1.8em;
}
.add-another-btn:hover {
border: 2px solid #5C99C7;
background: #5C99C7;
color: white;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<body style="background: var(--gray-dark);">
<h1 class="text-center" style="color: var(--light);">Skill Finder</h1>
<section>
<div id="multple-step-form-n" class="container" style="margin-top: 0px;margin-bottom: 10px;padding-top: 57px;">
<div id="progress-bar-button" class="multisteps-form">
<div class="row">
<div class="col-12 col-lg-8 ml-auto mr-auto mb-4">
<div class="multisteps-form__progress"><a class="btn multisteps-form__progress-btn js-active" role="button" title="User Info">City</a><a class="btn multisteps-form__progress-btn" role="button" title="User Info">Skills</a><a class="btn multisteps-form__progress-btn" role="button"
title="User Info">Results</a></div>
</div>
</div>
</div>
<div id="multistep-start-row" class="row">
<div id="multistep-start-column" class="col-12 col-lg-8 m-auto">
<form id="main-form" class="multisteps-form__form">
<div id="single-form-next" class="multisteps-form__panel shadow p-4 rounded bg-white js-active" data-animation="scaleIn">
<h3 class="text-center multisteps-form__title">Enter your City</h3>
<div id="form-content" class="multisteps-form__content">
<div id="input-grp-single" class="form-row mt-4">
<div class="col-12"><input class="form-control multisteps-form__input" type="text" placeholder="City"></div>
</div>
<div id="next-button" class="button-row d-flex mt-4"><button class="btn btn btn-primary ml-auto js-btn-next" type="button" title="Next">Next</button></div>
</div>
</div>
<div id="single-form-next-prev" class="multisteps-form__panel shadow p-4 rounded bg-white" data-animation="scaleIn">
<h3 class="text-center multisteps-form__title">Skills</h3>
<div id="form-content-1" class="multisteps-form__content">
<div id="input-grp-single-1" class="form-row mt-4">
<div class="col-12"><input class="form-control multisteps-form__input" type="text" placeholder="Skill 1"></div>
</div>
<br>
<button id='addButton' class="btn btn-outline-primary text-truncate float-none float-sm-none add-another-btn" data-bss-hover-animate="pulse" type="button">Add Skill<i class="fas fa-plus-circle edit-icon"></i></button>
<div id="next-prev-buttons" class="button-row d-flex mt-4"><button class="btn btn btn-primary js-btn-prev" type="button" title="Prev">Prev</button><button class="btn btn btn-primary ml-auto js-btn-next" type="button" title="Next">Find Results</button></div>
</div>
</div>
<div id="single-form-next-prev-1" class="multisteps-form__panel shadow p-4 rounded bg-white" data-animation="scaleIn">
<h3 class="text-center multisteps-form__title">Map</h3>
<div id="form-content-2" class="multisteps-form__content">
<div id="mapid"></div>
<div id="next-prev-buttons-1" class="button-row d-flex mt-4"><button class="btn btn btn-primary js-btn-prev" type="button" title="Prev">Prev</button><button class="btn btn btn-primary ml-auto js-btn-next" type="button" title="Next">Next</button></div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.min.js"></script>

How to makea div appear after X seconds with javascript?

I am starting with JS and I would like to make the block on the following code appear after 10 seconds.
https://jsfiddle.net/74hmx0vb/1
<div class='popup1' id="popup1">
<div class="container">
<div class="row rowpopup">
<div class="iconpopup">
<img class="imgpopup" src="" />
</div>
<div class="textpopup">
<div class="textpopup1">
</div>
<div class="textpopup2">
</div>
</div>
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
</div>
I would also like to add a slide-in transition when the block appears.
How to do that?
This is using CSS for the animation.
Move .popup1 out of the view to prepare for its animation by setting left: -350px;
Then #keyframes leftSlideIn will contain the style to animate into.
Finally, get .popup1 to animate using leftSlideIn.
animation-fill-mode of forwards will keep the last keyframe state after animation ends.
.popup1 {
height: 100px;
width: 300px;
position: fixed;
z-index: 99999;
background: white;
bottom: 50px;
left: -350px;
border-radius: 10px;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.45);
-moz-box-shadow: 0 0 30px rgba(0, 0, 0, 0.45);
-webkit-box-shadow: 0 0 30px rgba(0, 0, 0, 0.45);
animation: 1s leftSlideIn forwards;
animation-delay: 10s;
}
#keyframes leftSlideIn {
to {
left: 50px;
}
}
.rowpopup {
display: inline-flex;
}
.textpopup {
padding: 10px;
margin-top: -15px;
}
.textpopup1 {
font-size: 16px;
}
.textpopup2 {
font-size: 14px;
}
.iconpopup {
padding: 10px;
}
.imgpopup {
width: 30px;
}
.hidepopup {
display: none !important;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="popup1" id="popup1">
<div class="container">
<div class="row rowpopup">
<div class="iconpopup">
<img
class="imgpopup"
src="https://cdn.shopify.com/s/files/1/0076/6931/7690/files/clock2.png?8339"
/>
</div>
<div class="textpopup">
<div class="textpopup1">
Order as soon as possible
</div>
<div class="textpopup2">
there is little time remaining for this deal to end
</div>
</div>
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
</div>
Here is a jQuery- CSS solution. I have added the hidepopup class to the main div of you content. I remove it after 10 seconds and add the animation class.
$(document).ready(function(){
setTimeout(displayBox, 10000);
});
function displayBox(){
$('.popup1').removeClass('hidepopup');
$('.popup1').addClass('anim-effect ');
}
.popup1 {
height: 100px;
width:300px;
position: fixed;
z-index: 99999;
background: white;
border-radius: 10px;
box-shadow: 0 0 30px rgba(0,0,0,0.45);
}
.anim-effect{
bottom: 50px;
left:50px;
-webkit-animation: slideIn 1s forwards;
-moz-animation: slideIn 1s forwards;
animation: slideIn 1s forwards;
}
#-webkit-keyframes slideIn {
0% {
transform: translateX(-900px);
}
100% {
transform: translateX(0);
}
}
.rowpopup {
display: inline-flex;
}
.textpopup {
padding: 10px;
margin-top: -15px;
}
.textpopup1 {
font-size:16px;
}
.textpopup2 {
font-size:14px;
}
.iconpopup {
padding:10px;
}
.imgpopup {
width:30px;
}
.hidepopup {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class='popup1 hidepopup' id="popup1">
<div class="container">
<div class="row rowpopup">
<div class="iconpopup">
<img class="imgpopup" src="https://cdn.shopify.com/s/files/1/0076/6931/7690/files/clock2.png?8339" />
</div>
<div class="textpopup">
<div class="textpopup1">
Order as soon as possible
</div>
<div class="textpopup2">
there is little time remaining for this deal to end
</div>
</div>
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
</div>
document.getElementById("div_to_display").style.display="block"},time);
so the sample code will look like this
document.getElementById("textpopup1").style.display="block"},10000);
the textpopup1 will display after 10 seconds.

This chain of CSS animation should run infinitely but it doesn't

I have this simple set of CSS animations that I want to run indefinitely. But for some reason, it only runs twice and stops.
Here's a CodePen example.
Here is how I implement it using Jquery (this is also seen on the code)
$('#slide1').one(animationEnd, () => {
$('#slide1').css('display', 'none').removeClass('animate-1')
$('#slide2').css('display', '').addClass('animate-2')
})
$('#slide2').one(animationEnd, () => {
$('#slide2').css('display', 'none').removeClass('animate-2')
$('#slide3').css('display', '').addClass('animate-3')
})
$('#slide3').one(animationEnd, () => {
$('#slide3').css('display', 'none').removeClass('animate-3')
$('#slide1').css('display', '').addClass('animate-1')
})
See that #slide3 should revert to #slide1 for animation. It did, but it stops after 2 cycles.
You have defined counter variable as const, but it needs to be let to allow later reassignment.
let counter = 0;
Also you need to use $.on instead of $.one when binding to the animation end. $.on is used to bind handler to some event (every time it occurres), while $.one is used for one time binding only (run the handler first time the event occurres, but no more that that).
Here is your updated example:
https://codepen.io/anon/pen/WXNOKQ
answer already given and accepted, this is only for infos since the javaScript takes only three boxes into account.
animation-delay can be used to keep animation looping infinitly:
body {
color: #FFFFFF;
background-color: #27292d;
overflow: hidden;
background: #27292d url('bg.jpg') no-repeat fixed center;
font-family: 'Roboto', sans-serif;
}
.slider-container {
position: absolute;
right: 0;
top: 40%;
}
.slider-content {
position: relative;
font-size: 32px;
text-transform: uppercase;
}
.boxes {
float: left;
padding: 10px 20px;
margin: 5px;
position: relative;
}
.sub-box {
clear: both;
margin-left: 60px;
}
.sub-box span {
color: #000000;
padding: 10px 20px;
background-color: #FFFFFF;
}
.box1 {
background-color: #FF4F80;
}
.box2 {
background-color: #4CA2F0;
}
.box3 {
background-color: #53CEC8;
}
#keyframes heartbeat {
0% {
transform: translate(100px, 200px) scale(0)
}
50% {
transform: translate(100px, 200px) scale(0)
}
60% {
transform: translate(-100px) scale(1.5)
}
70% {
transform: translate(-100px) scale(1.5)
}
80% {
transform: translate(-100px) scale(1.5)
}
100% {
transform: translate(100px, -200px) scale(0)
}
}
.slider-single {
position: absolute;
right: 0;
width: 400px;
height: 50px;
margin: 20px;
transform: scale(0);
}
.animate-1 {
transition: 300ms cubic-bezier(.17, .67, .55, 1.43);
animation: ease-out heartbeat 6s -3s infinite;
}
.animate-2 {
transition: 300ms cubic-bezier(.17, .67, .55, 1.43);
animation: ease-out heartbeat 6s -1s infinite;
}
.animate-3 {
transition: 300ms cubic-bezier(.17, .67, .55, 1.43);
animation: ease-out heartbeat 6s 1s infinite;
}
<div class="slider-container">
<div class="slider-content">
<div id='slide1' class="slider-single animate-1">
<div class=''>
<p class='boxes box1'>Pink Header</p>
</div>
<div class='sub-box'>
<span>White Header</span>
</div>
</div>
<div id='slide2' class="slider-single animate-2">
<div>
<p class='boxes box2'>Another Header</p>
</div>
<div class='sub-box'>
<span>subheader</span>
</div>
</div>
<div id='slide3' class="slider-single animate-3">
<div>
<p class='boxes box3'>10 more to go</p>
</div>
</div>
</div>
</div>
<div class="slider-container">
<div class="slider-content">
<div id='slide1' class="slider-single animate-1">
<div class=''>
<p class='boxes box1'>Pink Header</p>
</div>
<div class='sub-box'>
<span>White Header</span>
</div>
</div>
<div id='slide2' class="slider-single" style='display:none;'>
<div>
<p class='boxes box2'>Another Header</p>
</div>
<div class='sub-box'>
<span>subheader</span>
</div>
</div>
<div id='slide3' class="slider-single" style='display:none;'>
<div>
<p class='boxes box3'>10 more to go</p>
</div>
</div>
</div>
</div>

Overlay for several moduls possible?

Why can I not use the class myBtn for several overlays ? It is a class it must work or not? I want to use the overlay function for several buttons is it in some way possible ? I know the ids can not been used for several times thats why I changes it to classes but it still does not work.
I have the example from w3schools below.
<!DOCTYPE html>
<html>
<head>
<style>
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
-webkit-animation-name: fadeIn; /* Fade in the background */
-webkit-animation-duration: 0.4s;
animation-name: fadeIn;
animation-duration: 0.4s
}
/* Modal Content */
.modal-content {
position: fixed;
bottom: 0;
background-color: #fefefe;
width: 100%;
-webkit-animation-name: slideIn;
-webkit-animation-duration: 0.4s;
animation-name: slideIn;
animation-duration: 0.4s
}
/* The Close Button */
.close {
color: white;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.modal-header {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
.modal-body {padding: 2px 16px;}
.modal-footer {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
/* Add Animation */
#-webkit-keyframes slideIn {
from {bottom: -300px; opacity: 0}
to {bottom: 0; opacity: 1}
}
#keyframes slideIn {
from {bottom: -300px; opacity: 0}
to {bottom: 0; opacity: 1}
}
#-webkit-keyframes fadeIn {
from {opacity: 0}
to {opacity: 1}
}
#keyframes fadeIn {
from {opacity: 0}
to {opacity: 1}
}
</style>
</head>
<body>
<h2>Bottom Modal</h2>
<!-- Trigger/Open The Modal -->
<button class="myBtn">Open Modal</button>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-header">
<span class="close">×</span>
<h2>Modal Header</h2>
</div>
<div class="modal-body">
<p>Some text in the Modal Body</p>
<p>Some other text...</p>
</div>
<div class="modal-footer">
<h3>Modal Footer</h3>
</div>
</div>
</div>
<h2>2 Bottom Modal</h2>
<!-- Trigger/Open The Modal -->
<button class="myBtn">Open Modal</button>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-header">
<span class="close">×</span>
<h2>Modal Header</h2>
</div>
<div class="modal-body">
<p>Some text in the Modal Body</p>
<p>Some other text...</p>
</div>
<div class="modal-footer">
<h3>Modal Footer</h3>
</div>
</div>
</div>
<script>
// Get the modal
var modal = document.getElementById('myModal');
// Get the button that opens the modal
var btn = document.getElementsByClassName("myBtn")[0];
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
</body>
</html>
U are using 2 times the following id.
id="myModal"
Change it to class and also the javascript part so it looks like this:
var modal = document.getElementByClassName('myModal');
As u said, u can only use once an id.

Jquery multiple div toggle

OK. It won't take anybody long to work out that I am learning jQuery here and might have gone about this in THE most cack-handed way possible. That's why I'm here though.
I have been creating a "panel" based menu system that provides a number of different functions (menu, filter, search, basket and account). I have it 99% where I want to be. Indeed if you click on the menu icon (as an example) you will see the exact effect. Click it again and everything is perfect.
My problem comes when the user clicks on another icon with their initial "panel" open. Now you can see the gaps in my knowledge.
Please note the effect is on a different div for the panel and on the same div each time (main). Naturally it would be best if either:
a) when clicking on a new icon without closing a panel the jQuery closes the previous panel, removes the close-btn, slides back the main and then opens fires the new panel.
or
b) it closes the previous panel, removes the close-btn but keeps the main open (I think this is over complicating).
HTML
<div id="mainpanel">
<div class="menunav">
<div class="toggle menu-btn"></div>
<div class="toggle filter-btn"></div>
<div class="toggle search-btn"></div>
<div class="toggle basket-btn"></div>
<div class="toggle account-btn"></div>
</div>
</div>
<div class="togglepanel mainmenu">
menu here
</div>
<div class="togglepanel filter">
filter here
</div>
<div class="togglepanel search">
search here
</div>
<div class="togglepanel basket">
basket here
</div>
<div class="togglepanel account">
account here
</div>
<main>
content will be here
</main>
CSS
#mainpanel {
position: fixed;
display: table;
top: 0;
left: 0;
width: 125px;
height: 100%;
background: #206ba4;
vertical-align: middle;
z-index: 9999;}
main {
position: relative;
top: 0;
margin-left: 125px;
transform: translateX(0);
transform: translateY(0);
transition: transform .5s;}
.move {
transform: translateX(300px) !important;}
.menunav {
display: table-cell;
color: #fff;
z-index: 1001;
margin: 20px 0 0;
text-align: center;
vertical-align: middle;}
.menunav div {
display: block;
width: 100%;
margin: 0 0 30px;
text-align: center;}
.menu-btn:after, .filter-btn:after, .search-btn:after, .basket-btn:after, .account-btn:after, .close-btn:after {
font-family: FontAwesome;
content: "menu";
font-size: 1.8em;
font-weight: 200;
color: #fff;
display: block;
height: 1em;
width: 1em;
margin: 0 0 0 30%;
cursor: pointer;}
.filter-btn:after {
content: "filter";}
.search-btn:after {
content: "search";}
.basket-btn:after {
content: "basket";}
.account-btn:after {
content: "account";}
.close-btn:after {
content: "close";}
.mainmenu, .filter, .search, .basket, .account {
position: fixed;
width: 300px;
top: 0;
left: 125px;
height: 100%;
background: #54a4de;
transform: translateX(-100%);
transition: transform .5s;
z-index: -1;}
.expand {
transform: translateX(0px);}
jQuery
jQuery(function($){
$('.menu-btn').click(function(){
$('.mainmenu').toggleClass('expand')
$('main').toggleClass('move')
$('.menu-btn').toggleClass('close-btn')
})
})
jQuery(function($){
$( '.filter-btn' ).click(function(){
$('.filter').toggleClass('expand')
$('main').toggleClass('move')
$('.filter-btn').toggleClass('close-btn')
})
})
jQuery(function($){
$( '.search-btn' ).click(function(){
$('.search').toggleClass('expand')
$('main').toggleClass('move')
$('.search-btn').toggleClass('close-btn')
})
})
jQuery(function($){
$( '.basket-btn' ).click(function(){
$('.basket').toggleClass('expand')
$('main').toggleClass('move')
$('.basket-btn').toggleClass('close-btn')
})
})
jQuery(function($){
$( '.account-btn' ).click(function(){
$('.account').toggleClass('expand')
$('main').toggleClass('move')
$('.account-btn').toggleClass('close-btn')
})
})
Here is the jsfiddle
Many thanks, in advance, for any pointers....my head hurts!
DEMO HERE
Many redundant code in your attempt, but still a good attempt to achieve this. So below are my suggestions to achieve this.
Tips:
Do not include multiple jQuery(function as this is equivalent to $(document).ready function and its good if you have only one per
js file
Write a single common event to all the buttons and differentiate based on $(this) for each click that happens
Add an extra data-* attribute to your .toggle element, say here data-target, to target its corresponding panel-body
So below are some changes I made to your code..
HTML
<div class="menunav">
<!--data-target to each of its corresponding body class-->
<div class="toggle menu-btn" data-target=".mainmenu"></div>
<div class="toggle filter-btn" data-target=".filter"></div>
<div class="toggle search-btn" data-target=".search"></div>
<div class="toggle basket-btn" data-target=".basket"></div>
<div class="toggle account-btn" data-target=".account"></div>
</div>
JS
jQuery(function($){
//click event to one common class i.e toggle
$('.toggle').click(function(){
var target=$(this).data('target'); //get the clicked element's target property
$('.togglepanel').not($(target)).removeClass('expand');
//remove class from all the togglepanel elements except the current element's target
$('.toggle').removeClass('close-btn');
//general action in any scenario to remove close-btn
if($(target).hasClass('expand'))
{
//if target has expand class then remove it and do necessary changes
$(target).removeClass('expand')
$('main').removeClass('move')
$(this).removeClass('close-btn')
}
else
{
//else add necessary classes
$(target).addClass('expand')
$('main').addClass('move')
$(this).addClass('close-btn')
}
})
})
jQuery(function($){
$(document).on('click', '.toggle', function (){
// to close all open contents
$('.togglepanel').removeClass('expand');
$('main').removeClass('move');
var target = $(this).data("target");
if( $(this).hasClass('close-btn') ){
$('.toggle').toggleClass('close-btn', false);
$('main').toggleClass('move', false)
$(target).toggleClass('expand', false);
}else{
$('.toggle').toggleClass('close-btn', false);
$(this).toggleClass('close-btn', true);
$('main').toggleClass('move', true)
$(target).toggleClass('expand', true);
}
});
})
#mainpanel {
position: fixed;
display: table;
top: 0;
left: 0;
width: 125px;
height: 100%;
background: #206ba4;
vertical-align: middle;
z-index: 9999;
}
main {
position: relative;
top: 0;
margin-left: 125px;
transform: translateX(0);
transform: translateY(0);
transition: transform .5s;
}
.move {
transform: translateX(300px) !important;
}
.menunav {
display: table-cell;
color: #fff;
z-index: 1001;
margin: 20px 0 0;
text-align: center;
vertical-align: middle;
}
.menunav div {
display: block;
width: 100%;
margin: 0 0 30px;
text-align: center;
}
.menu-btn:after, .filter-btn:after, .search-btn:after, .basket-btn:after, .account-btn:after, .close-btn:after {
font-family: FontAwesome;
content: "menu";
font-size: 1.8em;
font-weight: 200;
color: #fff;
display: block;
height: 1em;
width: 1em;
margin: 0 0 0 30%;
cursor: pointer;
}
.filter-btn:after {
content: "filter";
}
.search-btn:after {
content: "search";
}
.basket-btn:after {
content: "basket";
}
.account-btn:after {
content: "account";
}
.close-btn:after {
content: "close";
}
}
.close-btn:after {
content: "\f00d";
}
.mainmenu, .filter, .search, .basket, .account {
position: fixed;
width: 300px;
top: 0;
left: 125px;
height: 100%;
background: #54a4de;
transform: translateX(-100%);
transition: transform .5s;
z-index: -1;
}
.expand {
transform: translateX(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainpanel">
<div class="menunav">
<div class="toggle menu-btn" data-target=".mainmenu"></div>
<div class="toggle filter-btn" data-target=".filter"></div>
<div class="toggle search-btn" data-target=".search"></div>
<div class="toggle basket-btn" data-target=".basket"></div>
<div class="toggle account-btn" data-target=".account"></div>
</div>
</div>
<div class="togglepanel mainmenu">
menu here
</div>
<div class="togglepanel filter">
filter here
</div>
<div class="togglepanel search">
search here
</div>
<div class="togglepanel basket">
basket here
</div>
<div class="togglepanel account">
account here
</div>
<main>
content will be here
</main>
You are actually doing a lot of codes which can be converted to a single line.
Instead of adding a click event on each buttons, try something like this:
First, add a data-target attribute to your buttons, something like:
<div class="toggle menu-btn" data-target=".mainmenu"></div>
<div class="toggle filter-btn" data-target=".filter"></div>
<div class="toggle search-btn" data-target=".search"></div>
<div class="toggle basket-btn" data-target=".basket"></div>
<div class="toggle account-btn" data-target=".account"></div>
And on your jQuery:
jQuery(function($){
$(document).on('click', '.toggle', function (){
// to close all open contents
$('.togglepanel').removeClass('expand');
$('main').removeClass('move');
var target = $(this).data("target");
if( $(this).hasClass('close-btn') ){
$('.toggle').toggleClass('close-btn', false);
$('main').toggleClass('move', false)
$(target).toggleClass('expand', false);
}else{
$('.toggle').toggleClass('close-btn', false);
$(this).toggleClass('close-btn', true);
$('main').toggleClass('move', true)
$(target).toggleClass('expand', true);
}
});
});

Categories

Resources