<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet">
</head>

<body>
  <section id="camp-activities-inquiry">
    <h1>Camp Activities Inquiry</h1>
    <form action="/submit-form" method="POST">
      <label for="activity-select">Which camp activities are you most looking forward to?</label>
      <select id="activity-select" name="activity">
        <option value="">--Please choose an option--</option>
        <option value="hiking">Hiking</option>
        <option value="canoeing">Canoeing</option>
        <option value="fishing">Fishing</option>
        <option value="crafts">Crafts</option>
        <option value="archery">Archery</option>
      </select>

      <label for="food-allergies">Food Allergies (if any)</label>
      <textarea id="food-allergies" name="food_allergies" rows="4" cols="50"></textarea>

      <label for="additional-info">Additional things the counselor should know</label>
      <textarea id="additional-info" name="additional_info" rows="4" cols="50"></textarea>

      <button type="submit">Submit</button>
    </form>
  </section>
</body>
body {
  background: linear-gradient(135deg, #ffd700, #ffbb00);
  background-attachment: fixed;
  font-family: "Lato", sans-serif;
  font-style: normal;
  text-align: center;
  transition: all 800ms;
}

body.dark-mode {
  background: linear-gradient(135deg, #2D4496, #0E3358);
  background-attachment: fixed;
  color: #fefefe;
}

section {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

form {
  position: relative;
  width: 70%;
  height: 60vh;
  padding: 24px 8px;
  display: flex;
  flex-direction: column;
  background: #fefefe;
  border: 2px solid black;
  z-index: 2;
  transition: all 800ms;
}

form.dark-mode {
  background: #252e33;
  border: none;
}

#activity-select {
  padding: 8px 12px;
  background: #fefefe;
  color: #252e33;
  border: 1px solid #252e33;
  border-radius: 8px;
  font-weight: 500;
  -moz-appearance: none; /* Firefox */
  -webkit-appearance: none; /* Safari and Chrome */
  appearance: none;
  background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23131313%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
  background-repeat: no-repeat;
  background-position: right 0.7rem top 50%;
  background-size: 0.65rem auto;
  cursor: pointer;
}

textarea {
  padding: 12px;
  resize: none;
}

textarea::-webkit-scrollbar {
  width: 0.5rem;
}

textarea::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.2);
}

textarea::-webkit-scrollbar-thumb {
  background-color: #bababa;
  outline: 1px solid rgba(0, 0, 0, 0.3);
}

button {
  padding: 8px;
  position: absolute;
  bottom: -20%;
  right: 0;
  width: 25%;
  background: #006992;
  border-radius: 8px;
  color: #fefefe;
  font-weight: 600;
  cursor: pointer;
}

button:hover,
button:focus {
  border-color: transparent;
  background: #00a1e0;
}

/* this div will give the "note" appareance */
#note-back {
  position: absolute;
  width: 71%;
  height: 71vh;
  top: 88px;
  left: 17%;
  background: #ffe7de;
  z-index: 1;
}

label,
select,
textarea {
  width: 80%;
  margin: 0 auto;
}

label {
  margin-bottom: 1rem;
}

/* We will position the image on the right side of the form */
#form-image {
  position: absolute;
  bottom: 20%;
  left: 30%;
  z-index: 3;
  width: 40%;
  max-height: 40vh;
}

/* Style for the Steps button */
#prev-step,
#next-step {
  position: absolute;
  top: 40vh;
  border: solid #252e33;
  border-width: 0 12px 12px 0;
  display: inline-block;
  padding: 20px;
  z-index: 5;
  cursor: pointer;
  transition: all 800ms;
}

#prev-step {
  left: 6%;
  transform: rotate(135deg);
  -webkit-transform: rotate(135deg);
}

#next-step {
  right: 5%;
  transform: rotate(-45deg);
  -webkit-transform: rotate(-45deg);
}

#prev-step:hover,
#next-step:hover {
  border: solid #fefefe;
  border-width: 0 12px 12px 0;
}

#prev-step:focus,
#next-step:focus {
  border: solid white;
  border-width: 0 12px 12px 0;
  outline: none;
  box-shadow: inset -4px -4px 0 #000;
}

#prev-step.dark-mode,
#next-step.dark-mode {
  border: solid #fefefe;
  border-width: 0 12px 12px 0;
}

