I want to make a stepper component - javascript

I want to hide prev btn and the other words
But I want to show them and prev btn one by one when I press next button and display finish btn i am on the latest word.
The buttons, prev, next and finish do the things which are not the same when I have finish button I want to post the words.
I tried many time but not worked. Here is my code that I've tried:
function nextBtn() {
var itemOne = document.getElementById("step-1");
var itemTwo = document.getElementById("step-2");
var itemThree = document.getElementById("step-3");
var itemFour = document.getElementById("step-4");
var prevBtn = document.getElementById("prevBtn");
var nextBtn = document.getElementById("nextBtn");
if (itemOne.style.display == "block" && itemTwo.style.display == "none" && prevBtn.style.display == "none") {
itemOne.style.display = "none";
itemTwo.style.display = "block";
prevBtn.style.display = "block";
}
else {
console.log('Xatolik ishlamayapti');
}
}
#step-1 {
display: block;
}
#step-2 {
display: none;
}
#step-3 {
display: none;
}
#step-4 {
display: none;
}
#prevBtn {
display: none;
}
#nextBtn {
display: block;
}
<div class="step-container">
<div id="step-1">Hello</div>
<div id="step-2">Hi</div>
<div id="step-3">Salom</div>
<div id="step-4">Molas</div>
<button id="prevBtn" #click="prevBtn()">back</button>
<button id="nextBtn" #click="nextBtn()">next</button>
</div>
What's wrong at above link.
Thank you in advance.

The main problem with your approach is that itemOne.style.display == "block" will not evaluate to true because it doesn't consider that the node has some css set externally.
It would make more sense to use html classes for your step divs so that you can select them all at once with querySelectorAll().
The logic would be easier to manage if you use a variable to track which number step is the current step.
Then you can just increase and decrease the variable each time you click on either the previous or next buttons.
const allSteps = document.querySelectorAll('.step')
const totalSteps = allSteps.length
const prevButton = document.querySelector('#prevBtn')
const nextButton = document.querySelector('#nextBtn')
const finishButton = document.querySelector('#finishBtn')
// Hide everything except for #step-1
document
.querySelectorAll(".step:not(#step-1)")
.forEach(step => (step.style.display = "none"))
// Hide the prev button
prevButton.style.display = 'none'
// Hide the finish button
finishButton.style.display = 'none'
let currentStep = 1
function nextBtn() {
currentStep++;
refreshDisplay()
}
function prevBtn() {
currentStep--;
refreshDisplay()
}
function refreshDisplay() {
// hide every step
allSteps.forEach(step => (step.style.display = "none"))
// show only the currentStep
document.querySelector(`#step-${currentStep}`).style.display = 'block'
// hide or show the prevButton
if (currentStep === 1) {
prevButton.style.display = 'none'
} else {
prevButton.style.display = 'inline-block'
}
// hide or show nextButton & finish button
if (currentStep === totalSteps) {
nextButton.style.display = 'none'
finishButton.style.display = 'inline-block'
} else {
nextButton.style.display = 'inline-block'
finishButton.style.display = 'none'
}
}
function finish() {
console.log('you are finished')
}
<div class="step-container">
<div class="step" id="step-1">Hello</div>
<div class="step" id="step-2">Hi</div>
<div class="step" id="step-3">Salom</div>
<div class="step" id="step-4">Molas</div>
<button id="prevBtn" onclick="prevBtn()">back</button>
<button id="nextBtn" onclick="nextBtn()">next</button>
<button id="finishBtn" onclick="finish()">finish</button>
</div>

Something like this?
var activeButton = 0;
function next() {
document.getElementById(activeButton).classList.remove('active');
activeButton++;
document.getElementById(activeButton).classList.add('active');
}
function previous() {
document.getElementById(activeButton).classList.remove('active');
activeButton--;
document.getElementById(activeButton).classList.add('active');
}
.step {
display: none;
}
.active {
display: inline;
}
<button id="0" class="active step">First</button>
<button id="1" class="step">Second</button>
<button id="2" class="step">Third</button>
<button id="3" class="step">Fourth</button>
<button id="4" class="step">Fifth</button>
<button id="5" class="step">Sixth</button>
<button id="6" class="step">Seventh</button>
<hr>
<button id="next" onclick="next()">Next</button>
<button id="next" onclick="previous()">Previous</button>

