So I wrote this multi-step form and it worked with the current code I have listed below until I changed it to send/receive data from php. The only thing that works is updating the progress bar but other then that it doesn't work. I have an idea why its not working cause of the actual button event isn't targeting the correct $(this).parent();
when I changed it from nextSection()
to onSubmit()
. I would possibly like to write it where it just selects the div class from an object then remove the current section but I wanna keep it the way I have for now.
$(".btn").on("click", nextSection);
function nextSection() {
if (typeof sections[current] !== "undefined") {
if(valid) {
current_section = $(this).parent();
next_section = $(this).parent().next();
console.log(current_section)
next_section.fadeIn();
current_section.remove();
current ;
updateProgressbar();
if (current === 1) {
let username = $(".username").val();
updatePenguinObj("username", username);
} else if (current === 2) {
let password = $(".password").val();
let email = $(".email").val();
updatePenguinObj("password", password);
updatePenguinObj("email", email);
} else if (current === 3) {
let name = $(".done");
name.text(name.text().replace(/%. ?%/, userData.username));
}
}
}
}
Then I changed it to the onSubmit()
function w/ the validation responses.
$(".btn").on("click", onSubmit);
function onSubmit(event) {
event.preventDefault()
let request = new XMLHttpRequest()
request.onreadystatechange = () => handleResponse(request)
let formData = new FormData()
formData.append('username', userData.username);
formData.append('color', userData.colorId);
formData.append('password', userData.password);
formData.append('email', userData.email);
request.open('POST', 'scripts/php/create.php')
request.send(formData)
}
function handleResponse(request) {
if (request.readyState !== XMLHttpRequest.DONE || request.status !== 200) {
return
}
let response = JSON.parse(request.responseText);
if (!response) {
return
}
sectionValidation(response);
}
function sectionValidation(response) {
valid = true;
let section = $(sections[current]);
let input = section.find("input");
input.each(function() {
let inputs = $(this).attr('type') === "checkbox" ? !$(this).is(':checked') : input;
if(inputs) {
if (!response.valid) {
showError(response.message);
return valid = response.valid;
}
}
});
if(valid) {
nextSection(); //This is where nextSection is excuted to go to next page but doesnt.
}
}
I pastebin the entire code for each file type that way im not spamming this thread with just code. Overall i'm just trying to figure out how to fix it where I can go to the next section.
HTML - https://pastebin.com/eF8eXBfN
JS - https://pastebin.com/LuvYtYFc
PHP -
Basically just returns a JSON Object {message: "Test", valid: false}
for the message responses and validation for it to go to next section.
CodePudding user response:
if this isn't helpful I apologise in advance ....
because nextSection(); uses $(this) it won't have refrance to the button as it would have done when you used $(".btn").on("click", nextSection);
so you could add a reference of $(this) though to that function from the onSubmit
I create an example using your code, I dummy the response from the php but the rest is the same: https://jsfiddle.net/PatrickHume/8x6rodpn/
I don't know if this is better but it's another approach, I hope its helpful
let valid = true;
let sections = {
0: ".rules-section",
1: ".color-section",
2: ".info-section",
3: ".done-section"
};
let userData;
let current = 0,
current_section, next_section;
let currPalleteId = 0;
let penguinColors = {
"Blue": "003366",
"Green": "009900",
"Pink": "FF3399",
"Black": "333333",
"Red": "CC0000",
"Orange": "FF6600",
"Yellow": "FFCC00",
"Purple": "660099",
"Brown": "996600",
"Peach": "FF6666",
"Dark Green": "006600",
"Light Blue": "0099CC",
"Lime Green": "8AE302",
"Sensei Gray": "93A0A4",
"Aqua": "02A797",
"Arctic White": "F0F0D8",
};
window.onload = function() {
initalizeCreate();
};
function initalizeCreate() {
loadPalletes();
createPenguinObj();
$(".btn").on("click", onSubmit);
$(".show-password").on("click", togglePassword);
$("#startAgain").on("click", resetForm);
$(".random-username").on("click", randomUsername);
$(".username").keyup(function() {
let username = this.value;
updateDollName(username);
});
}
async function randomUsername() {
let url = "https://randomuser.me/api/";
let obj = await (await fetch(url)).json();
obj = obj.results[0];
let randuser = obj.login.username
$(".username").val(randuser);
updateDollName(randuser);
}
function updateDollName(username) {
username === "" ? $(".penguinName").text("Penguin Name") : $(".penguinName").text(username);
}
function togglePassword() {
$(this).toggleClass("fa-eye fa-eye-slash");
let input = $(this).prev('.info-section input');
input.attr('type', input.attr('type') === 'password' ? 'text' : 'password');
}
function resetForm() {
location.reload()
}
function nextSection($this) {
if (typeof sections[current] !== "undefined") {
if (valid) {
current_section = $($this).parent();
next_section = $($this).parent().next();
// console.log(current_section)
next_section.fadeIn();
current_section.remove();
current ;
updateProgressbar();
if (current === 1) {
let username = $(".username").val();
updatePenguinObj("username", username);
} else if (current === 2) {
let password = $(".password").val();
let email = $(".email").val();
updatePenguinObj("password", password);
updatePenguinObj("email", email);
} else if (current === 3) {
let name = $(".done");
name.text(name.text().replace(/%. ?%/, userData.username));
}
}
}
}
function onSubmit(event) {
event.preventDefault()
let request = new XMLHttpRequest()
request.onreadystatechange = () => handleResponse(request, $(this))
let formData = new FormData()
formData.append('username', userData.username);
formData.append('color', userData.colorId);
formData.append('password', userData.password);
formData.append('email', userData.email);
request.open('POST', 'https://reqbin.com/sample/post/json')
request.send(formData)
}
function handleResponse(request, $this) {
if (request.readyState !== XMLHttpRequest.DONE || request.status !== 200) {
return
}
var resp = `{
"message": "Test",
"valid": true
}`
let response = JSON.parse(resp);
if (!response) {
return
}
sectionValidation(response, $this);
}
function sectionValidation(response, $this) {
valid = true;
let section = $(sections[current]);
let input = section.find("input");
input.each(function() {
let inputs = $(this).attr('type') === "checkbox" ? !$(this).is(':checked') : input;
if (inputs) {
if (!response.valid) {
showError(response.message);
return valid = response.valid;
}
}
});
if (valid) {
nextSection($this);
}
}
function showError(text) {
$("#c_container").append(`<div ><div ><div id="error-content"><div id="error-msg-txt"> %text% </div><div id="error-btn"><div id="error-txt">Ok</div></div></div></div></div>`);
$("#error-btn").on("click", () => {
closeError();
});
let message = $("#error-msg-txt").html(text);
message.text(message.text().replace(/%. ?%/, message));
$(".error-block-container").fadeIn();
}
function closeError() {
$(".error-block-container").remove();
}
function updateProgressbar() {
let progressSteps = document.querySelectorAll(".progress-step");
progressSteps.forEach((progressStep, id) => {
if (id < current 1) {
progressStep.classList.add("progress-step-active");
progressStep.classList.add("step");
} else {
progressStep.classList.remove("progress-step-active");
progressStep.classList.remove("step");
}
});
progressSteps.forEach((progressStep, id) => {
if (id < current) {
progressStep.classList.add("progress-step-check");
progressStep.classList.remove("progress-step-active");
} else {
progressStep.classList.remove("progress-step-check");
}
});
let progressActive = document.querySelectorAll(".step");
$(".progress").css("width", ((progressActive.length - 1) / (progressSteps.length - 1)) * 100 "%");
}
function loadPalletes() {
let colorIndexNum = 0;
for (let palletes in penguinColors) {
let colorHex = penguinColors[palletes],
colorIndex = palletes,
colorIndexCurrNum = colorIndexNum;
$("#palletes").append(`<div data-id="${colorIndexCurrNum}" style="background: #${colorHex}"></div> `);
}
$("#palletes").on("click", function(e) {
currPalleteId = $(e.target).attr("data-id");
e.currentTarget.querySelector(".active").classList.remove("active");
if (e.target.classList.contains("tinyPallete")) {
e.target.classList.add("active");
}
$(".doll").css("background-color", "#" penguinColorByIndex(currPalleteId, false));
});
}
function penguinColorByIndex(index, keys) {
if (keys) {
return Object.keys(penguinColors)[--index];
}
return Object.values(penguinColors)[--index];
}
function updatePenguinObj(key, value) {
userData[key] = value;
return userData;
}
function createPenguinObj() {
userData = new Object();
userData.username = "";
userData.colorId = Number(currPalleteId);
userData.password = "";
userData.email = "";
return userData;
}
<html>
<head>
<title>Create Account</title>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
<link type="text/css" rel="stylesheet" href="styles/fonts.css" />
<link type="text/css" rel="stylesheet" href="styles/create.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
</head>
<body>
<div id="c_header">
<h2>Create a Free Account</h2>
<div id="startAgain">Start Again</div>
<div >
<div id="progress"></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</div>
</div>
<div id="c_container">
<div id="c_content">
<img id="logo" src="images/logo.png" /><img id="safety" src="images/safety.png" />
<form method="POST">
<div >
<div >
<div >
<div>
<div id="rule-title">Respect other penguins</div>
Club Penguin does not tolerate any swearing, bullying or mean behavior toward other penguins. Disciplinary action will be taken should any one of these occur while playing.
</div>
<img id="rule-image" src="images/respect.png" />
</div>
<div >
<div>
<div id="rule-title">No inappropriate talk</div>
References to drugs and alcohol related activities, and sexual, racial or otherwise inappropriate talk are not permitted.
</div>
<img id="rule-image" src="images/inapp.png" />
</div>
<div >
<div>
<div id="rule-title">Never reveal personal information</div>
The best way to stay safe online is to NEVER share your real name, phone number, address, email or passwords.
</div>
<img id="rule-image" src="images/personal.png" />
</div>
<div >
<div>
<div id="rule-title">No cheating</div>
Use of third party programs to cheat is prohibited. Players who use any third party programs while playing risk being permanently banned.
</div>
<img id="rule-image" src="images/cheating.png" />
</div>
</div>
<hr />
<div id="agree"> <span >
<input type="checkbox" id="agree" name="agree" /><label>I agree to the Club Penguin Rules.</label>
</span>
</div>
<div id="terms"> <span >
<input type="checkbox" id="terms" name="terms" /><label>I agree to the <a id="hyper" href="#">Terms of Use</a></label>
</span>
</div>
<button name="submit">Continue</button>
</div>
<div >
<div id="color-form">
<p id="epname">Enter Your Penguin Name:</p>
<!--<span >
<div id="bubble-msg"></div>
</span>-->
<input type="text" name="username" id="inputaligncenter" maxlength="16" /> <span toggle="#random_username" title="Random Username"></span>
<div id="cpsmall">Minimum 4 characters: use only numbers, letters and spaces.</div>
<p id="cpname">Click on a Color:</p>
<div id="palletes"></div>
<img id="paintbucket" src="images/paintbucket.png" />
</div>
<div > <img src="images/doll.png" /> <span >Penguin Name</span> </div>
<button name="submit">Continue</button>
</div>
<div >
<div id="info-form">
<div id="ppname-wrapper">
Penguin Password:
<div id="ppsmall">This is the password you will use to login to Club Penguin. </div>
<input type="password" name="password" placeholder="Password"><span toggle="#password" ></span>
<input type="password" name="cpassword" placeholder="Confirm Password"><span toggle="#c_password" ></span>
<p id="activatedTxt">your penguin must be activated before you will be able to play at club penguin</p>
Parent's Email Address:
<div id="ppsmall">Please enter your parent's valid email address. Club Penguin will send your parent an e-mail with an activation code.</div>
<div > <img src="images/envelope.png">
<input type="text" name="email">
</div>
</div>
<div > <img src="images/doll.png" /> <span >Penguin Name</span> </div>
</div>
<button type="submit" name="submit">Continue</button>
</div>
<div >
<h2 >%username%, your Account Has Been Successfully Created!</h2>
</div>
</form>
</div>
</div>
</body>
</html>
CodePudding user response:
Solved my problem lol. I just wrote another function that just selects the classes from a div, removes the current, then adds 1 to the current section to show the next. If anyone has a better method feel free to correct me.
function gotoNextSection() {
current_section = $(sections[current]);
current_section.remove();
current ;
next_section = $(sections[current]);
next_section.fadeIn();
updateProgressbar();
}