#prev-step.dark-mode:hover,
#next-step.dark-mode:hover {
  border: solid #252e33;
  border-width: 0 12px 12px 0;
  box-shadow: inset -4px -4px 0 #fefefe;
}

#prev-step.dark-mode:focus,
#next-step.dark-mode:focus {
  border: solid #252e33;
  border-width: 0 12px 12px 0;
  box-shadow: inset -4px -4px 0 #fefefe;
}

/* Let's add some step indicators */
#step-container {
  position: relative;
  width: 20%;
  height: 3rem;
  margin: 1rem auto;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  z-index: 3;
}

.step {
  height: 15px;
  width: 15px;
  background-color: #858585;
  border: none;
  border-radius: 50%;
  display: inline-block;
  opacity: 0.5;
}

/* Mark the active step: */
.active {
  background-color: #1e2d2f;
}
.step.active.dark-mode {
  background-color: #fefefe;
}

/* Hide elements - General class */
.isHidden {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
}

@media (min-width: 1050px) {
  form {
    width: 50%;
  }

  #note-back {
    width: 52%;
    height: 69vh;
    left: 25%;
  }
}

@media (max-width: 640px) {
  form {
    width: 64%;
  }

  #note-back {
    width: 65%;
    height: 68vh;
    left: 21%;
  }

  #activity-select {
    background-image: none;
  }

  button {
    padding: 12px 8px;
    bottom: -25%;
    width: 33%;
    right: 33%;
  }

  #form-image {
    bottom: 25%;
    left: 25%;
    width: 50%;
  }
}

@media (max-height: 400px) {
  form {
    position: relative;
    width: 60%;
  }

  label,
  #activity-select,
  #food-allergies,
  #additional-info {
    width: 40%;
    margin: 0;
    margin-left: 5%;
  }

  label {
    margin-bottom: 1rem;
  }

  #form-image {
    bottom: 0;
    left: 45%;
    max-height: 70vh;
  }
}

.invalid {
  border: 1px solid #ff3341 !important;
}

.finish {
  border: 2px solid #75a998 !important;
}

#toggle {
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  appearance: none;
  outline: none;
  cursor: pointer;

  width: 2rem;
  height: 2rem;
  box-shadow: inset calc(2rem * 0.33) calc(2rem * -0.25) 0;
  border-radius: 999px;
  color: hsl(240, 100%, 95%);

  transition: all 500ms;

  &:checked {
    transform: scale(0.75);
    color: hsl(40, 100%, 50%);
    box-shadow: inset 0 0 0 2rem,
      calc(calc(2rem * 0.65) * -1) 0 0 calc(2rem * -0.4),
      calc(2rem * 0.65) 0 0 calc(2rem * -0.4),
      0 calc(calc(2rem * 0.65) * -1) 0 calc(2rem * -0.4),
      0 calc(2rem * 0.65) 0 calc(2rem * -0.4),
      calc(calc(2rem * 0.45) * -1) calc(calc(2rem * 0.45) * -1) 0
        calc(2rem * -0.4),
      calc(2rem * 0.45) calc(2rem * 0.45) 0 calc(2rem * -0.4),
      calc(calc(2rem * 0.45) * -1) calc(2rem * 0.45) 0 calc(2rem * -0.4),
      calc(2rem * 0.45) calc(calc(2rem * 0.45) * -1) 0 calc(2rem * -0.4);
  }
}
/* All images used in this demo comes from the amazing Work illustrations by Storyset 
https://storyset.com/work
*/

/* A helpful page for color reference 
https://coolors.co/
*/

/* Dark mode toggle by mrozilla
https://codepen.io/mrozilla/pen/OJJNjRb?editors=1010
*/

// Add a div for styling
(function () {
  let noteBack = document.createElement("div");
  noteBack.setAttribute("id", "note-back");
  document.body.appendChild(noteBack);
})();

// Add the form image
(function () {
  let img = document.createElement("img");
  img.setAttribute("id", "form-image");
  // Default image
  img.src =
    "https://gist.github.com/assets/152430863/3444f12b-4bc6-448d-85fd-4ce76efd30f7";
  document.body.appendChild(img);
})();

// Add a div for containing the steps
(function () {
  let stepContainer = document.createElement("div");
  stepContainer.setAttribute("id", "step-container");
  document.body.appendChild(stepContainer);
})();

