I'm trying to make an open/colapse elements on this page. I'm using #wrapper::before to overlay screen, also it has a eventlistner to close elements showed. Using {capture: true} on wrapper eventListner I made it open and colapse, but when I click on search bar to type something, it colapse anyway.
How do I make it not colapse with any click? Just on the wrapper::before
const responsiveIcons = document.querySelectorAll('.mininav>*');
const wrapper = document.querySelector('#wrapper');
const mainNav = document.querySelector('aside');
const searchBar = document.querySelector('form#search');
function openItem(e){
e.classList.add('show');
wrapper.classList.add('show');
}
function closeItems(){
switch(true){
case mainNav.classList.contains('show'):
mainNav.classList.remove('show');
break;
case searchBar.classList.contains('show'):
searchBar.classList.remove('show');
break;
}
wrapper.classList.remove('show');
}
function showSelector(e){
const eClass = e.target.classList;
switch(true){
case eClass.contains('nav'):
openItem(mainNav);
break;
case eClass.contains('searchbar'):
openItem(searchBar);
break;
}
// if(e.target.classList.contains('nav')){
// openItem(mainNav);
// } else if{}
}
wrapper.addEventListener('click', closeItems, {capture: true});
responsiveIcons.forEach(e => e.addEventListener('click', showSelector));
:root {
--font-family: "Ubuntu", sans-serif;
--font-size: 16px;
--title-color: rgb(58, 58, 58);
--background-color: white;
--bgHeader: #003459;
--bgSearchBar: #002a45;
--headers: #003459;
--bgMain: #EBF9FF;
--textColor: #00171F;
--cardGreen: rgba(157, 255, 0, 1);
--cardBlue: rgba(0, 174, 255, 1);
--cardRed: rgba(255, 42, 42, 1);
--cardYellow: rgba(255, 251, 0, 1);
--headerMargin: .5rem 0;
--box-shadow: 0 1rem 1rem -0.75rem rgb(105 96 215 / 18%);
--wrap-first-column: 14rem;
--nav-txt-color: #5c5c5c;
}
#wrapper {
display: grid;
grid-template-columns: min-content 1fr;
grid-template-rows: min-content 1fr;
background-color: var(--bgMain);
min-height: 100%;
}
#wrapper.show::before {
content: "";
position: fixed;
background-color: black;
opacity: 0.5;
z-index: 2;
width: 100%;
height: 100%;
}
header {
grid-column: span 2;
column-span: all;
background: var(--bgHeader);
justify-content: space-between;
}
.brand {
height: fit-content;
width: 12.5rem;
align-items: center;
margin: var(--headerMargin);
}
header > div + div {
height: fit-content;
width: auto;
align-items: center;
margin: var(--headerMargin);
margin: auto 0.5rem;
}
.mininav {
color: white;
width: max-content;
display: inline-block;
flex-direction: row;
flex-wrap: nowrap;
}
aside.show {
left: 0;
}
aside {
inset: 0 auto;
position: absolute;
top: 0;
left: calc(var(--wrap-first-column) * -1);
}
main {
width: inherit;
}
form#search.show {
top: 0.5rem;
}
form#search {
position: absolute;
top: -2.5rem;
left: 0;
width: 100%;
transition: top 0.15s ease-out;
}
form#search > div {
position: relative;
margin-left: 10px;
}
<div id="wrapper">
<!-- Full container grid -->
<header class="flex">
<div class="brand flex">
<img src="./images/logo-cp-admin.png" alt="" class="">
</div>
<div class="flex">
<!-- search bar -->
<form id="search" action="#" method="get">
<div class=" align-top">
<input id="searchbar" type="search" placeholder=" "
class="text-xs focus:outline-none bg-bgSearchBar/[.0] focus:bg-bgSearchBar/50 text-white p-1.5 pl-3 pr-6 my-0.5 rounded-xl">
<label for="searchbar">Busca...</label>
<span class="mdi mdi-magnify"></span>
</div>
</form>
</div>
<!-- mobile responsive -->
<div class="mininav flex" >
<label class="searchbar mdi mdi-magnify">MAGNIFY</label>
<label class="nav mdi mdi-menu">HAM-MENU
</div>
</header>
<div class="flex col-span2">
<!-- side content (menu & widgets)-->
<aside>
side
</aside>
<main>
main
</main>
</div>
Two things needed to be changed.
First, the closeItems() function needs to be changed to accept an event, and to ignore clicks on the search bar.
Second, the #wrapper.show::before rule needs to not have z-index: 2 which was making the search bar appear below the ::before element and impossible to click on.
const responsiveIcons = document.querySelectorAll('.mininav>*');
const wrapper = document.querySelector('#wrapper');
const mainNav = document.querySelector('aside');
const searchBar = document.querySelector('form#search');
function openItem(e){
e.classList.add('show');
wrapper.classList.add('show');
}
function closeItems(e){
if(e.target.id == 'searchbar')
return;
switch(true){
case mainNav.classList.contains('show'):
mainNav.classList.remove('show');
break;
case searchBar.classList.contains('show'):
searchBar.classList.remove('show');
break;
}
wrapper.classList.remove('show');
}
function showSelector(e){
const eClass = e.target.classList;
switch(true){
case eClass.contains('nav'):
openItem(mainNav);
break;
case eClass.contains('searchbar'):
openItem(searchBar);
break;
}
// if(e.target.classList.contains('nav')){
// openItem(mainNav);
// } else if{}
}
wrapper.addEventListener('click', closeItems, {capture: true});
responsiveIcons.forEach(e => e.addEventListener('click', showSelector));
:root {
--font-family: "Ubuntu", sans-serif;
--font-size: 16px;
--title-color: rgb(58, 58, 58);
--background-color: white;
--bgHeader: #003459;
--bgSearchBar: #002a45;
--headers: #003459;
--bgMain: #EBF9FF;
--textColor: #00171F;
--cardGreen: rgba(157, 255, 0, 1);
--cardBlue: rgba(0, 174, 255, 1);
--cardRed: rgba(255, 42, 42, 1);
--cardYellow: rgba(255, 251, 0, 1);
--headerMargin: .5rem 0;
--box-shadow: 0 1rem 1rem -0.75rem rgb(105 96 215 / 18%);
--wrap-first-column: 14rem;
--nav-txt-color: #5c5c5c;
}
#wrapper {
display: grid;
grid-template-columns: min-content 1fr;
grid-template-rows: min-content 1fr;
background-color: var(--bgMain);
min-height: 100%;
}
#wrapper.show::before {
content: "";
position: fixed;
background-color: black;
opacity: 0.5;
width: 100%;
height: 100%;
}
header {
grid-column: span 2;
column-span: all;
background: var(--bgHeader);
justify-content: space-between;
}
.brand {
height: fit-content;
width: 12.5rem;
align-items: center;
margin: var(--headerMargin);
}
header > div + div {
height: fit-content;
width: auto;
align-items: center;
margin: var(--headerMargin);
margin: auto 0.5rem;
}
.mininav {
color: white;
width: max-content;
display: inline-block;
flex-direction: row;
flex-wrap: nowrap;
}
aside.show {
left: 0;
}
aside {
inset: 0 auto;
position: absolute;
top: 0;
left: calc(var(--wrap-first-column) * -1);
}
main {
width: inherit;
}
form#search.show {
top: 0.5rem;
}
form#search {
position: absolute;
top: -2.5rem;
left: 0;
width: 100%;
transition: top 0.15s ease-out;
}
form#search > div {
position: relative;
margin-left: 10px;
}
<div id="wrapper">
<!-- Full container grid -->
<header class="flex">
<div class="brand flex">
<img src="./images/logo-cp-admin.png" alt="" class="">
</div>
<div class="flex">
<!-- search bar -->
<form id="search" action="#" method="get">
<div class=" align-top">
<input id="searchbar" type="search" placeholder=" "
class="text-xs focus:outline-none bg-bgSearchBar/[.0] focus:bg-bgSearchBar/50 text-white p-1.5 pl-3 pr-6 my-0.5 rounded-xl">
<label for="searchbar">Busca...</label>
<span class="mdi mdi-magnify"></span>
</div>
</form>
</div>
<!-- mobile responsive -->
<div class="mininav flex" >
<label class="searchbar mdi mdi-magnify">MAGNIFY</label>
<label class="nav mdi mdi-menu">HAM-MENU
</div>
</header>
<div class="flex col-span2">
<!-- side content (menu & widgets)-->
<aside>
side
</aside>
<main>
main
</main>
</div>
Related
I'm struggling with infinite carousel below:
let $carousel = document.querySelector('.carousel');
let $ref_ribbon = document.querySelector('.carousel__ribbon');
let $ref_right = document.querySelector('.carousel__button--right');
let $ref_left = document.querySelector('.carousel__button--left');
let $ref_counter = 0;
let $direction;
const transfer = () => {
if ($direction === -1) {
$ref_ribbon.appendChild($ref_ribbon.firstElementChild);
} else if ($direction === 1) {
$ref_ribbon.prepend($ref_ribbon.lastElementChild);
}
$ref_ribbon.style.transition = "none";
$ref_ribbon.style.transform = "translateX(0px)";
setTimeout(function() {
$ref_ribbon.style.transition = "transform .7s ease-in-out";
})
}
const right_button = () => {
if ($direction === 1) {
$ref_ribbon.prepend($ref_ribbon.lastElementChild);
$direction = -1;
}
$direction = -1;
$carousel.style.justifyContent = 'flex-start';
$ref_ribbon.style.transform = `translateX(-${300}px)`;
}
const left_button = () => {
$ref_counter--;
if ($direction === -1) {
$ref_ribbon.appendChild($ref_ribbon.firstElementChild);
$direction = 1;
}
$direction = 1;
$carousel.style.justifyContent = 'flex-end';
$ref_ribbon.style.transform = `translateX(${300}px)`;
}
$ref_right.addEventListener('click', right_button);
$ref_left.addEventListener('click', left_button);
$ref_ribbon.addEventListener('transitionend', transfer)
.carousel {
display: flex;
margin: auto;
position: relative;
height: 200px;
width: 300px;
background-color: red;
justify-content: flex-start;
}
.carousel__button {
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
z-index: 100;
}
.carousel__button--left {
left: 0;
}
.carousel__button--right {
right: 0;
}
.carousel__ribbon {
display: flex;
flex-direction: row;
outline: 3px solid black;
height: 100%;
transition: transform .7s ease-in-out;
}
.carousel__pane {
display: flex;
background-color: skyblue;
height: 100%;
width: 300px;
flex-shrink: 0;
outline: 1px dashed navy;
}
.carousel__content {
text-align: center;
margin: auto;
}
.carousel__indicator {
display: flex;
gap: 10px;
left: 50%;
transform: translateX(-50%);
height: 30px;
position: absolute;
bottom: 0;
}
.carousel__circle {
height: 10px;
width: 10px;
background-color: gray;
border-radius: 50%;
cursor: pointer;
}
.carousel__circle--active {
background-color: black;
}
<div class="carousel">
<button class="carousel__button carousel__button--left"><</button>
<button class="carousel__button carousel__button--right">></button>
<div class="carousel__ribbon">
<div class="carousel__pane">
<p class="carousel__content">Pane 1</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 2</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 3</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 4</p>
</div>
<div class="carousel__pane">
<p class="carousel__content">Pane 5</p>
</div>
</div>
<div class="carousel__indicator">
<div class="carousel__circle carousel__circle--active"></div>
<div class="carousel__circle"></div>
<div class="carousel__circle"></div>
<div class="carousel__circle"></div>
<div class="carousel__circle"></div>
</div>
</div>
I would like to connect indicator so when somebody click on proper circle then carousel will automatically slide to this particular panel. Also, I would like to set this circles that they will show which panel is currently active.
In addition, I would like to get such effect that carousel will jump to this particular panel immediately, ommiting other panels between.
So, if active one is first panel and I click fifth circle, then carousel will smoothly change panel like to the panel number two, but instead of number two I will see number five.
Sadly I always fail to get this effect. I would appriciate if somebody more experienced direct me how to deal with this problem.
I am using an image carousel which is working perfectly. Except that I can't use 2nd, 3rd carousel on same page. If I use more than one carousel on same page than the 2nd and 3rd are not working only the 1st. I am not expert and need some help if it possbile to change the code and have more than one carousel on same page? Here is the code:
Style:
/** img-carousel **/
#imgages-carousel {
display: grid;
align-items: center;
justify-items: center;
padding: 40px 0px;
}
.img-carousel-container {
width: 800px;
position: relative;
}
.img-carousel {
display: flex;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
padding-bottom: 5px;
}
.img-carousel div {
flex: none;
scroll-snap-align: start;
width: 800px;
position: relative;
}
.img-carousel div img {
display: block;
width: 100%;
object-fit: cover;
}
.img-carousel div p {
position: absolute;
top: 0;
right: 10px;
background: rgba(0,0,0,0.5);
color: #fff;
padding: 5px;
border-radius: 10px;
}
.img-carousel-container button {
position: absolute;
top: calc(50% - 15px);
transform: translateY(-50%);
border: none;
background-color: rgba(255, 193, 7, 0.7);
color: #000;
cursor: pointer;
padding: 10px 15px;
border-radius: 50%;
outline: none;
opacity: 0;
transition: all ease-in-out 0.5s;
}
#prev {
left: 10px;
}
#next {
right: 10px;
}
.img-carousel-container:hover button {
opacity: 1;
}
.img-carousel-container button:hover {
background-color: #ffc107;
}
/** custom scrollbar **/
.img-carousel::-webkit-scrollbar {
width: 10px;
height: 10px;
}
.img-carousel::-webkit-scrollbar-thumb {
background: #ffc107;
border-radius: 10px;
}
.img-carousel::-webkit-scrollbar-track {
background: transparent;
}
.img-carousel-container:hover .img-carousel::-webkit-scrollbar-thumb {
visibility: visible;
}
#media screen and (max-width: 800px) {
.img-carousel-container {
width: 100%;
}
.img-carousel div {
width: 100%;
}
}
Script:
const carousel = document.querySelector('.img-carousel');
const prevBtn = document.getElementById('prev');
const nextBtn = document.getElementById('next');
let carsouselImages = document.querySelectorAll('.img-carousel div');
//Next Carousel
const nextCarousel = () => {
if(carsouselImages[carsouselImages.length - 1]) {
carousel.scrollTo(0, 0);
}
carousel.scrollBy(300, 0);
};
nextBtn.addEventListener('click', e => {
nextCarousel();
});
//Prev Carousel
const prevCarousel = () => {
if(carsouselImages[0]) {
carousel.scrollTo(4800,0);
}
carousel.scrollBy(-300, 0);
};
prevBtn.addEventListener('click', e => {
prevCarousel();
});
// Auto carousel
const auto = true; // Auto scroll
const intervalTime = 5000;
let sliderInterval;
if (auto) {
sliderInterval = setInterval(nextCarousel, intervalTime);
};
carousel.addEventListener('mouseover', (stopInterval) => {
clearInterval(sliderInterval);
});
carousel.addEventListener('mouseleave', (startInterval) => {
if (auto) {
sliderInterval = setInterval(nextCarousel, intervalTime);
}
});
//for mobile events
carousel.addEventListener('touchstart', (stopIntervalT) => {
clearInterval(sliderInterval);
});
carousel.addEventListener('touchend', (startIntervalT) => {
if (auto) {
sliderInterval = setInterval(nextCarousel, intervalTime);
}
});
//Debounce
var previousCall;
window.addEventListener('resize', () => {
if (previousCall >= 0) {
clearTimeout(previousCall);
}
previousCall = setTimeout(() => {
carousel.scrollBy(-300, 0);
}, 200);
});
Html:
<!-- section images carousel -->
<section id="imgages-carousel">
<div class="img-carousel-container">
<div class="img-carousel">
<div>
<img src="https://source.unsplash.com/9Nok_iZEgLk/800x450">
<p>1/6</p>
</div>
<div>
<img src="https://source.unsplash.com/4v7ubW7jz1Q/800x450">
<p>2/6</p>
</div>
<div>
<img src="https://source.unsplash.com/rtCujH697DU/800x450">
<p>3/6</p>
</div>
<div>
<img src="https://source.unsplash.com/ELv8fvulR0g/800x450">
<p>4/6</p>
</div>
<div>
<img src="https://source.unsplash.com/LoPGu6By90k/800x450">
<p>5/6</p>
</div>
<div>
<img src="https://source.unsplash.com/Ndz3w6MCeWc/800x450">
<p>6/6</p>
</div>
</div>
<button id="prev"><i class="fas fa-chevron-left fa-2x"></i></button>
<button id="next"><i class="fas fa-chevron-right fa-2x"></i></button>
</div>
</section>
Here is a solution looping through the carousels. All you need to do is to make sure your styles are added. There are styles based on the id of the carousels - that needs to be added for all of them or made universal.
Here is little bit revised answer, no need to declare the functions and variables several times inside the forLoop like it was before.
What this code does it selects all carousels with the class .img-carousel and loops through them. Adding functionality to each carousel and relative buttons (based on index). The core functionality is the same only now it is added dynamically.
const carousels = document.querySelectorAll('.img-carousel');
const prevBtn = document.querySelectorAll('.prev');
const nextBtn = document.querySelectorAll('.next');
let carsouselImages = document.querySelectorAll('.img-carousel div');
//Next Carousel
const nextCarousel = (carousel) => {
if(carsouselImages[carsouselImages.length - 1]) {
carousel.scrollTo(0, 0);
}
carousel.scrollBy(300, 0);
};
//Prev Carousel
const prevCarousel = (carousel) => {
if(carsouselImages[0]) {
carousel.scrollTo(4800,0);
}
carousel.scrollBy(-300, 0);
};
// Auto carousel
carousels.forEach((carousel, index)=>{
nextBtn[index].addEventListener('click', e => {
nextCarousel(carousel);
});
prevBtn[index].addEventListener('click', e => {
prevCarousel(carousel);
});
// Auto carousel
const auto = true; // Auto scroll
const intervalTime = 5000;
let sliderInterval;
let previousCall;
if (auto) {
sliderInterval = setInterval(()=>nextCarousel(carousel), intervalTime);
};
carousel.addEventListener('mouseover', (stopInterval) => {
clearInterval(sliderInterval);
});
carousel.addEventListener('mouseleave', (startInterval) => {
if (auto) {
sliderInterval = setInterval(()=>nextCarousel(carousel), intervalTime);
}
});
//for mobile events
carousel.addEventListener('touchstart', (stopIntervalT) => {
clearInterval(sliderInterval);
});
carousel.addEventListener('touchend', (startIntervalT) => {
if (auto) {
sliderInterval = setInterval(()=>nextCarousel(carousel), intervalTime);
}
});
//Debounce
window.addEventListener('resize', () => {
if (previousCall >= 0) {
clearTimeout(previousCall);
}
previousCall = setTimeout(() => {
carousel.scrollBy(-300, 0);
}, 200);
});
});
/** img-carousel **/
#imgages-carousel {
display: grid;
align-items: center;
justify-items: center;
padding: 40px 0px;
}
#imgages-carousel1 {
display: grid;
align-items: center;
justify-items: center;
padding: 40px 0px;
}
.img-carousel-container {
width: 800px;
position: relative;
}
.img-carousel {
display: flex;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
padding-bottom: 5px;
}
.img-carousel div {
flex: none;
scroll-snap-align: start;
width: 800px;
position: relative;
}
.img-carousel div img {
display: block;
width: 100%;
object-fit: cover;
}
.img-carousel div p {
position: absolute;
top: 0;
right: 10px;
background: rgba(0,0,0,0.5);
color: #fff;
padding: 5px;
border-radius: 10px;
}
.img-carousel-container button {
position: absolute;
top: calc(50% - 15px);
transform: translateY(-50%);
border: none;
background-color: rgba(255, 193, 7, 0.7);
color: #000;
cursor: pointer;
padding: 10px 15px;
border-radius: 50%;
outline: none;
opacity: 0;
transition: all ease-in-out 0.5s;
}
.prev {
left: 10px;
}
.next {
right: 10px;
}
.img-carousel-container:hover button {
opacity: 1;
}
.img-carousel-container button:hover {
background-color: #ffc107;
}
/** custom scrollbar **/
.img-carousel::-webkit-scrollbar {
width: 10px;
height: 10px;
}
.img-carousel::-webkit-scrollbar-thumb {
background: #ffc107;
border-radius: 10px;
}
.img-carousel::-webkit-scrollbar-track {
background: transparent;
}
.img-carousel-container:hover .img-carousel::-webkit-scrollbar-thumb {
visibility: visible;
}
#media screen and (max-width: 800px) {
.img-carousel-container {
width: 100%;
}
.img-carousel div {
width: 100%;
}
}
<!-- section images carousel -->
<section id="imgages-carousel">
<div class="img-carousel-container">
<div class="img-carousel">
<div>
<img src="https://source.unsplash.com/9Nok_iZEgLk/800x450">
<p>1/6</p>
</div>
<div>
<img src="https://source.unsplash.com/4v7ubW7jz1Q/800x450">
<p>2/6</p>
</div>
<div>
<img src="https://source.unsplash.com/rtCujH697DU/800x450">
<p>3/6</p>
</div>
<div>
<img src="https://source.unsplash.com/ELv8fvulR0g/800x450">
<p>4/6</p>
</div>
<div>
<img src="https://source.unsplash.com/LoPGu6By90k/800x450">
<p>5/6</p>
</div>
<div>
<img src="https://source.unsplash.com/Ndz3w6MCeWc/800x450">
<p>6/6</p>
</div>
</div>
<button class="prev"><i class="fas fa-chevron-left fa-2x"></i></button>
<button class="next"><i class="fas fa-chevron-right fa-2x"></i></button>
</div>
</section>
<section id="imgages-carousel1">
<div class="img-carousel-container">
<div class="img-carousel">
<div>
<img src="https://source.unsplash.com/9Nok_iZEgLk/800x450">
<p>1/6</p>
</div>
<div>
<img src="https://source.unsplash.com/4v7ubW7jz1Q/800x450">
<p>2/6</p>
</div>
<div>
<img src="https://source.unsplash.com/rtCujH697DU/800x450">
<p>3/6</p>
</div>
<div>
<img src="https://source.unsplash.com/ELv8fvulR0g/800x450">
<p>4/6</p>
</div>
<div>
<img src="https://source.unsplash.com/LoPGu6By90k/800x450">
<p>5/6</p>
</div>
<div>
<img src="https://source.unsplash.com/Ndz3w6MCeWc/800x450">
<p>6/6</p>
</div>
</div>
<button class="prev"><i class="fas fa-chevron-left fa-2x "></i></button>
<button class="next"><i class="fas fa-chevron-right fa-2x "></i></button>
</div>
</section>
I want to validate a multipage form using Js. Here is what I want the code to be, when I click 'next' i want it to validate whether the radio button has been checked or not. If not then display an alert popup. The multipage form already works but the problem here is I cannot validate the radio button on each page.
Hope anyone can help me solve this problem since I have been few days trying to solve this problem but I don't know how to do it. Thank you in advance.
HTML
<form class="form" action="" method="post">
<!-- Progress bar -->
<div class="progressbar">
<div class="progress" id="progress"></div>
<div class="progress-step progress-step-active" data-title="DEPARTMENT"></div>
<div class="progress-step" data-title="BLOCK"></div>
<div class="progress-step" data-title="TITLE"></div>
<div class="progress-step" data-title="DESCRIPTION"></div>
<div class="progress-step" data-title="DONE"></div>
</div>
<!-- start Steps 1-->
<div class="form-step form-step-active">
<br/>
<div class="page-header">
<h1>First, choose one department that is related to the complaint you are about to make.
<span style="color:#ffef96; font-size:15px;"><br/>
<p>Click any department for hint</p>
</span>
</h1>
<br/>
<div class="radio-toolbar">
<input type="radio" id="radio1" name="cdepartment" class="hint" value="GENERAL" required/>
<label for="radio1">GENERAL
<span class="hintclick"> e-Aduan UiTM used for
<span style="color:#ffef96">general complaints about UiTM.</span>
</span>
</label>
<input type="radio" id="radio2" name="cdepartment" class="hint" value="FACILITIES"/>
<label for="radio2">FACILITIES
<span class="hintclick">For
<span style="color:#ffef96">electrical, mechanical, telecommunications, event management.</span>
</span>
</label>
<input type="radio" id="radio3" name="cdepartment" class="hint" value="ICT"/>
<label for="radio3">ICT
<span class="hintclick">e-Aduan ICT used for
<span style="color:#ffef96">ICT complaints </span>
</label>
</div>
<br/>
</div><!-- page header-->
<div class="width-50 ml-auto" >
NEXT
</div>
</div>
<!-- end Steps 1 -->
<!-- start Steps 2 -->
<div class="form-step">
<br/>
<div class="page-header">
<h1>Second, which block do you wish to complaint about?</h1>
<br/>
<div class="radio-toolbar">
<div class="grid-container">
<?php
$count=4;
$sql="SELECT * FROM `block`";
$result=mysqli_query($connection,$sql);
while($std=mysqli_fetch_array($result))
{
?>
<input type="radio" id="<?php echo $std['bid'];?>" name="cblock" value="<?php echo $std['blockname'];?>" required/>
<label for="<?php echo $std['bid'];?>"><?php echo $std['blockname'];?></label>
<br/>
<?php }?>
</div>
</div>
</div> <!-- page header-->
<div class="btns-group width-50 ml-auto">
PREVIOUS
NEXT
</div>
</div>
<!-- end Steps 2 -->
<!-- start Steps 3 -->
<div class="form-step">
<br/>
<div class="page-header">
<h1>Third, pick a title or topic
<span style="color:#ffef96; font-size:15px;"><br/>
<p>If your related toppic is not listed, please fill in below text box instead.</p>
</span>
</h1>
<br/>
<div class="radio-toolbar">
<input type="radio" id="radioApple" name="radioFruit" value="apple" required/>
<label for="radioApple">Apple</label>
<input type="radio" id="radioBanana" name="radioFruit" value="banana"/>
<label for="radioBanana">Banana</label>
<input type="radio" id="radioOrange" name="radioFruit" value="orange"/>
<label for="radioOrange">Orange</label>
</div>
<div class="input-group">
<textarea type="text" class="form-control" row="5" name="cdescription" placeholder="Write here.." required/></textarea>
</div>
<br/>
</div>
<div class="btns-group width-50 ml-auto">
PREVIOUS
NEXT
</div>
</div>
<!-- end Steps 3 -->
<!-- start Steps 4 -->
<div class="form-step">
<div class="page-header">
<h1>Lastly, state your description regarding the complaint made
<span style="color:#ffef96; font-size:15px;"><br/>
<p> Below box you can write any notes about the complaint so the staff can help to understand</p>
</span>
</h1>
<br/>
<div class="input-group">
<textarea type="text" class="form-control" row="5" name="cdescription" placeholder="Write here.." required/></textarea>
</div>
</div>
<div class="btns-group width-50 ml-auto">
PREVIOUS
<button class="btn" type="submit" name="submit">SUBMIT</button>
</div>
</div>
<!-- end Steps 4 -->
<!-- start Steps 5 -->
<div class="form-step">
<div class="page-header">
<h1>THANK YOU <br/>
YOU CAN SEE RECENT COMPLAINT ON YOUR HOMEPAGE
</h1>
</div>
<!-- end Steps 5 -->
</form>
CSS
:root {
--primary-color: rgb(165, 121, 64);
}
*,
*::before,
*::after {
box-sizing: border-box;
}
.width-50 {
width: 30%;
}
.ml-auto {
margin-left: auto;
}
/* Progressbar */
.progressbar {
position: relative;
display: flex;
justify-content: space-between;
counter-reset: step;
margin: 2rem 4rem;
}
.progressbar::before,
.progress {
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%);
height: 4px;
width: 100%;
background-color: #dcdcdc;
z-index: -1;
}
.progress {
background-color: var(--primary-color);
width: 0%;
transition: 0.3s;
}
.progress-step {
width: 2.1875rem;
height: 2.1875rem;
background-color: #dcdcdc;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.progress-step::before {
counter-increment: step;
content: counter(step);
}
.progress-step::after {
content: attr(data-title);
position: absolute;
top: calc(100% + 0.5rem);
font-size: 0.85rem;
color: #666;
}
.progress-step-active {
background-color: var(--primary-color);
color: #f3f3f3;
}
/* Form */
.form {
width: 80%;
margin: 30px auto;
border: 1px solid #ccc;
border-radius: 0.35rem;
padding: 1.5rem;
box-shadow:
4px 4px 4px 0px #d1d9e6 inset,
-4px -4px 4px 0px #ffffff inset;
}
.form-step {
display: none;
transform-origin: top;
animation: animate 0.5s;
}
.form-step-active {
display: block;
}
.input-group {
margin: 2rem 0;
}
#keyframes animate {
from {
transform: scale(1, 0);
opacity: 0;
}
to {
transform: scale(1, 1);
opacity: 1;
}
}
.row{
height:100%;
width: 50px;
}
/* Button */
.btns-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
}
.btn {
padding: 16px;
display: block;
text-decoration: none;
background-color: rgba(0, 0, 0, 0.2);
color: #f3f3f3;
text-align: center;
border-radius: 0.25rem;
cursor: pointer;
transition: 0.3s;
border-radius: 15px 25px;
box-shadow: 5px 8px 10px #888888;
}
.btn:hover {
box-shadow: 0 0 0 2px #fff, 0 0 0 3px ;
color: #f3f3f3;
}
/* end progress bar*/
.radio-toolbar {
margin-left: 10px;
text-align: center;
}
.radio-toolbar input[type="radio"] {
opacity: 0;
position: fixed;
width: 0;
}
.radio-toolbar label {
display: inline-block;
background-color: #f0efef;
padding: 10px;
font-size: 18px;
border: 3px solid #444;
border-radius: 4px;
width: 300px;
height:auto;
}
.radio-toolbar label:hover {
background-color: #c2d4dd;
cursor: pointer;
}
.radio-toolbar input[type="radio"]:focus + label {
border: 2px dashed #f0efef;
}
.radio-toolbar input[type="radio"]:checked + label {
background-color:#a57940;
border-color: #c2d4dd;
}
/* end radio button*/
.hint, label .hintclick {
display: none;
opacity: 0;
}
.hint:checked+ label .hintclick {
display: block;
opacity: 1;
font-size: 17px;
color: white;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto auto auto auto auto auto ;
}
.grid-container > label {
width: 100%;
}
JS
const prevBtns = document.querySelectorAll(".btn-prev");
const nextBtns = document.querySelectorAll(".btn-next");
const progress = document.getElementById("progress");
const formSteps = document.querySelectorAll(".form-step");
const progressSteps = document.querySelectorAll(".progress-step");
let formStepsNum = 0;
nextBtns.forEach((btn) => {
btn.addEventListener("click", () => {
formStepsNum++;
updateFormSteps();
updateProgressbar();
});
});
prevBtns.forEach((btn) => {
btn.addEventListener("click", () => {
formStepsNum--;
updateFormSteps();
updateProgressbar();
});
});
function updateFormSteps() {
formSteps.forEach((formStep) => {
formStep.classList.contains("form-step-active") &&
formStep.classList.remove("form-step-active");
});
formSteps[formStepsNum].classList.add("form-step-active");
}
function updateProgressbar() {
progressSteps.forEach((progressStep, idx) => {
if (idx < formStepsNum + 1) {
progressStep.classList.add("progress-step-active");
} else {
progressStep.classList.remove("progress-step-active");
}
});
const progressActive = document.querySelectorAll(".progress-step-active");
progress.style.width =
((progressActive.length - 1) / (progressSteps.length - 1)) * 100 + "%";
}
I have a carousel created on my own and I want to know how I can do that with JS. I know how I can do it by CSS but the problem is the change of the photos. Why change the src so that is my problem. If anyone knows how can I do it in JS it will be alright. Maybe changing the classes or something.
let imagenEnsaladas = document.getElementById("photosEnsaladas");
let buttonNext = document.getElementById("nextPhoto");
let carruselLi = document.getElementById("carruselLista").getElementsByTagName("li");
let positionCarrusel = 0;
let carruselPhotos = [
"assets/carrusel/ens.-ventresca-300-x300-300x300.png",
"assets/carrusel/ensalada bacalao200x200.png",
"assets/carrusel/ensalada-alcachofas-300x-300-300x300.jpg",
"assets/carrusel/ENsalada-yemas-300x300.png",
"assets/carrusel/ensalada-de-queso-cabra300x300-300x300.png",
];
window.onload = function playFoto() {
carruselLi[positionCarrusel].style.backgroundColor = "red";
if (positionCarrusel >= carruselPhotos.length) {
positionCarrusel++;
} else if (positionCarrusel > carruselPhotos.length) {}
imagenEnsaladas.src = carruselPhotos[positionCarrusel];
buttonNext.addEventListener("click", clickNextFoto);
function clickNextFoto() {
if (positionCarrusel >= carruselPhotos.length - 1) {
positionCarrusel = 0;
} else {
positionCarrusel++;
console.log(positionCarrusel);
}
imagenEnsaladas.src = carruselPhotos[positionCarrusel];
for (let i = 0; i < carruselLi.length; i++) {
if (i === positionCarrusel) {
carruselLi[positionCarrusel].style.backgroundColor = "red";
} else {
carruselLi[i].style.backgroundColor = "#1a1d20";
}
}
}
};
.textoNovedades {
margin: 0% 5% 0% 5%;
line-height: 30px;
}
.tablaNovedadesEnsalada {
display: flex;
flex-direction: row-reverse;
background: #1a1d20;
color: rgb(246, 225, 185);
justify-content: center;
align-items: center;
padding: 2% 2% 2% 2%;
width: 100%;
}
.carruselEnsaladas {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.nextPhoto {
background-image: url(assets/carrusel/siguiente.jpg);
background-size: auto;
background-position-x: 54%;
border-radius: 12px;
background-position-y: 47%;
width: 60%;
height: 9vh;
margin: 7%;
border: 3px;
box-shadow: 3px 3px 3px #999;
}
.tablaNovedadesEnsalada ul {
list-style: none;
}
<section class="tablaNovedadesEnsalada">
<div class="carruselEnsaladas">
<img src="" alt="photos carrusel" id="photosEnsaladas" class="photosEnsaladas">
<button id="nextPhoto" class="nextPhoto">
</button>
</div>
<p class="textoNovedades">
<ul id="carruselLista">
<li value="0"> ensalada de laminas de bacalao</li>
<li value="1"> Ensalada de alcachofas</li>
<li value="2"> Ensalada de yemas</li>
<li value="3">ensalada de ventresca</li>
<li value="4">Ensalada queso cabra</li>
</ul>
</p>
</section>
I have multiple elements with the same class name and want them to perform the same javascript function but output their unique "inner.Text" specific
to the element i clicked. Right Now i know i need an [index] and a loop
but I just don't know how to implement that at the moment since im a novice in javascript.
spent 3 hours trying to figure it out
const myButton = document.querySelectorAll('.clipboard-icon');
const myInp = document.querySelectorAll('.snippetcode');
myButton.forEach(ree =>
ree.addEventListener('click', copyElementText));
function copyElementText(id) {
var text = myInp.innerText;
var elem = document.createElement("textarea");
document.body.appendChild(elem);
elem.value = text;
elem.select();
document.execCommand("copy");
document.body.removeChild(elem);
console.log('clicked');
}
console.log(myButton);
console.log(myInp);
/*everything works fine if the script was changed to affect only ONE class name but I cant figure out how to make them work for more than one
*/
.snippet1 {
border: solid rgb(55, 63, 184) 3px;
}
.snippet_holder {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
padding: 0 3.5rem;
margin: 0 0 1rem 0;
position: relative;
}
.buttons {
width: 170px;
height: 40px;
border: 0;
padding: 0;
font-size: 1rem;
color: #fff;
border-radius: 10px;
}
.snippet_holder:hover .clipboard-icon {
display: block;
position: absolute;
top: 15px;
right: 65px;
background: rgb(51, 153, 136);
margin: 0;
width: 30px;
padding: 0;
height: 30px;
}
.clipboard-icon {
display: none;
}
.clipboard-icon img {
width: inherit;
height: inherit;
position: relative;
}
.clipboard-icon pre {
display: none;
}
.snippetcode1 {
display: none;
}
.button1 {
-webkit-animation: rainbow 6.5s ease infinite;
animation: rainbow 6.5s ease infinite;
background-image: linear-gradient(124deg, #ff470f, #ff3860, #b86bff, #3273dc);
background-size: 800% 800%;
}
#keyframes rainbow {
0% {
background-position: 1% 80%;
}
50% {
background-position: 99% 20%;
}
100% {
background-position: 1% 80%;
}
0% {
background-position: 1% 80%;
}
50% {
background-position: 99% 20%;
}
100% {
background-position: 1% 80%;
}
}
main {
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<html>
<body>
<main>
<div class="snippet_holder snippet_holder1">
<div class="clipboard-icon">
<pre>
<code class= "snippetcode">
1st class text copieddddd
</code>
</pre>
<img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png">
</div>
<button type="button" class="buttons button1">button</button>
</div>
<div class="snippet_holder snippet_holder1">
<div class="clipboard-icon">
<pre>
<code class= "snippetcode">
22222nddd class text copieddddd
</code>
</pre>
<img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png">
</div>
<button type="button" class="buttons button1">button</button>
</div>
<div class="snippet_holder snippet_holder1">
<div class="clipboard-icon">
<pre>
<code class= "snippetcode">
3rd class text copieddddd
</code>
</pre>
<img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png">
</div>
<button type="button" class="buttons button1">button</button>
</div>
<div class="snippet_holder snippet_holder1">
<div class="clipboard-icon">
<pre>
<code class= "snippetcode">
4thhhhhhhhclass text copieddddd
</code>
</pre>
<img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png">
</div>
<button type="button" class="buttons button1">button</button>
</div>
</main>
</body>
</html>
You've to query the .snippetcode related to the button pressed, so, it makes no sense to query the nodeList myInp, you can access to the right element using the currentTarget provided in the event object...
function copyElementText(event) {
var text = event.currentTarget.querySelector('.snippetcode').innerText;
var elem = document.createElement("textarea");
document.body.appendChild(elem);
elem.value = text;
elem.select();
document.execCommand("copy");
document.body.removeChild(elem);
console.log('clicked');
}