Close offcanvas with a button - javascript

Trying to close the offcanvas with the close button inside the offcanvas. Right now, I can only close it with the button I opened it with. What did I do wrong? See attached code.
(function mainScript() {
"use strict";
const offcanvasToggle = document.querySelector('[data-bs-toggle="offcanvas"], [data-bs-dissmiss="offcanvas"]');
const offcanvasCollapse = document.querySelector(".offcanvas-collapse");
offcanvasToggle.addEventListener("click", function () {
offcanvasCollapse.classList.toggle("open");
});
})();
.offcanvas-collapse {
position: fixed;
top: 0;
/* Height of navbar */
bottom: 0;
left: 100%;
width: 30%;
padding: 8px 8px;
overflow-y: auto;
visibility: hidden;
background-color: #343a40;
transition: transform 0.3s ease-in-out, visibility 0.3s ease-in-out;
}
.offcanvas-collapse.open {
visibility: visible;
transform: translateX(-100%);
}
<div id="navbar" class="flex-wrap center">
<div id="nav-toggler-wrapper">
<button id="nav-toggler" aria-label="Menü" data-bs-toggle="offcanvas" aria-label="Toggle navigation">
<span class="menu-label">Menu</span>
</button>
</div>
</div>
<div id="sidenav" class="offcanvas offcanvas-collapse">
<div class="offcanvas-header flex-wrap center between">
<button id="nav-toggler" data-bs-dissmiss="offcanvas" aria-label="Toggle navigation">
<span class="menu-label">Close</span>
</button>
</div>
</div>

You need to use querySelectorAll instead of querySelector, because you try to select more then one element and use forEach for apply eventListner to each one like:
(function mainScript() {
"use strict";
const offcanvasToggle = document.querySelectorAll('[data-bs-toggle="offcanvas"], [data-bs-dissmiss="offcanvas"]');
const offcanvasCollapse = document.querySelector(".offcanvas-collapse");
offcanvasToggle.forEach(el => {
el.addEventListener("click", function() {
offcanvasCollapse.classList.toggle("open");
});
});
})();
.offcanvas-collapse {
position: fixed;
top: 0;
/* Height of navbar */
bottom: 0;
left: 100%;
width: 30%;
padding: 8px 8px;
overflow-y: auto;
visibility: hidden;
background-color: #343a40;
transition: transform 0.3s ease-in-out, visibility 0.3s ease-in-out;
}
.offcanvas-collapse.open {
visibility: visible;
transform: translateX(-100%);
}
<div id="navbar" class="flex-wrap center">
<div id="nav-toggler-wrapper">
<button id="nav-toggler" aria-label="Menü" data-bs-toggle="offcanvas" aria-label="Toggle navigation">
<span class="menu-label">Menu</span>
</button>
</div>
</div>
<div id="sidenav" class="offcanvas offcanvas-collapse">
<div class="offcanvas-header flex-wrap center between">
<button id="nav-toggler" data-bs-dissmiss="offcanvas" aria-label="Toggle navigation">
<span class="menu-label">Close</span>
</button>
</div>
</div>

Related

Span tag disappear after few seconds

