Show a new form after clicking - javascript

I'm trying to realize a 3-step form system. Basically, when you load the page, the first step of the form is displayed. Once completed and after the user has clicked on the "next step" button, form number 2 appears, and so on.
But I'm stuck on JS code. I do not know how to go about it.
My logic was simply to put parent elements (.step) in display: none, and after the user clicked the button, make the next step in display: block. What do you think ?
(This is obviously a prototype and divs will be replaced by )
My codepen
HTML:
<div class="steps">
<div class="step step1">
Step 1/3
</div>
<div class="step step2">
Step 2/3
</div>
<div class="step step3">
Step 3/3
</div>
</div>
<button type="submit" class="btn next-step">Next step</button>
CSS:
.step {
display: none;
&.is-active {
display: block;
}
}
Javascript (ES5/6), not jQuery
const btnStep = document.querySelector('.next-step');
const steps = [].slice.call(document.querySelector('.steps').children);
btnStep.addEventListener('click', () =>
steps.forEach(step => {
// if (step.classList.contains('is-active')) {
// step.classList.remove('is-active')
// }
step.nextElementSibling.classList.add('is-active')
})
)
Thanks so much.

I think you should use a step counter. You should count the steps in js and put them in a variable called something like "numberOfSteps" so you can always add more steps. Then make two methods, one for incrementing and one for decrementing and change the counter accordingly. And then if (stepCounter === numberOfSteps), show the submit button.
Try to put all the logic in different functions and call them with the corresponding event handler (on click, etc.)
Hope this gets you on your way. Good luck!

Im not sure what kind of behavior u want after the third step
But here is my solution tho im not sure this is exactly how u want it to work
https://jsfiddle.net/b5kvksau/
var x = 1;
function ini() {
if (x == 1) {
document.querySelector(".step1").classList.toggle("is-active");
document.querySelector(".step2").classList.toggle("is-active");
x++;
console.log(x);
} else if (x == 2) {
document.querySelector(".step2").classList.toggle("is-active");
document.querySelector(".step3").classList.toggle("is-active");
x++;
console.log(x);
} else if (x == 3) {
document.querySelector(".step3").classList.toggle("is-active");
document.querySelector(".hello-world").innerHTML = "All done!";
x = 5; // Add your desired execution after 3/3 steps of the form are completed
}
}
at "x=5" just add ur code for when the form is done, if its gonna be a redirect or whatever
Its very simple but the simpler it is the easier it is to debug and implement

i HAd a little time so i came to an easy solution here http://codepen.io/AAnkudovich/pen/BWbaEp
on button click call the function an add active class to first element as it will be the starting point
<div class="steps">
<div class=" is-active step1">
Step 1/3
</div>
<div class="step step2">
Step 2/3
</div>
<div class="step step3">
Step 3/3
</div>
</div>
<button type="submit" class="btn next-step" onclick="stepnext()">Next step</button>
and this is the function to go into your js
function stepnext() {
document.getElementsByClassName('is-active')[0].classList.add('step');
var elem = document.getElementsByClassName('is-active');
elem[0].nextSibling.nextSibling.classList.add('is-active');
document.getElementsByClassName('is-active')[0].classList.remove('is-active');
}

Related

document.getElementById issues with for loop