const totalSteps = 3;
// Add 3 steps dots
(function () {
  for (let i = 0; i < totalSteps; i++) {
    let step = document.createElement("span");
    step.classList.add("step");
    const stepContainer = document.getElementById("step-container");
    stepContainer.appendChild(step);
  }
})();

// Add step prev and next buttons
(function () {
  const section = document.getElementById("camp-activities-inquiry");

  let prevStep = document.createElement("div");
  prevStep.setAttribute("id", "prev-step");
  section.insertBefore(prevStep, section.children[0]);

  let nextStep = document.createElement("div");
  nextStep.setAttribute("id", "next-step");
  document.body.appendChild(nextStep);
})();

// Add a checkbox for dark mode
(function () {
  let darkModeBtn = document.createElement("input");
  darkModeBtn.setAttribute("id", "toggle");
  darkModeBtn.setAttribute("type", "checkbox");
  document.body.appendChild(darkModeBtn);
})();

// All getters
let activitiesSelect = document.getElementById("activity-select");
let activitiesSelectLabel = document.querySelector(
  "label[for='activity-select']"
);
let foodAlergies = document.getElementById("food-allergies");
let foodAlergiesLabel = document.querySelector("label[for='food-allergies']");
let additionalInfo = document.getElementById("additional-info");
let additionalInfoLabel = document.querySelector(
  "label[for='additional-info']"
);
let formImage = document.getElementById("form-image");
let submitButton = document.querySelector("button[type=submit]");
let steps = document.getElementsByClassName("step");
let prevStep = document.getElementById("prev-step");
let nextStep = document.getElementById("next-step");
let modeToggle = document.getElementById("toggle");

// TAB LOGIC
let currentActivity = ""; // For select
let currentTab = 0;
let darkMode = false; // For darkMode check
showCurrentTab();