Related

Changing class of button and display of div with JavaScript

I have JavaScript to show/hide div on click. Inside that div are more buttons to show/hide PNGs.
I want the clicked button to have a bottom border line until another button in that div is clicked.
I have achieved this but each time I click on a button in the shown div the bottom border line stays on the button when I click the next button.
I've spent hours trying to fix this. please help
let wildCard = document.querySelectorAll(".element-select-container button");
for (let button of wildCard) {
button.addEventListener('click', (e) => {
const et = e.target;
const active = document.querySelector(".active");
let redline = (".redline");
if (active) {
active.classList.remove("redline");
active.classList.remove("active");
}
et.classList.add("active");
et.classList.add("redline");
let allContent = document.querySelectorAll('.button-wrapper');
for (let content of allContent) {
if(content.getAttribute('data-e') === button.getAttribute('data-e')) {
content.style.display = "block";
}
else {
content.style.display = "none";
}
}
});
}
HTML
<div class="element-select-container">
<button id="but81" class="but81 redline" data-e="81" type="button" name="">Doors</button>
<button id="but82" class="but82" data-e="82" type="button" name="">Windows</button>
<button id="but83" class="but83" data-e="83" type="button" name="">Facia</button>
<button id="but84" class="but84" data-e="84" type="button" name="">Guttering</button>
<button id="but85" class="but85" data-e="85" type="button" name="">Garage</button>
<button id="but86" class="but86" data-e="86" type="button" name="">Steps</button>
</div>
CSS
.redline {
border-bottom: 2px solid red;
}
The issue is, on first load, the first button is redline but not active - so, when you press a different button, the code to remove redline from active doesn't find active so redline isn't removed
simple fix
const active = document.querySelector(".active,.redline");
As follows
let wildCard = document.querySelectorAll(".element-select-container button");
for (let button of wildCard) {
button.addEventListener('click', (e) => {
const et = e.target;
const active = document.querySelector(".active,.redline");
if (active) {
active.classList.remove("redline");
active.classList.remove("active");
}
et.classList.add("active");
et.classList.add("redline");
let allContent = document.querySelectorAll('.button-wrapper');
for (let content of allContent) {
if(content.getAttribute('data-e') === button.getAttribute('data-e')) {
content.style.display = "block";
}
else {
content.style.display = "none";
}
}
});
}
.redline {
border-bottom: 2px solid red;
}
<div class="element-select-container">
<button id="but81" class="but81 redline" data-e="81" type="button" name="">Doors</button>
<button id="but82" class="but82" data-e="82" type="button" name="">Windows</button>
<button id="but83" class="but83" data-e="83" type="button" name="">Facia</button>
<button id="but84" class="but84" data-e="84" type="button" name="">Guttering</button>
<button id="but85" class="but85" data-e="85" type="button" name="">Garage</button>
<button id="but86" class="but86" data-e="86" type="button" name="">Steps</button>
</div>

JavaScript Function