My code fetches data from the backend API
for (var i = 0; i < myObj.length; i++) {}
stored object i want to display in variables and im able to display them accordingly
everything is fine until here
but I want to display the description in a popup
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_popup
based on this tutorial I have implemented the same
html1 += ` <div class="popup" onclick="myFunction()">Click me to toggle the popup!
<span class="popuptext" id="myPopup">${desc}</span>
</div>
<p > ${desc}</p>
<script>
function myFunction() {
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}</script>
`;
but when I clicked on it I expected different cards to show different data accordingly but instead, it's just showing the data of the first card element
when clicked on the second one only the first card element pops up with only that particular data of that card
I thought the issue could be because of ID so gave dynamic variables as id
but it's of no use When clicked nothing is coming up
not even error
is there any way where we can display dynamic data based upon the card in that popup
IDs must be unique
Use the loop number to make a unique call to the function, and give each span its own ID.
html1 += ` <div class="popup" onclick="myFunction('${i}')">Click me to toggle the popup!
<span class="popuptext" id="myPopup-${i}">${desc}</span>
</div>
<p > ${desc}</p>
and you only need one script block for all of them
<script>
function myFunction(id) {
var popup = document.getElementById("myPopup-"+id);
popup.classList.toggle("show");
}</script>
I think it's because you are reusing the same id. In html element IDs have to be unique. You could try to append a sequence number to id="myPopup" as you loop, e.g. id="myPopup1", id="myPopup2" etc...
The problem is because you are using the id property. For that reason the first object works and the others no, Javascript takes the id an use it for the first that find and it discart the others.
Try giving the action by class to every button. Something like this:
const buttons = [...document.querySelectorAll('.btn-toggle')]
buttons.forEach(button => button.addEventListener('click', e => click(e)))
const click = e => e.target.parentElement.children[1].classList.toggle('show')
.show {
color: red;
display: block!important;
}
.hide{
display: none
}
<div>
Hello from div 1
<button class="btn-toggle">Toggle</button>
<div class="hide">Toggle!</div>
</div>
<div>
Hello from div 2
<button class="btn-toggle">Toggle</button>
<div class="hide">Toggle!</div>
</div>
<div>
Hello from div 3
<button class="btn-toggle">Toggle</button>
<div class="hide">Toggle!</div>
</div>
As everyone wrote, id is to be unique to work properly.
If you change your css to react to .popup.show it would become more simple:
//REM: this = div.popup
function myFunction(div){
div.classList.toggle('show');
}
.popup span{
display: none
}
.popup.show span{
display: block
}
<div class = 'popup' onclick = 'myFunction(this)'>click<span>clicked</span></div>

How to hide an element in if statement?

I am making an html change to a CMS that will affect all pages when the changes are live. I would like this html alert to only affect 1 specific page. I am attempting to do an if statement for the page title.
The logic is that if the page title is Test Article Two then show the html that I have put in place, if not then display=none. With this logic in place, I am viewing the html on all pages not just the one I want it to show.
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<!--page alert -->
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
<script>
function showAlert() {
if(#pageTitle === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
}else {
document.getElementById('alert-dialog').style.display = 'none';
}
}
</script>
I'd recommend changing a class on the body element so that you can use CSS for the styling.
HTML: nothing really changed here
<body>
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
</div>
</body>
javascript: just check the document.title and add the class the the body element
<script>
if(document.title === "Test Article Two") {
document.body.classList.add("show-alert");
}
</script>
Use CSS for the styling. Always hide #alert-dialog and only show it when we add the class to the body.
<style>
#alert-dialog {
display: none;
}
.show-alert #alert-dialog {
display: block;
}
</style>
If you are making static pages or using server side rendering, you could add logic to add a class to show or hide the alert element without adding more javascript to the page. It will have the relevant class(es) when the html is generated and delivered. This way you won't have to create a function, call it and manipulate the DOM after everything is rendered.
I may have missed this in the code above, are you calling the showAlert function anywhere? If not, your alert won't be shown (or will be shown depending on the default styles).
One thing I'd caution against is the imperative nature of the code here. If you wanted to reuse this alert functionality on another page, you'd have to add another more logic to detect another page title every time you wanted to use the alert. Since you are using a CMS, you might consider adding a flag to show the alert, and on this specific page, turn that flag on.
If you wanted to use the function strategy, I'd set your default alert styles:
#alert-dialog {
display: none;
}
.show {
display: block;
}
and try something like this:
<script>
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').classList.add('show');
}
}
document.addEventListener("DOMContentLoaded", showAlert);
</script>
Another alternative is to take a look at the path of the page this is supposed to be on (window.location.pathname) and using regex to see if it matches what you want. I'd recommend that over looking at the title since it's more likely the title of the page will change rather than the url.
In JavaScript, you can access the page title with document.title. You should change the script like this:
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
} else {
document.getElementById('alert-dialog').style.display = 'none';
}
}

How to undo "this.onclick=null"? How to restore javascript onclick functionality to a div?

I am displaying a div with a default background color. When I click it once, it changes color. A second click does nothing, because the div has this code: "this.onclick=null". That much works well.
However, after I click the div once, I want to click a button to restore its onclick functionality. But the button I have created for that purpose doesn't work, because I don't know what javascript code to use. Does anyone know?
As you can see, I'm working with Bootstrap 3. (Please note that I am a beginner with only basic knowledge of php and js.) Here is my code:
HTML for the div:
<div class="row">
<div class="col-sm-12">
<div id="testDiv" style="background-color: #0000FF" onclick="colorClick(id); this.onclick=null;">
Clicking this div once changes the color.
</div>
</div>
</div>
JAVASCRIPT for the div:
function colorClick(id){
var randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);  
document.getElementById(id).style.backgroundColor=randomColor;
/* The random color generator is from stackoverflow.com/questions/1484506/random-color-generator */
}
HTML for the button:
<div class="row">
<div class="col-sm-12">
    <button type='button' class='btn btn-default btn-lg' onclick=reEnableOnclick()>
This button should re-enable the onclick functionality, but it does not
</button>
</div>
</div>
JAVASCRIPT for the button:
function reEnableOnclick(){
document.getElementById("testDiv").onclick=click;  /* This is only pseudo-code. What real code should I put here? */
}
(Both js functions are in a separate .js document)
EDIT #2: This needs to work for about 100 divs on the same page.
Since you need to apply this functionality to 100s of divs, try keeping track of just the locked states rather than all the divs states at all times. Assuming each div id is unique you could try:
Javascript:
let locked = [];
function lockCheckRun(id) {
let divID = document.getElementById(id);
if (!locked.includes(divID) {
colorClick(id);
locked.push(divID);
}
}
function lockReset() {
locked.length = 0;
}
Explanation:
create an empty array to store locked element ids. We'll call this array 'locked'.
next, create a function which checks to see if the locked array includes the current unique element id. if it does not, then we will run your 'colorClick' function. once that completes, we will add the current element id to the 'locked' array via .push()
when you want to reset your locked element array, run the 'lockReset' function.
Optional Polyfill for comptability with older browsers:
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (search instanceof RegExp) {
throw TypeError('first argument must not be a RegExp');
}
if (start === undefined) { start = 0; }
return this.indexOf(search, start) !== -1;
};
}
Assign the original onclick code.
function reEnableOnclick() {
document.getElementById("testDiv").onclick = "colorClick(id); this.onclick=null;";
}
You can have a pseudo variable inside your javascript code that serves the purpose
In this case you can write
HTML Code
<div class="row">
<div class="col-sm-12">
<div id="testDiv" style="background-color: #0000FF" onclick="colorClick(id)">
Clicking this div once changes the color.
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<button type='button' class='btn btn-default btn-lg' onclick=reEnableOnclick()>
This button should re-enable the onclick functionality, but it does not
</button>
</div>
</div>
Javascript Code
var divDisabled = false;
function colorClick(id){
if(!divDisabled) {
var randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
document.getElementById(id).style.backgroundColor=randomColor;
divDisabled = true;
/* The random color generator is from stackoverflow.com/questions/1484506/random-
color-generator */
}
}
function reEnableOnclick(){
divDisabled = false;
}
So now, You will set divDisabled for false by default so the first click of div will work as you want & following clicks on div won't as it is currently,
But As soon as you hit the button click it enables the click on div with setting buttonDisable to false, so it will again work once on div, as you want
Don't remove the click event, just check a flag to see if the behaviour is enabled or not. E.G:
var clickEnabled = true;
function colorClick(id) {
if (clickEnabled) {
var randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
document.getElementById(id).style.backgroundColor = randomColor;
clickEnabled = false;
}
}
function reEnableOnclick() {
clickEnabled = true;
}
<div class="row">
<div class="col-sm-12">
<div id="testDiv" style="background-color: #0000FF" onclick="colorClick(id);">
Clicking this div once changes the color.
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<button type='button' class='btn btn-default btn-lg' onclick=reEnableOnclick()>
This button will re-enable the onclick functionality
</button>
</div>
</div>
You could define the function to run onclick outside of the assignment and use it to set and reset the click handler...
function functionThatRunsWhenButtonClicked() {
// do stuff
}
then in the places you need to assign it, assign it..
<div class="row">
<div class="col-sm-12">
<div id="testDiv" style="background-color: #0000FF" onclick="functionThatRunsWhenButtonClicked(); this.onclick=null;">
Clicking this div once changes the color.
</div>
</div>
</div>
function reEnableOnclick(){
document.getElementById("testDiv").onclick=functionThatRunsWhenButtonClicked; /* This
is only pseudo-code. What real code should I put here? */
}
You can do the same thing with colorClick(id)

JQuery: Hide all images except one, starting from the first one and scrolling it

I can't change the HTML code, and it looks like this:
<div class="slider">
<div class="slider-control">
<button id="prev">Previous</button>
<button class="foll">Next</button>
</div>
<div class="slider-image">
<img src="html.png" alt="Html" />
<img src="css.png" alt="Css" />
<img src="jquery.png" alt="jQuery" />
</div>
</div>
When the program starts I need to show the first image. If I click on "Previous" I want to show the previous img (if the currently img showed is the first one, I want to show the last one), if I click on "Next" then I want to show the next img.
I need it to be a generic solution case I need to use it also with more images.
I tried with:
function showImage(){
$(".slider-image img").not(":eq(n)").hide();
}
$(document).ready(function(){
n = 0;
showImage(n);
$(".slider-control button").click(function(){
if($(this).is("div.slider-control.prev")){
n -= 1;
showImage(n);
}
else if($(this).is("div.slider-control.foll")){
n += 1;
showImage(n);
}
});
});
But it doesn't show anything
There was a few issues that I've fixed for you, but this should now work okay for you
showImage was not taking n as a paramater, but you were passing it that when you were calling it
function showImage() {... // Not taking the param you're passing
function showImage(n) {... // Now we are, and assigning it the name 'n'
You weren't using .show() on the element you wanted to show - you were only ever using .hide()
There was also an issue with how spamming the next or previous buttons would change the n higher / lower than your element count, and so you would end up selecting elements that didn't exist. To keep your n within the range of your elements, you can do this to loop back around an array's indexes
n = n % $('.slider-image img').length;
Finally, you weren't passing n to the :not(:eq(n)) - I've just used template literals to insert the variable cleanly
In the HTML, I set your buttons to both use IDs, because I felt this made more sense and helps readabilit
In the $(document).ready(..., you also had an error with your .is() - You were alredy working from the <button> element, so you're okay to check just on the ID of the buttons
function showImage(n){
n = n % $(".slider-image img").length;
$(".slider-image img").not(`:eq(${n})`).hide();
$(".slider-image img").eq(n).show();
}
$(document).ready(function(){
n = 0;
showImage(n);
$(".slider-control button").click(function(){
if($(this).is("#prev")){
n -= 1;
showImage(n);
}
else if($(this).is("#foll")){
n += 1;
showImage(n);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slider">
<div class="slider-control">
<button id="prev">Previous</button>
<button id="foll">Next</button>
</div>
<div class="slider-image">
<img src="https://via.placeholder.com/150" alt="Html" />
<img src="https://via.placeholder.com/200" alt="Css" />
<img src="https://via.placeholder.com/250" alt="jQuery" />
</div>
</div>

simulate clicks without user interactivity every x seconds

I have 5 divs every div call H4.
I create this by javascript to get the result and it works but now I need it to do this automatically in sequence without user interactivity to be like auto slider, for example, caption1 should click first and show caption1content after 8 seconds caption 2 clicks and show captoin2content and so on how can I do this by javascript.
JS:
$("#caption1").on('click', function() {
$("#caption1content").fadeIn();
$("#caption2content,#caption3content,#caption4content,#caption5content").fadeOut();
});
$("#caption2").on('click', function() {
$("#caption2content").fadeIn();
$("#caption1content,#caption3content,#caption4content,#caption5content").fadeOut();
});
$("#caption3").on('click', function() {
$("#caption3content").fadeIn();
$("#caption1content,#caption2content,#caption4content,#caption5content").fadeOut();
});
$("#caption4").on('click', function() {
$("#caption4content").fadeIn();
$("#caption1content,#caption2content,#caption3content,#caption5content").fadeOut();
});
$("#caption5").on('click', function() {
$("#caption5content").fadeIn();
$("#caption1content,#caption2content,#caption3content,#caption4content").fadeOut();
});
HTML:
<div id="caption">
<h4 id="caption1content" class="ccntnt">text1</h4>
<h4 id="caption2content" class="ccntnt">text2</h4>
<h4 id="caption3content" class="ccntnt">text3</h4>
<h4 id="caption4content" class="ccntnt">text4</h4>
<h4 id="caption5content" class="ccntnt">text5</h4>
</div>
<div id="captionbtns">
<div id="caption1">text1</div>
<div id="caption2">text2</div>
<div id="caption3">text3</div>
<div id="caption4">text4</div>
<div id="caption5">text5</div>
</div>
well it is pretty simple you can use setInterval and you can do it like this not the perfect way but working.
it will click after every 8 seconds it will only loop through it once and further you can use a if condition to reset the count if you want to run it again and again;
let count = 1;
setInterval(function(){
$(`#caption${count}`).click();
count++;
},8000);

Categories