function showCurrentTab() {
  // Hide the form elements when needed
  if (currentTab === 0) {
    validateForm();
    activitiesSelect.classList.remove("isHidden");
    activitiesSelectLabel.classList.remove("isHidden");

    foodAlergies.setAttribute("class", "isHidden");
    foodAlergiesLabel.setAttribute("class", "isHidden");

    additionalInfo.setAttribute("class", "isHidden");
    additionalInfoLabel.setAttribute("class", "isHidden");

    submitButton.setAttribute("class", "isHidden");

    // Add and remove styling to the step indicators
    // We will also consider if dark mode is active
    if (darkMode) {
      steps[0].classList.add("active");
      steps[0].classList.add("dark-mode");
      steps[1].classList.remove("active");
      steps[1].classList.remove("dark-mode");
      steps[2].classList.remove("active");
      steps[2].classList.remove("dark-mode");
    } else {
      steps[0].classList.add("active");
      steps[1].classList.remove("active");
      steps[2].classList.remove("active");
    }

    // We will show the correct image accotding to the selected activity
    getImageBasedOnSelection(currentActivity);

    // This will make only the elements in screen to be accessible for the keyboard tab
    activitiesSelect.setAttribute("tabindex", 0);
    nextStep.setAttribute("tabindex", 0);
    foodAlergies.setAttribute("tabindex", -1);
    additionalInfo.setAttribute("tabindex", -1);
    submitButton.setAttribute("tabindex", -1);
    prevStep.setAttribute("tabindex", -1);

    // And this will set the focus on the form element when we change tabs
    activitiesSelect.focus();
  } else if (currentTab === 1) {
    validateForm();
    foodAlergies.classList.remove("isHidden");
    foodAlergiesLabel.classList.remove("isHidden");

    activitiesSelect.setAttribute("class", "isHidden");
    activitiesSelectLabel.setAttribute("class", "isHidden");

    additionalInfo.setAttribute("class", "isHidden");
    additionalInfoLabel.setAttribute("class", "isHidden");

    submitButton.setAttribute("class", "isHidden");

    formImage.src =
      "https://gist.github.com/assets/152430863/23141ef2-76a1-4122-b8e6-4cc9dbfbef6f";

    if (darkMode) {
      steps[0].classList.remove("active");
      steps[0].classList.remove("dark-mode");
      steps[1].classList.add("active");
      steps[1].classList.add("dark-mode");
      steps[2].classList.remove("active");
      steps[2].classList.remove("dark-mode"); 
    } else {
      steps[0].classList.remove("active");
      steps[1].classList.add("active");
      steps[2].classList.remove("active"); 
    }

    activitiesSelect.setAttribute("tabindex", -1);
    nextStep.setAttribute("tabindex", 0);
    foodAlergies.setAttribute("tabindex", 0);
    additionalInfo.setAttribute("tabindex", -1);
    submitButton.setAttribute("tabindex", -1);
    prevStep.setAttribute("tabindex", 0);

    foodAlergies.focus();
  } else {
    validateForm();
    additionalInfo.classList.remove("isHidden");
    additionalInfoLabel.classList.remove("isHidden");
    submitButton.classList.remove("isHidden");

    activitiesSelect.setAttribute("class", "isHidden");
    activitiesSelectLabel.setAttribute("class", "isHidden");

    foodAlergies.setAttribute("class", "isHidden");
    foodAlergiesLabel.setAttribute("class", "isHidden");

    formImage.src =
      "https://gist.github.com/assets/152430863/78fdd59e-5d0d-4d33-b654-6b8d2fc1f271";

    if (darkMode) {
      steps[0].classList.remove("active");
      steps[0].classList.remove("dark-mode");
      steps[1].classList.remove("active");
      steps[1].classList.remove("dark-mode");
      steps[2].classList.add("active");
      steps[2].classList.add("dark-mode"); 
    } else {
      steps[0].classList.remove("active");
      steps[1].classList.remove("active");
      steps[2].classList.add("active");
    }

    activitiesSelect.setAttribute("tabindex", -1);
    nextStep.setAttribute("tabindex", -1);
    foodAlergies.setAttribute("tabindex", -1);
    additionalInfo.setAttribute("tabindex", 0);
    submitButton.setAttribute("tabindex", 0);
    prevStep.setAttribute("tabindex", 0);

    additionalInfo.focus();
  }

  // Hide prevStep and nextStep btns when there are no steps before or after current
  if (currentTab == 0) {
    prevStep.setAttribute("class", "isHidden");
  } else {
    prevStep.classList.remove("isHidden");
    if (darkMode) {
      prevStep.setAttribute("class", "dark-mode");
    } else {
      prevStep.classList.remove("dark-mode");
    }
  }
  if (currentTab == totalSteps - 1) {
    nextStep.setAttribute("class", "isHidden");
  } else {
    nextStep.classList.remove("isHidden");
    if (darkMode) {
      nextStep.setAttribute("class", "dark-mode");
    } else {
      nextStep.classList.remove("dark-mode");
    }
  }
}

// Now we add the functionality to those buttons
function prev() {
  currentTab = currentTab - 1;
  showCurrentTab();
}

function next() {
  currentTab = currentTab + 1;
  showCurrentTab();
}

// Well actually, NOW we add the functionality
prevStep.onclick = prev;
nextStep.onclick = next;

// And this will help the navigation with keyboard
prevStep.onkeydown = function (event) {
  if (event.keyCode === 32 || event.keyCode === 13) {
    event.preventDefault();
    prevStep.click();
  }
};

nextStep.onkeydown = function (event) {
  if (event.keyCode === 32 || event.keyCode === 13) {
    event.preventDefault();
    nextStep.click();
  }
};

// Let's make some changes when different options are selected
// We will update currentActivity with each change
activitiesSelect.addEventListener("change", (event) => {
  currentActivity = event.target.value;
  getImageBasedOnSelection(event.target.value);
});

// This is to make the first option in the select, non selectable
let selectPlaceholder = document.forms[0].elements[0].options[0];
selectPlaceholder.setAttribute("disabled", "true");

// And this will help us change the image according to the selection
function getImageBasedOnSelection(activity) {
  switch (activity) {
    case "hiking":
      return (formImage.src =
        "https://gist.github.com/assets/152430863/108f6a4a-c024-4020-8b18-837570b92058");
    case "canoeing":
      return (formImage.src =
        "https://gist.github.com/assets/152430863/acffab85-e3c0-4b42-afb0-100044676f18");
    case "fishing":
      return (formImage.src =
        "https://gist.github.com/assets/152430863/95cb8a97-dbc2-4757-9374-90b67e037d70");
    case "crafts":
      return (formImage.src =
        "https://gist.github.com/assets/152430863/b010bcec-35df-4833-98f4-68d9b8f4e79a");
    case "archery":
      return (formImage.src =
        "https://gist.github.com/assets/152430863/d1fac704-591a-4478-bb99-9a9ba47290d8");
    default:
      formImage.src =
        "https://gist.github.com/assets/152430863/3444f12b-4bc6-448d-85fd-4ce76efd30f7";
  }
}

