0

I am trying a sign up page for the first time, using the required element. Frustratingly, this was working before but I guess I changed something and now it doesn't and I can't figure out what I'm missing here.

What I want to happen: When I click the submit button, one of two things will happen. It will either tell me I haven't input the required values and not submit (if I leave the values empty), or it will submit (if i have put in the values) and change the content to 'thanks' and will create an object of the user, which will be added to an array.

What is currently happening: I can only get one OR the other working, depending on how I query select the input type=submit button. If I have const submitButton = document.querySelector('button[type=submit]');it ensures that I need the required values to trigger the eventlistener, but it won't actually trigger the event and I get this in the console:

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

If I take away the button and have const submitButton = document.querySelector('[type=submit]');the event triggers as it should (goes to thank you message, makes an object, adds to the list) but it doesn't stop it from submitting if the required values are empty.

I've tried various ways of re-writing it (including '[type="submit"]') but its not working and I assume I'm missing something simple here? Any help is appreciated. CSS completely works, so I'll paste my html and js in case anyone needs it.

HTML:

            <div class="rightside-content">

                    <div class="signup-title">
                        <h1>Sign up</h1>
                    </div>
                    <form class="join-form">

                        <ul>
                            <li><input type="text" name="username" class="username" placeholder="Username" required></li>

                            <li><input type="text" name="fullname" class="fullname" placeholder="Full Name" required></li>
                            
                            <li><input type="email" name="email" class="email" placeholder="Email Address" pattern=".+@gmail\.com" required></li>
                            
                            <li><input type="text" name="phone" class="phone" placeholder="Phone Number" required></li>

                            <li><input type="text" name="postcode" class="postcode" placeholder="Post Code" required></li>
                        
                            <li><input type="password" name="password" class="password" placeholder="Enter a password" required></li>
                        </ul>
                        <input type="submit">
                    </form>
                </div>

            </div>

        </div>

JS:

const submitButton = document.querySelector('[type="submit"]');
const registerForm = document.querySelector(".rightside-content");

const userName = document.querySelector(".username");
const fullName = document.querySelector(".fullname");
const emailAddress = document.querySelector(".email");
const contactNumber = document.querySelector(".phone");
const postCode = document.querySelector(".postcode");
const Password = document.querySelector(".password");

let users = [];
let user = {userName: userName.value, fullName: fullName.value, emailAddress: emailAddress.value, contactNumber: contactNumber.value, postCode: postCode.value, Password: Password.value};
let count = 0;

submitButton.addEventListener("click", (e) =>{
    e.preventDefault();

    user.userName = userName.value;
    user.fullName = fullName.value;
    user.emailAddress = emailAddress.value;
    user.contactNumber = Number(contactNumber.value);
    user.postCode = Number(postCode.value);
    user.Password = Password.value;

    users.push(user);
    console.log(users);
    console.log(users.length);

    registerForm.innerHTML = 'Thank you for joining!';
    registerForm.style.fontSize = '1.5rem';
    registerForm.style.fontFamily = 'Segoe UI, Tahoma, Geneva, Verdana, sans-serif';
    registerForm.style.textAlign = 'center';
    registerForm.style.marginTop = '50%'; 
    
    users[count] = user;
    count = count + 1;
})