Hello everybody I have this code that I have made alone.
function appearafter() {
document.getElementById("buttonappear").style.display = "block";
document.getElementById("button").style.display = "block";
document.getElementById("hinzufuegen").style.display = "none";
function myFunction() {
var itm = document.getElementById("myList2").lastChild;
var cln = itm.cloneNode(true);
document.getElementById("myList1").appendChild(cln);
}
function allFunction() {
myFunction();
appearafter();
}
#button {
display: none;
}
#buttonappear {
display: none;
}
#test {
width: 300px;
height: 300px;
background-color: red;
}
<!DOCTYPE html>
<html>
<body>
<button id="hinzufuegen" onclick="allFunction()">ADD</button>
<div id="myList1">
<button id="button" onclick="">DELETE</button>
<div id="myList2">
<div id="test">
</div>
</div>
</div>
<button onclick="allFunction()" id="buttonappear">ADD</button>
</body>
</html>
What I want to make is that the red square whenever you are clicking on the ADD button it will be a clone and when you click on the DELETED button that the clone is deleted. Can somebody help me, please?
In addition to missing } as was mentioned in the comments, there was a not-so-obvious problem with finding the <div> to clone. The lastChild was actually a text node containing the \n (newline), after the <div>. It's better to search for <div> by tag:
var itm = document
.getElementById('myList2')
.getElementsByTagName('div')[0];
Since there's only one <div> we can use the zero index to find this first and only one.
And for delete function you can use a similar approach and get the last <div> and remove it.
function appearafter() {
document.getElementById("buttonappear").style.display = "block";
document.getElementById("button").style.display = "block";
document.getElementById("hinzufuegen").style.display = "none";
}
function myFunction() {
var itm = document.getElementById("myList2").getElementsByTagName("div")[0];
var cln = itm.cloneNode(true);
document.getElementById("myList1").appendChild(cln);
}
function deleteFunction() {
var list1 = document.getElementById("myList1");
var divs = Array.from(list1.getElementsByTagName("div"));
// If the number of divs is 3, it means we're removing the last
// cloned div, hide the delete button.
if (divs.length === 3) {
document.getElementById("button").style.display = "none";
}
var lastDivToDelete = divs[divs.length - 1];
list1.removeChild(lastDivToDelete);
}
function allFunction() {
myFunction();
appearafter();
}
#button {
display: none;
}
#buttonappear {
display: none;
}
#test {
/* make it smaller so it's easier to show in a snippet */
width: 30px;
height: 30px;
background-color: red;
}
<button id="hinzufuegen" onclick="allFunction()">ADD</button>
<div id="myList1">
<button id="button" onclick="deleteFunction()">DELETE</button>
<div id="myList2">
<div id="test"></div>
</div>
</div>
<button onclick="allFunction()" id="buttonappear">ADD</button>

button toggle display show hide

I want to show-hide the display of these layers with a button click. I can't figure out how to do it with 2 buttons, and 2 divs...
Html:
<div id="first">This is the FIRST div</div>
<div id="second">This is the SECOND div</div>
<button id="toggle">Show first div and hide second div</button>
<button id="toggletoo">Show second div and hide first div</button>
Css:
#first {
display: none;
}
#second {
display: none;
}
Js:
const targetDiv = document.getElementById("first");
const btn = document.getElementById("toggle");
btn.onclick = function () {
if (targetDiv.style.display !== "none") {
targetDiv.style.display = "block";
} else {
targetDiv.style.display = "none";
}
}
https://codepen.io/MaaikeNij/pen/YzrgbQw
Try with the following code:
#first{
display: block; /* <--- change */
}
#second {
display: none;
}
const firstDiv = document.getElementById("first");
const secondDiv = document.getElementById("second");
document.getElementById("toggle").onclick = function () {
if (firstDiv.style.display === "none") {
firstDiv.style.display = "block";
secondDiv.style.display = "none";
} else {
firstDiv.style.display = "none";
secondDiv.style.display = "block";
}
}
There's lots of ways to do this. One common way I've seen in various templates is to add and remove classes. Another way is to call the function from the button's onclick attribute. But my favorite is to write a function that requires no editing of the div HTML because I don't want to interfere with the HTML guy's work, I just want to put functioning code in there. (BTW, I am positive there is a more elegant way to write this, but here ya go!)
const firstDiv = document.querySelector("#first");
const secondDiv = document.querySelector("#second");
const firstButt = document.querySelector("#toggle");
const secondButt = document.querySelector("#toggletoo");
firstButt.addEventListener("click",toggleDivShowHide);
secondButt.addEventListener("click",toggleDivShowHide);
function toggleDivShowHide() {
if (firstDiv.style.display !== "none") {
firstDiv.style.display = "none";
secondDiv.style.display = "block";
} else {
firstDiv.style.display = "block";
secondDiv.style.display = "none";
}
}
You're saying "if the first div is set to none, then set it to block and set the second div to none. Otherwise, do the opposite."
I tried something different, this is working :)))
<div id="first" style="display:none;"> This is the FIRST div</div>
<div id="second" style="display:none;"> This is the SECONDdiv</div>
<input type="button" name="answer" value="Show first div and hide second div" onclick="showDivOne()" />
<input type="button" name="answer" value="Show second div and hide first div" onclick="showDivTwo()" />
function showDivOne() {
document.getElementById('first').style.display = "block";
document.getElementById('second').style.display = "none";
}
function showDivTwo() {
document.getElementById('second').style.display = "block";
document.getElementById('first').style.display = "none";
}
https://codepen.io/MaaikeNij/pen/vYeMGyN
Correction: you should add event Listener for both toggle & toggletoo.
Solution: solution with reusable code.
const Toggles = document.querySelectorAll('.toggle');
const Hides = document.querySelectorAll('.hide');
Toggles.forEach((el) => {
el.addEventListener("click", (e) => {
Hides.forEach((el) => {
el.parentElement.firstElementChild.classList.add('hide');
});
e.target.parentElement.firstElementChild.classList.toggle('hide');
});
})
.hide {
display: none;
}
<div>
<div class="hide">This is the FIRST div</div>
<button class="toggle">Show first div and hide first div</button>
</div>
<div>
<div class="hide">This is the SECOND div</div>
<button class="toggle">Show second div and hide first div</button>
</div>
<div>
<div class="hide">This is the Third div</div>
<button class="toggle">Show Third div and hide first div</button>
</div>
<div>
<div class="hide">This is the Fourth div</div>
<button class="toggle">Show Fourth div and hide first div</button>
</div>
For precisely such cases, javascript has the toggle function. I rewrite your code a little bit.
const btns = document.querySelectorAll(".toggleBtn");
btns.forEach(b => {
b.onclick = function (e) {
reset();
console.log(e.target.getAttribute('data-target'))
const target = e.target.getAttribute('data-target');
const t = document.querySelector('#' + target);
t.classList.toggle('hide');
}
});
function reset() {
const divs = document.querySelectorAll('.out');
divs.forEach(d => d.classList.add('hide'))
}
.hide {
display: none;
}
<div id="first" class="out hide">This is the FIRST div</div>
<div id="second" class="out hide">This is the SECOND div</div>
<button class="toggleBtn" data-target="first">Show first div and hide second div</button>
<button class="toggleBtn" data-target="second">Show second div and hide first div</button>

