I made a subscription form. I divided questions in four pages and I am trying to use JavaScript code in order to hide pages and show the page I am going to with Next button. It worked well when I only had Next buttons. But from the moment I added Previous buttons, it don't have the expected effect : I can go to the second part of the form but at the second click (on Previous or Next button), all parts of the form disappear.
How is it possible to make it work ?
html.twig
{% extends 'base.html.twig' %}
{% block title %}Incris-toi !{% endblock %}
{% block main %}
<main >
<header></header>
{{form_start(userform)}}
<div >
<div >
{{form_widget(userform.email, {'attr' : {'placeholder' : 'Mon adresse e-mail', 'class' : 'form-control'}})}}
{{form_label(userform.email, 'Mon adresse e-mail', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.password.first, {'attr' : {'placeholder' : 'Mon mot de passe', 'class' : 'form-control'}})}}
{{form_label(userform.password.first, 'Mon mot de passe', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.password.second, {'attr' : {'placeholder' : 'Confirmation de mon mot de passe', 'class' : 'form-control'}})}}
{{form_label(userform.password.second, 'Confirmation de mon mot de passe', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.roles)}}
<span ></span>
<span ></span>
</div>
<button type="button" >Je m'inscris</button>
</div>
<div >
<h1 >Pour savoir qui tu es.</h1>
<div >
{{form_widget(userform.gender, {'attr' : {'placeholder' : 'Es-tu un homme ou une femme ?', 'class' : 'form-control'}})}}
{{form_label(userform.gender, 'Es-tu un homme ou une femme ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.firstname, {'attr' : {'placeholder' : 'Quel est ton prénom ?', 'class' : 'form-control'}})}}
{{form_label(userform.firstname, 'Quel est ton prénom ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.lastname, {'attr' : {'placeholder' : 'Quel est ton nom de famille ?', 'class' : 'form-control'}})}}
{{form_label(userform.lastname, 'Quel est ton nom de famille ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
<p>Quelle est ta date de naissance ?</p>
{{form_widget(userform.birthdate, {'select' : {'class' : 'form-select'}})}}
</div>
<div >
<button type="button" >Précédent</button>
<button type="button" >Suivant</button>
</div>
</div>
<div >
<h1 >Pour mieux te connaître.</h1>
<div >
{{form_widget(userform.occupation, {'attr' : {'placeholder' : 'Quelle est ton occupation (ton métier, tes études…) ?', 'class' : 'form-control'}})}}
{{form_label(userform.occupation, 'Quelle est ton occupation (ton métier, tes études…) ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.nationality, {'attr' : {'placeholder' : 'Quelle est ta nationalité ?', 'class' : 'form-control'}})}}
{{form_label(userform.nationality, 'Quelle est ta nationalité ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.nativelanguage, {'attr' : {'placeholder' : 'Quelle est ta langue maternelle ?', 'class' : 'form-control'}})}}
{{form_label(userform.nativelanguage, 'Quelle est ta langue maternelle ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<button type="button" >Suivant</button>
</div>
<div >
<h1 >Et savoir ce que tu viens faire ici.</h1>
<div >
{{form_widget(userform.wishedlanguages, {'attr' : {'placeholder' : 'Quelle(s) langue(s) souhaites-tu pratiquer ?', 'class' : 'form-control'}})}}
{{form_label(userform.wishedlanguages, 'Quelle(s) langue(s) souhaites-tu pratiquer ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<button >Je valide mon inscription</button>
</div>
{{form_end(userform)}}
</main>
{% endblock %}
{% block js %}
<script src="../assets/js/scripts.js"></script>
{% endblock %}
scripts.js
const pages = document.querySelectorAll(".formpage")
window.onload = () => {
document.querySelector(".formpage").style.display = "initial"
let nextbutton = document.querySelectorAll(".next")
for(let button of nextbutton) {
button.addEventListener("click", nextPage)
}
let prevbutton = document.querySelectorAll(".prev")
for(let button of prevbutton) {
button.addEventListener("click", previousPage)
}
}
function nextPage(){
for(let page of pages){
page.style.display = "none"
}
this.parentElement.nextElementSibling.style.display = "initial"
}
function previousPage(){
for(let page of pages){
page.style.display = "none"
}
this.parentElement.previousElementSibling.style.display = "initial"
}
CodePudding user response:
The problem is technically a logical error. Your HTML is different for page 1 and at least page 2.
Read the comments in the following code:
<div >
<h1 >Inscris-toi sur
<img src="../public/img/logo-gozpeak.png" alt="Logo Go Zpeak !" width="auto" height="60" >
</h1>
<div >
{{form_widget(userform.email, {'attr' : {'placeholder' : 'Mon adresse e-mail', 'class' : 'form-control'}})}}
{{form_label(userform.email, 'Mon adresse e-mail', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.password.first, {'attr' : {'placeholder' : 'Mon mot de passe', 'class' : 'form-control'}})}}
{{form_label(userform.password.first, 'Mon mot de passe', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.password.second, {'attr' : {'placeholder' : 'Confirmation de mon mot de passe', 'class' : 'form-control'}})}}
{{form_label(userform.password.second, 'Confirmation de mon mot de passe', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.roles)}}
<span ></span>
<span ></span>
</div>
<!-- This isn't enclosed inside an element, hence its parent is the .formpage element above -->
<button type="button" >Je m'inscris</button>
</div>
<div >
<h1 >Pour savoir qui tu es.</h1>
<div >
{{form_widget(userform.gender, {'attr' : {'placeholder' : 'Es-tu un homme ou une femme ?', 'class' : 'form-control'}})}}
{{form_label(userform.gender, 'Es-tu un homme ou une femme ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.firstname, {'attr' : {'placeholder' : 'Quel est ton prénom ?', 'class' : 'form-control'}})}}
{{form_label(userform.firstname, 'Quel est ton prénom ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
{{form_widget(userform.lastname, {'attr' : {'placeholder' : 'Quel est ton nom de famille ?', 'class' : 'form-control'}})}}
{{form_label(userform.lastname, 'Quel est ton nom de famille ?', {'label_attr' : {'class' : 'label'}})}}
</div>
<div >
<p>Quelle est ta date de naissance ?</p>
{{form_widget(userform.birthdate, {'select' : {'class' : 'form-select'}})}}
</div>
<!-- This is enclosed inside a div element, hence its parent is NOT the .formpage element above -->
<div >
<button type="button" >Précédent</button>
<button type="button" >Suivant</button>
</div>
</div>...
Now one straightforward solution is to encapsulate the button on the first page around a div
as well.
BTW, there is no need to iterate over all pages and set display: none
on each one separately. Instead, you could make this a little bit more efficient by simply setting display: none
on the current div
.
Below is a better definition of nextPage()
:
function nextPage(){
// Inefficient
//for(let page of pages){
// page.style.display = "none"
//}
this.parentElement.style.display = 'none';
this.parentElement.nextElementSibling.style.display = "initial"
}