I have two div those contain h tag inside which I have a span tag those contain letters
First Div
<div class="startname">
<h6 class="alphabets" >
<span class="letters">A</span>
<span class="letters">B</span>
<span class="letters">C</span>
<span class="letters">D</span>
<span class="letters">E</span>
<span class="letters">F</span>
</h6>
</div>
Second Div
<div class="endname">
<h6 class="alphabets" >
<span class="letters">G</span>
<span class="letters">H</span>
<span class="letters"> </span>
<span class="letters">I</span>
<span class="letters">J</span>
</h6>
</div>
First div starts from left top of the screen and scales to a particular location using keyframe
Second div starts from few pixels below the first div of the screen and scales to a particular location using keyframe
I want letters EF in startname and <whitespace>IJ in lastname to disappear after few seconds of startname and lastname align
Here's the code I found which pages div disappear after few seconds
Tried it out in svelte doesn't seem to be working here's the entire code below. How do I achieve the desired result?
<script>
window.onload = function() {
window.setTimeout(fadeout, 4000); //8 seconds
}
function fadeout() {
document.getElementById('fadeout').style.opacity = '0';
}
</script>
<style>
.startname {
width: 150px;
height: 150px;
background: red;
position: relative;
animation: startnamemymove 5s 1 forwards;
display: flex;
align-items: center;
justify-content:flex-end;
}
#fadeout {
opacity: 1;
transition: 3s opacity;
}
.endname {
width: 150px;
height: 150px;
background: red;
position: relative;
animation: endnamemymove 5s 1 forwards;
display: flex;
align-items: center;
}
#keyframes startnamemymove {
from {top: 0px;
left:0px;
transform: scale(.5);}
to {top:150px;left: 200px;
transform: scale(2.0);
}
}
#keyframes endnamemymove {
from {top: 100px;
left:100px;
transform: scale(.5);}
to {top:0px;left: 500px;
transform: scale(2.0);
}
}
</style>
<h1>The #keyframes Rule</h1>
<div class="startname">
<h6 class="alphabets" >
<span class="letters">A</span>
<span class="letters">B</span>
<span class="letters">C</span>
<span class="letters">D</span>
<span class="letters" id="fadeout">E</span>
<span class="letters" id="fadeout">F</span>
</div>
<div class="endname">
<h6 class="alphabets" >
<span class="letters">G</span>
<span class="letters">H</span>
<span class="letters" id="fadeout"> </span>
<span class="letters" id="fadeout">I</span>
<span class="letters" id="fadeout">J</span>
</h6>
</div>
Here's a solution with these modifications:
set the transition class after a timeout via Svelte's use:action
(the class has to have the :global() flag so it gets compiled even though the class is not directly used. And both classes are needed :global(.letters.fadeout) so that the specificity is enough to overwrite the setting of the first class, because these elements have the Svelte suffix added .letters.svelte-5nw7mj)
get rid of the whitespace between <span> elements by setting display:flex on the <h6> (a question on this)
if the width should be animated, it must be set before on the <span> elements. This can be done by giving them display: inline-block; and the desired width
->> a REPL
(I reduced the time to 3s so it was faster to try out...)
<script>
function handleFadeout(node) {
setTimeout(() => {
node.classList.add('fadeout')
},3000)
}
</script>
<h1>The #keyframes Rule</h1>
<div class="startname">
<h6 class="alphabets" >
<span class="letters">A</span>
<span class="letters">B</span>
<span class="letters">C</span>
<span class="letters">D</span>
<span class="letters" use:handleFadeout>E</span>
<span class="letters" use:handleFadeout>F</span>
</h6>
</div>
<div class="endname">
<h6 class="alphabets" >
<span class="letters">G</span>
<span class="letters">H</span>
<span class="letters" use:handleFadeout> </span>
<span class="letters" use:handleFadeout>I</span>
<span class="letters" use:handleFadeout>J</span>
</h6>
</div>
<style>
.startname {
width: 150px;
height: 150px;
background: red;
position: relative;
animation: startnamemymove 3s 1 forwards;
display: flex;
align-items: center;
justify-content:flex-end;
}
.endname {
width: 150px;
height: 150px;
background: red;
position: relative;
animation: endnamemymove 3s 1 forwards;
display: flex;
align-items: center;
}
#keyframes startnamemymove {
from {top: 0px;
left:0px;
transform: scale(.5);}
to {top:150px;left: 200px;
transform: scale(2.0);
}
}
#keyframes endnamemymove {
from {top: 100px;
left:100px;
transform: scale(.5);}
to {top:0px;left: 500px;
transform: scale(2.0);
}
}
.letters {
display: inline-block;
width: 12px;
}
h6 {
display:flex;
}
:global(.letters.fadeout) {
opacity: 0;
width: 0px;
padding: 0;
overflow: hidden;
transition: all 300ms;
}
</style>
You can't use same id in several elements. Please use class.
The method getElementById() will return only the first element with that id. You can use classes and getElementsByClassName(), which returns the list of elements with that class name. Here is the code.
The error is on repeating id fadeout more than once.
You need to create a new class with the styles you want and put it together with letters: class="letters fadeout". Just a space between.
Read more here: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors#id_selectors
Here is the result which can help you.
Steps need to remember
HTML attribute ID will be use on single element
You can use getElementsByClassName() or querySelectorAll() to apply opacity in multiple elements.
window.onload = function() {
window.setTimeout(fadeout, 4000); //8 seconds
}
function fadeout() {
document.querySelectorAll('span.fadeout').forEach(el => {
el.style.display = "none";
});
}
.startname {
width: 150px;
height: 150px;
background: red;
position: relative;
animation: startnamemymove 5s 1 forwards;
display: flex;
align-items: center;
justify-content:flex-end;
padding-right: 10px;
}
.fadeout {
opacity: 1;
transition: 3s opacity;
}
.endname {
width: 150px;
height: 150px;
background: red;
position: relative;
animation: endnamemymove 5s 1 forwards;
display: flex;
align-items: center;
}
#keyframes startnamemymove {
from {top: 0px;
left:0px;
transform: scale(.5);}
to {top:150px;left: 200px;
transform: scale(2.0);
}
}
#keyframes endnamemymove {
from {top: 100px;
left:100px;
transform: scale(.5);}
to {top:0px;left: 500px;
transform: scale(2.0);
}
}
<h1>The #keyframes Rule</h1>
<div class="startname">
<h6 class="alphabets" >
<span class="letters">A</span>
<span class="letters">B</span>
<span class="letters">C</span>
<span class="letters">D</span>
<span class="letters fadeout">E</span>
<span class="letters fadeout">F</span>
</h6>
</div>
<div class="endname">
<h6 class="alphabets" >
<span class="letters">G</span>
<span class="letters">H</span>
<span class="letters fadeout"> </span>
<span class="letters fadeout">I</span>
<span class="letters fadeout">J</span>
</h6>
</div>