EDIT FOR FUTURE PEOPLE: a couple answers helped a lot, but if you need to continue with the [addEventListener] element, I found that having it as formname.addeventlistener("submit"....) also fixed my issue (as suggested by AchoVasilev's comment)

paparonnie
  • 170
  • 8
  • 2
    Why don't you add the event listener to the form and listen for the submit event? That way you won't need to get every element by the query selector, you will get the form data from the submit event. Also you should add checks if the input is valid in your function and only after they are valid to continue to change the html of the form. – AchoVasilev Jun 24 '22 at 04:24
  • https://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element – epascarello Jun 24 '22 at 04:41
  • @epascarello: Not related. It’s an `` that matches `[type=submit]` but not `button[type=submit]`. – Ry- Jun 24 '22 at 04:43

3 Answers3

1

Just add onsubmit event on your form, like this:

<form class="join-form" onsubmit="event.preventDefault(); return fn(this)">

And replace your submitButton.addEventListener("click", (e) =>{....} with the following function.

function fn(e) {
            user.userName = userName.value;
            user.fullName = fullName.value;
            user.emailAddress = emailAddress.value;
            user.contactNumber = Number(contactNumber.value);
            user.postCode = Number(postCode.value);
            user.Password = Password.value;

            users.push(user);
            console.log(users);
            console.log(users.length);

            registerForm.innerHTML = 'Thank you for joining!';
            registerForm.style.fontSize = '1.5rem';
            registerForm.style.fontFamily = 'Segoe UI, Tahoma, Geneva, Verdana, sans-serif';
            registerForm.style.textAlign = 'center';
            registerForm.style.marginTop = '50%';

            users[count] = user;
            count = count + 1;
        }
1

The following should do the job with a lot less code to write and maintain:

const users=[], msg=document.getElementById("msg");
document.querySelector("form").onsubmit=ev=>{let usr;
 users.push(usr=Object.fromEntries( [...ev.target.querySelectorAll("ul input")].map(e=>[e.name,e.value])));
 console.log(users);
 msg.textContent=`Thank you for joining, ${usr.fullname}!`
 return false;
}
form li {display:block}
<div class="rightside-content">
  <div class="signup-title">
    <h1>Sign up</h1>
  </div>
  <form class="join-form">
    <ul>
      <li><input type="text" name="username" class="username" placeholder="Username" required></li>
      <li><input type="text" name="fullname" class="fullname" placeholder="Full Name" required></li>
      <li><input type="email" name="email" class="email" placeholder="Email Address" pattern=".+@gmail\.com" required value="asv@gmail.com"></li>
      <li><input type="text" name="phone" class="phone" placeholder="Phone Number" required></li>
      <li><input type="text" name="postcode" class="postcode" placeholder="Post Code" required></li>
      <li><input type="password" name="password" class="password" placeholder="Enter a password" required></li>
    </ul>
    <input type="submit">
  </form>
  <div id="msg"></div>
</div>
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
0

Bind the <form> to the "submit" event:

form.addEventListener("submit", (e) => {//...

Also,

  • you don't really need a count if you have .length.
  • FormData() is kinda the same thing as user object (your way seems a lot easier though).
  • the syntax used is from the HTMLFormElement interface.
  • don't convert phone and zipcode values to numbers, unless you intend to sort them.
  • changed .phone type to tel

const form = document.forms.join;
const IO = form.elements;

const id = IO.username;
const name = IO.fullname;
const email = IO.email;
const cell = IO.phone;
const zip = IO.postcode;
const pass = IO.password;

let users = [];
let user = {};

form.addEventListener("submit", (e) => {
  e.preventDefault();

  user.id = id.value;
  user.name = name.value;
  user.email = email.value;
  user.cell = cell.value;
  user.zip = zip.value;
  user.pass = pass.value;

  users.push(user);
  console.log(users);
  console.log(users.length);

  form.innerHTML = 'Thank you for joining!';
  form.style.fontSize = '1.5rem';
  form.style.fontFamily = 'Segoe UI, Tahoma, Geneva, Verdana, sans-serif';
  form.style.textAlign = 'center';
  form.style.marginTop = '50%';

});
<form id="join">

  <ul>
    <li><input type="text" name="username" class="username" placeholder="Username" required></li>

    <li><input type="text" name="fullname" class="fullname" placeholder="Full Name" required></li>

    <li><input type="email" name="email" class="email" placeholder="Email Address" pattern=".+@gmail\.com" required></li>

    <li><input type="tel" name="phone" class="phone" placeholder="Phone Number" required></li>

    <li><input type="text" name="postcode" class="postcode" placeholder="Post Code" required></li>

    <li><input type="password" name="password" class="password" placeholder="Enter a password" required></li>
  </ul>
  <input type="submit">
</form>
zer00ne
  • 41,936
  • 6
  • 41
  • 68