-1

I am trying to write a simple form with some basic validation, but the pressing the submit button bypasses event.preventDefault(); and the form gets submitted anyway.

function myFunction() {
  if(document.getElementById("username").val() == ''){
    alert('Please enter a username');
    event.preventDefault();
  }
}

This is the code for the form, the username input field, and the submit button:

<form method ="POST" action="db/registerinsert.php" class="content formregister" id="registerform">
  <div class="content formcontact">
    <section class="section">
      <div class="columns">
        <div class="column is-8 is-offset-2">
          <div class="field">
            <label class="label">Username</label>
            <div class="control has-icons-right">
              <input class="input" name="username" id= "username" type="text" placeholder="" required="">
            </div>
          </div>
          <div class="field is-grouped">
            <div class="control">
              <button class="button is-link" type="submit" onclick="javascript:myFunction()" Value="Submit">Submit</button>
            </div>
          </div>
        </div>
      </div>
    </section>
  </div>
</form>

I also have required="" on the <input> field but leaving the field empty doesn’t trigger this either.

TylerH
  • 20,799
  • 66
  • 75
  • 101
DanS
  • 19
  • 7
  • I'm still getting the alert with either .val or .value and then it moves onto the insert page? And i dont appear to be getting any errors. really strange. – DanS Feb 12 '21 at 21:20
  • I am getting the alert. But it still continues onto the insert page. Fixed the .value as you mentioned and changed to an addEventListener. – DanS Feb 12 '21 at 21:35

2 Answers2

2

There are a few tiny mistakes. The important ones are:

  • Incorrectly retrieving the <input> value
  • Not listening for the submit event

But using obsolete features like the global event or using onclick attributes will also lead to trouble, eventually.

The <input> value

<input> elements don’t have a val method. Don’t confuse jQuery with the native DOM API. jQuery uses the val method, whereas the native DOM API uses the value property.

Your function will throw Uncaught TypeError: document.querySelector(...).val is not a function on invocation.

The value you want to compare is either one of these:

document.getElementById("username").value // Native DOM; let’s stick with this one
document.querySelector("#username").value // Native DOM
$("#username").val() // jQuery

You can also append a .trim() to any of them if you want to disallow whitespace-only inputs, too.

The comparison

== and != are almost never recommended. They’re not always intuitively transitive since they oftentimes unnecessarily perform type coercion. Use === and !== instead.

The if condition therefore should look like this:

if(document.getElementById("username").value === ""){ /* … */ } // Native DOM

The event object

The way you’ve used event.preventDefault(); uses the obsolete global window.event. It’s not recommended. Use the event argument instead. See What exactly is the parameter e (event) and why pass it to JavaScript functions?.

The proper event type and event target

Clicking the submit button is only one way of submitting a form. You could press Enter as well. Think about it: what is it that you want to prevent? You want to prevent form submission. So listen for the submit event instead. You’d do this on the <form>, not the <button>. Only <form> events dispatch submit events.

Naming conventions

Not crucial, but to avoid confusion in the last step, I’m going to rename id="registerform" to id="registerForm", since JavaScript uses camelCase in several places.

Binding the event and bringing everything together

Inline event handlers like onclick or onsubmit are not recommended. They are an obsolete, hard-to-maintain and unintuitive way of registering events. Always use addEventListener or jQuery’s .on instead.

This is the event binding, using native DOM APIs. It also uses arrow functions.

document.getElementById("registerForm").addEventListener("submit", (event) => {
  if(document.getElementById("username").value === ""){
    event.preventDefault();
    alert("Please enter a user name.");
  }
});

Using jQuery:

$("#registerForm").on("submit", (event) => {
  if($("#username").val() === ""){
    event.preventDefault();
    alert("Please enter a user name.");
  }
});

In the HTML, remove onclick completely. You’ve also thrown in a javascript: label for some reason…

Finally, <button>s don’t really use a value attribute. Their tag content is already sort of their value.

<form id="registerForm" class="content formregister" method="POST" action="db/registerinsert.php">
  <!-- Omitting stylistic containers -->
  <input id="username" name="username" class="input" type="text" required="required">
  <button class="button is-link" type="submit">Submit</button>
</form>

Alternative: reportValidity and checkValidity

You’ve included a required attribute. The way to make use of this is to call reportValidity or checkValidity on the form. Note that these methods don’t have full browser support yet, as of 2021.

document.getElementById("registerForm").addEventListener("submit", (event) => {
  if(!event.target.reportValidity()){
    event.preventDefault();
  }
});

Using reportValidity, the browser UI will already display a message like “Please fill out this field” if it’s empty. The similar method checkValidity will also work the same way in the JS, but won’t show the user a message, so your custom alert can be reintroduced.

See the MDN articles on form validation and constraint validation for more, e.g. setting patterns.


Alternative: requestSubmit

There’s a new API, called requestSubmit which simplifies form validation, but isn’t well supported as of 2021. This relies on the required attribute.

document.querySelector("registerForm button[type='submit']")
  .addEventListener("click", ({target}) => target.form.requestSubmit(target));
<form id="registerForm" class="content formregister" method="POST" action="db/registerinsert.php">
  <!-- Omitting stylistic containers -->
  <input id="username" name="username" class="input" type="text" required="required">
  <button class="button is-link" type="submit">Submit</button>
</form>

The JS above also uses destructuring assignment and the form property.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
-1

I am not sure if this is what you want but if you want to cancel the submit action you should pass the event as a parameter to the function like this:

const form = document.querySelector('form');
form.addEventListener('submit', myFunction);

`function myFunction(e) {
   if(document.querySelector(".input").value == ''){
      alert('Please enter a username');
      e.preventDefault();
   }
}

Hope it Helps

Samuel
  • 39
  • 3