How to assign diffrent popup with same function with 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>

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>

Bootstrap navbar disappears when in a div where it should be always visible

Sorry for the bad title, I didn't really know how to explain it concisely.
I'm trying to make a navbar that only shows up when hovering over an icon that appears only when scrolling upwards and stays visible as long as I have my cursor over it (over the navbar or the icon).
The problem is, I want it to be always visible in the first section of the website.
It works ok when first loading it, but after scrolling down and then returning up when I hover over the navbar and then I move the cursor outside it disappears.
Here's a fiddle so you can take a look: https://jsfiddle.net/kksp9pbu/1/
Here's the HTML:
<div id="menu-trigger" class="hidden-menu trigger"><i class="fa fa-bars"></i></div>
<nav class="navbar navbar-default navbar-fixed-top" id="main-nav">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
</div>
</div>
</nav>
<main>
<section class="container-fluid">
<div class="row">
<div class="col-xs-12" id="header">
<h1>The navbar should always be visible here</h1>
</div>
</div>
</section>
<section class="container-fluid">
<div class="row" id="about">
<div id="about-l"><h3>About</h3></div>
</div>
</section>
<section class="container-fluid">
<div class="row" id="portfolio">
<div id="about-l"><h3>Portfolio</h3></div>
</div>
</section>
CSS in case you need it:
#menu-trigger {
position: fixed;
top: 15px;
height: 40px;
right: 20px;
z-index:1;
cursor: pointer;
}
.fa-bars{
color: #fff
}
#main-nav {
height: 70px;
background-color: rgba(0, 119, 124, 0.46);
border-bottom: 3px solid #111;
}
.navbar-fixed-top {
top:0px;
-webkit-transition: all 0.5s ease;
transition: all 0.5s ease;
}
.hidden-nav {
top:-75px !important;
}
.trigger {
opacity: 1;
-webkit-transition: all 0.5s ease;
transition: all 0.5s ease;
}
.hidden-menu {
opacity: 0;
}
#main-nav a:link,
#main-nav a:visited {
text-decoration: none;
text-transform: uppercase;
font-weight: 400;
}
.navbar-nav {
margin-left: 80px;
}
.navbar-nav li {
padding: 30px 0 0 100px;
}
.navbar-nav>li>a {
padding: 0 0 5px 0 !important;
color: #fff !important;
}
.navbar-nav a:hover,
.navbar-nav a:active {
border-bottom: 1px solid #333;
}
.navbar-brand {
transition: color 0.2s ease;
color: #fff!important;
font-size: 2em !important;
font-weight: 100 !important;
}
.navbar-brand:hover {
color: #ffb100 !important;
}
/*----HEADER----*/
#header {
text-align: center;
height: 100vh;
background-color: #333;
background-color: #333;
color: #fff;
padding-top: 15%;
}
#header h1 {
font-size: 2.8em;
font-weight: 100;
}
/*----ABOUT----*/
#about{
height:100vh;
background-color:#39bebe;
}
#portfolio{
height:100vh;
background-color:#009eee;
}
And here's the jQuery code:
$(document).ready(function(){
var lastScrollTop = 0;
$(window).scroll(function(event) {
var scroll = $(window).scrollTop();
var aboutOffset=$("#about").offset().top;
if(scroll<=aboutOffset){ // if I haven't reached #about section yet
$("#main-nav").removeClass("hidden-nav");
} else {
$("#main-nav").addClass("hidden-nav"); //hide the navbar
function hideIt(){
$("#menu-trigger").addClass("hidden-menu"); //hide the trigger
};
if (scroll > lastScrollTop){ //scrolling down
setTimeout(hideIt, 2000);
} else {
$("#menu-trigger").removeClass("hidden-menu");
}
lastScrollTop = scroll;
$("#menu-trigger, #main-nav").on("mouseover", function(){ //if I hover over the trigger or the navbar
$("#main-nav").removeClass("hidden-nav"); // I leave the navbar visible
});
$("#menu-trigger, #main-nav").on("mouseout", function(){ //if I move the cursor out of the trigger or the navbar
$("#main-nav").addClass("hidden-nav"); // hide the navbar
});
}
}); // END $(window).scroll();
}); //END $(document).ready();
You have a function that it does something when you do scroll.
$(window).scroll(function(event) {
...
}
And you have a conditional that when it's false, this sets somthing behaviors.
if(scroll<=aboutOffset){
$("#main-nav").removeClass("hidden-nav");
} else {
...
}
The behavior that it's doing to hide the navbar is this:
$("#menu-trigger, #main-nav").on("mouseout", function(){
$("#main-nav").addClass("hidden-nav");
});
You need to delete this behavior ;-)
UPDATE
Or, a better solution would be this:
if(scroll<=aboutOffset){
$("#main-nav").removeClass("hidden-nav");
$("#menu-trigger, #main-nav").off("mouseout");
} else {
...
}