Changing color of only button that was clicked

I mean I want to change CSS properties of only the button that I've clicked and at the same time set other buttons to previous color. Hope I explained my problem clear
for(let i = 0; i < categoryBtns.length; i++) {
categoryBtns[i].addEventListener('click', function() {
let attr = this.getAttribute('id');
if(categoryBtns[i - 1].id != attr || categoryBtns[i + 1].id != attr) {
log([i]);
console.log('works');
this.style.backgroundColor = '#000000';
} else {
log('no');
}
})
}
I have also code that shows only divs that have current category. Should I code buttons in the same time when divs are showing and hiding?
$(document).ready(function() {
$('.category-item').click(function() {
let category = $(this).attr('id');
if(category == 'all') {
$('.prod_item').addClass('hide');
setTimeout(function() {
$('.prod_item').removeClass('hide');
}, 300);
} else {
$('.prod_item').addClass('hide');
setTimeout(function() {
$('.' + category).removeClass('hide');
}, 300);
}
});
});
I hope that I understood what you want correctly
const btns = document.querySelectorAll('.btn')
btns.forEach(btn => {
btn.addEventListener('click', () => {
btns.forEach(b => {
(b.classList.contains("active"))?
b.classList.remove("active"):true
});
btn.classList.add("active")
});
})
.active {
background-color: blue;
}
<button class = "btn">Click Me</button>
<button class = "btn">Click Me</button>
<button class = "btn active">Click Me</button>
<button class = "btn">Click Me</button>
<button class = "btn">Click Me</button>
use Array.forEach() to loop through the buttons and add/remove a styled class:
const btns = document.querySelector(".buttons");
const arr = Array.prototype.slice.call(btns.children, 0);
arr.forEach((el) => {
el.addEventListener("click", () => {
arr.forEach((el2) => {
el2.classList -= "active";
});
el.classList.toggle("active");
});
});
button.active {
color: red;
}
<div class="buttons">
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
<button>Button 4</button>
<button>Button 5</button>
</div>
You can add a class for the button clicked state, and a default color for all buttons inside divs with class category-item. One javascript function removes the clicked class from all buttons while the other adds it to a specific button.
$(document).ready(function() {
$('.category-item input[type="button"]').click(function() {
removeClickedClass();
addClickedClass(this.id);
});
function removeClickedClass() {
$('.category-item input[type="button"]').removeClass("btnColorClicked");
}
function addClickedClass(elemID) {
let id = "#" + elemID;
$(id).addClass("btnColorClicked");
}
});
.category-item input[type="button"] {
font-weight: bold;
background-color: #4CAF50;
cursor: pointer;
}
.btnColorClicked {
background-color: #0099ff !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="category-item">
<input type="button" class="" id="1" value="hi" />
</div>
<div class="category-item">
<input type="button" class="" id="2" value="there" />
</div>
<div class="category-item">
<input type="button" class="" id="3" value="hey" />
</div>
Here is an answer for your first block without jQuery, but you should get it.
function colorizeButtons(id) {
for (let i = 0; i < categoryBtns.length; i += 1) {
const buttonId = categoryBtns[i].getAttribute('id');
// Clicked button
if (buttonId === id) {
// Set the clicked color button
} else {
// Set other buttons color
}
}
}
for (let i = 0; i < categoryBtns.length; i++) {
categoryBtns[i].addEventListener('click', function() {
let attr = this.getAttribute('id');
colorizeButtons(attr)
});
}
here is an example with jquery btns are the list of buttons elements and when clicked they turn red if click again they turn white
$(btns).on("click",function(){
if(!this.clicked){
this.clicked = true;
$(this).css("background-color", "red");
}
else{
this.clicked = false;
$(this).css("background-color", "white");
}
});

With JS, open and close buttons work, but escape always tries to close the last modal [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I've got this working with my buttons, but I can't figure out how to make the escape key work with the correct modal. It always 'closes' the last modal, no matter how many I have.
It's all within my for loop, so I don't understand why thisModal tracks to the correct one for the buttons, but not for the document.onkeydown function.
Also, no comments about using jQuery please :).
const modalToggle = document.querySelectorAll(".button"),
modal = document.querySelectorAll(".modal"),
closeButton = document.querySelectorAll(".close");
if (modalToggle) {
for (i = 0; i < modalToggle.length; i++) {
let thisToggle = modalToggle[i];
let thisModal = modal[i];
let thisClose = closeButton[i];
thisToggle.addEventListener("click", () => openModal(thisModal));
thisClose.addEventListener("click", () => closeModal(thisModal));
document.onkeydown = (e) => {
if (e.keyCode == 27) {
console.log(thisModal); // Is always the LAST modal... why?
closeModal(thisModal);
}
}
};
}
function openModal(el) {
el.style.display = "block";
}
function closeModal(el) {
el.style.display = "none";
}
.modal {
display: none;
background: lightgray;
border: 1px solid black;
width: 50%;
height: 100px;
}
<button class="button">One</button>
<button class="button">Two</button>
<button class="button">Three</button>
<div class="modal">ONE
<button class="close">Close</button>
</div>
<div class="modal">TWO
<button class="close">Close</button>
</div>
<div class="modal">Three
<button class="close">Close</button>
</div>
It was because each run of the for loop was overriding the previous bind. Try this, pressing esc closes all modals
const modalToggle = document.querySelectorAll(".button"),
modal = document.querySelectorAll(".modal"),
closeButton = document.querySelectorAll(".close");
if (modalToggle) {
for (i = 0; i < modalToggle.length; i++) {
let thisToggle = modalToggle[i];
let thisModal = modal[i];
let thisClose = closeButton[i];
thisToggle.addEventListener("click", () => openModal(thisModal));
thisClose.addEventListener("click", () => closeModal(thisModal));
};
document.onkeydown = (e) => {
if (e.keyCode == 27) {
for (i = 0; i < modalToggle.length; i++) {
let thisToggle = modalToggle[i];
let thisModal = modal[i];
let thisClose = closeButton[i];
console.log(thisModal); // Is always the LAST modal... why?
closeModal(thisModal);
};
}
}
}
function openModal(el) {
el.style.display = "block";
}
function closeModal(el) {
el.style.display = "none";
}
.modal {
display: none;
background: lightgray;
border: 1px solid black;
width: 50%;
height: 100px;
}
<button class="button">One</button>
<button class="button">Two</button>
<button class="button">Three</button>
<div class="modal">ONE
<button class="close">Close</button>
</div>
<div class="modal">TWO
<button class="close">Close</button>
</div>
<div class="modal">Three
<button class="close">Close</button>
</div>

Categories