// Now we will add validation to the form
function validateForm() {
  // We will turn off the submit button if any value is missing
  if (
    activitiesSelect.value == "" ||
    foodAlergies.value == "" ||
    additionalInfo.value == ""
  ) {
    submitButton.setAttribute("disabled", "true");
  } else {
    submitButton.removeAttribute("disabled");
  }

  // We will add colors to indicate if the form values are valid
  if (currentTab == 0 && activitiesSelect.value == "") {
    activitiesSelect.classList.add("invalid");
  } else if (currentTab == 0 && activitiesSelect.value != "") {
    activitiesSelect.classList.remove("invalid");
    activitiesSelect.classList.add("finish");
  } else if (currentTab == 1 && foodAlergies.value == "") {
    foodAlergies.classList.add("invalid");
  } else if (currentTab == 1 && foodAlergies.value != "") {
    foodAlergies.classList.remove("invalid");
    foodAlergies.classList.add("finish");
  } else if (currentTab == 2 && additionalInfo.value == "") {
    additionalInfo.classList.add("invalid");
  } else if (currentTab == 2 && additionalInfo.value != "") {
    additionalInfo.classList.remove("invalid");
    additionalInfo.classList.add("finish");
  }
  return;
}

// Check validation on change as well
activitiesSelect.addEventListener("change", (event) => validateForm());
foodAlergies.addEventListener("change", (event) => validateForm());
additionalInfo.addEventListener("change", (event) => validateForm());

// Dark mode toggle
function changeMode() {
  darkMode = !darkMode;
  document.body.classList.toggle("dark-mode");
  document.forms[0].classList.toggle("dark-mode");
  prevStep.classList.toggle("dark-mode");
  nextStep.classList.toggle("dark-mode");
  steps[currentTab].classList.toggle("dark-mode");
}

modeToggle.onclick = changeMode;

// A little underwhelming but, here is the onsubmit action
document.forms[0].onsubmit = function (e) {
  // This is just to prevent the page to go blank
  e.preventDefault();
  alert("You made it!");
};

/* Here I'll leave all (or 90%) of my investigation links for transparency
the two major references for all my work as always are w3schools and MDN
but you will also see a lot of stack overflow

1. https://www.w3schools.com/howto/howto_js_form_steps.asp
2. https://www.w3schools.com/howto/howto_js_add_class.asp
3. https://www.w3schools.com/howto/howto_css_arrows.asp
4. https://www.w3schools.com/jsref/met_node_insertbefore.asp
5. https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute
6. https://developer.mozilla.org/en-US/docs/Web/API/Document/forms
7. https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event
8. https://developer.mozilla.org/es/docs/Web/CSS/box-shadow
9. https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
10. https://www.toptal.com/developers/keycode/enter
11. https://mui.com/base-ui/react-select/
12. https://www.educative.io/answers/how-to-add-an-id-to-element-in-javascript
13. https://stackoverflow.com/questions/6564171/get-all-the-button-tag-types
14. https://stackoverflow.com/questions/10872006/how-do-i-change-the-value-of-a-global-variable-inside-of-a-function
15. https://stackoverflow.com/questions/50191630/how-to-use-js-to-update-text-based-on-selected-option-value
16. https://stackoverflow.com/questions/23986930/how-to-make-an-html-dropdown-option-not-clickable
17. https://stackoverflow.com/questions/7079301/how-do-i-format-the-scrollbar-style-on-a-textarea
18. https://css-tricks.com/accessible-forms-with-pseudo-classes/
19. https://web.dev/articles/control-focus-with-tabindex
20. https://www.w3schools.com/jsref/dom_obj_checkbox.asp
21. https://www.w3schools.com/howto/howto_js_toggle_dark_mode.asp

What's next?
I will comeback to this project to add a "real" submit action
And maybe make it even more responsive
*/

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.