Home > database >  Multi-step form won't go to next section JS/HTML
Multi-step form won't go to next section JS/HTML

Time:07-16

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();
}
  • Related