Bootstrap Dropdown button width issue

I am using a sidebar to have a list of URL links or buttons if you will but I also need some dropdown buttons/lists in there as well.
I am having an issue of having it look consistently alike and also fill the width of the container also as front end isn't my strongest suite am struggling to get it to look how I want.
You can see that the list within the sidebar is the full width across.....but the button isn't so I need to get it the whole way across and look consistent with the list or alternatively somehow throw a drop down menu on top of the list if required, I have tried to maniputlate it via using btn-block and width 100% to no joy
I need to have a separate buttons for the drop down button seen in example.
jQuery(function($) {
$(document).ready(function() {
$('[data-toggle=offcanvas]').click(function() {
if ($('.sidebar-offcanvas').css('background-color') == 'rgb(255, 255, 255)') {
$('.list-group-item').attr('tabindex', '-1');
} else {
$('.list-group-item').attr('tabindex', '');
}
$('.row-offcanvas').toggleClass('active');
});
});
});
body {
padding-top: 50px;
}
/*
* Style tweaks
* --------------------------------------------------
*/
html,
body {
overflow-x: hidden;
/* Prevent scroll on narrow devices */
height: 100%;
}
body {
padding-top: 70px;
}
footer {
padding: 30px 0;
}
.navbar-inverse .navbar-brand:hover,
.navbar-inverse .navbar-brand:focus {
background-color: transparent;
color: #999999;
}
.head {
background: #668B8B;
color: #000000;
}
.side-contain {
margin-top: 5px;
border: 2px solid #668B8B;
border-radius: 10px;
}
/*
* Off Canvas
* --------------------------------------------------
* Greater thav 768px shows the menu by default and also flips the semantics
* The issue is to show menu for large screens and to hide for small
* Also need to do something clever to turn off the tabs for when the navigation is hidden
* Otherwise keyboard users cannot find the focus point
* (For now I will ignore that for mobile users and also not worry about
* screen re-sizing popping the menu out.)
*/
#media screen and (min-width: 768px) {
.row-offcanvas {
position: relative;
-webkit-transition: all .25s ease-out;
-moz-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas-right {
right: 25%;
}
.row-offcanvas-left {
left: 25%;
}
.row-offcanvas-right .sidebar-offcanvas {
right: -25%;
/* 3 columns */
background-color: rgb(255, 255, 255);
}
.row-offcanvas-left .sidebar-offcanvas {
left: -25%;
/* 3 columns */
background-color: rgb(255, 255, 255);
}
.row-offcanvas-right.active {
right: 0;
/* 3 columns */
}
.row-offcanvas-left.active {
left: 0;
/* 3 columns */
}
.row-offcanvas-right.active .sidebar-offcanvas {
background-color: rgb(254, 254, 254);
}
.row-offcanvas-left.active .sidebar-offcanvas {
background-color: rgb(254, 254, 254);
}
.row-offcanvas .content {
width: 75%;
/* 9 columns */
-webkit-transition: all .25s ease-out;
-moz-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas.active .content {
width: 100%;
/* 12 columns */
}
.sidebar-offcanvas {
position: absolute;
top: 0;
width: 25%;
/* 3 columns */
}
}
#media screen and (max-width: 767px) {
.row-offcanvas {
position: relative;
-webkit-transition: all .25s ease-out;
-moz-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas-right {
right: 0;
}
.row-offcanvas-left {
left: 0;
}
.row-offcanvas-right .sidebar-offcanvas {
right: -50%;
/* 6 columns */
}
.row-offcanvas-left .sidebar-offcanvas {
left: -50%;
/* 6 columns */
}
.row-offcanvas-right.active {
right: 50%;
/* 6 columns */
}
.row-offcanvas-left.active {
left: 50%;
/* 6 columns */
}
.sidebar-offcanvas {
position: absolute;
top: 0;
width: 50%;
/* 6 columns */
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="generator" content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<meta charset="utf-8" />
<title>Test</title>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand">Test</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form action="/logoutadmin" class="navbar-form navbar-right">
<button class="btn btn-success" type="submit" id="user" onsubmit="return false">Log Out</button>
</form>
</div>
</div>
</nav>
<div class="container-fluid">
<button type="button" class="btn btn-primary btn-xs" data-toggle="offcanvas">Toggle nav</button>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-6 col-sm-2 sidebar-offcanvas" id="sidebar" role="navigation">
<div class="side-contain">
<div class="panel-heading head" role="tab" id="headingOne">
<h2 class="panel-title">My Account</h2>
</div>
<div class="btn-group">
<button class="btn btn-default" type="button">Dropdown</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li>HTML
</li>
<li>CSS
</li>
<li>JavaScript
</li>
</ul>
</div>
- Placeholder
- Placeholder
- Placeholder
- Placeholder
</div>
</div>
<!--/span-->
<div class="col-xs-12 col-sm-10 content">
<div>
<h1 class="main-head">Test</h1>
<p class="lead">Hallo
</div>
</div>
<!--/span-->
</div>
<!--/row-->
</div>
<!-- /.container -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
</body>
</html>
I have attached a JS fiddle also:
https://jsfiddle.net/z2a7jr68/1/
You can add : btn-group-justified class to btn-group and width : 90% to next button
<div class="btn-group btn-group-justified" role="group">
<button class="btn btn-default" type="button" style="
width: 90%;
">Dropdown</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li>HTML</li>
<li><a `enter code here`href="#">CSS</a></li>
<li>JavaScript</li>
</ul>
</div>
Add following style to your drop down buttons.
<div class="btn-group" style="width:100%">
<button class="btn btn-default" type="button" style="width:80%">Dropdown</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="width:20%;">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" style="width:100%">
<li>HTML
</li>
<li>CSS
</li>
<li>JavaScript
</li>

Categories

Resources