1

I have a form, which I'd like to validate, then if valid, run a JavaScript function. For this, I have:

function updateMap() {
  //dummy
}
<form>
  <div class="group">
    <input type="number" id="hour" min="0" max="23" required>
    <span class="highlight"></span>
    <span class="bar"></span>
    <label>Hour of the day (0-23)</label>
  </div>
  <div class="group">
    <select class="weekselection" id="weekday" required>
      <option value="" disabled selected>Choose the weekday</option>
   <option value="0">Monday</option>
   <option value="1">Tuesday</option>
   <option value="2">Wednesday</option>
   <option value="3">Thursday</option>
   <option value="4">Friday</option>
   <option value="5">Saturday</option>
   <option value="6">Sunday</option>
  </select>
  </div>
  <div class="group">
    <select class="methodelection" id="normalization" required>
   <option value="" disabled selected>Choose data handling</option>
   <option value="0">Normalized data</option>
   <option value="1">Unnormalized data</option>
   <option hidden value="2">Normalization not needed in baseline</option>
  </select>
  </div>

  <div class="group">
    <select class="methodelection" id="method" onchange="setNormSelection()">
   <option value="" disabled selected>Choose the method</option>
   <option value="0">Baseline (daily/hourly mean)</option>
   <option value="1">SGD Regressor</option>
   <option value="2">Decision Tree</option>
   <option value="3">Neural Network - Multi-Layer Perceptron</option>
  </select>
  </div>
  <button type=button onClick="updateMap()">Show prediction!</button>
</form>

This works, however I'd like to actually check the validity of the fields. If in this code I'm sweitching to <button type=submit onSubmit="updateMap()">Show prediction!</button>, the validation works fine, but if the fields are filled, the updateMap() function doesn't get called, the page just flashes as if it's updated itself to default. What am I missing?

lte__
  • 7,175
  • 25
  • 74
  • 131
  • If your event handler does not do anything to prevent the natural browser behavior of a "submit" button, the form will be submitted. – Pointy May 06 '17 at 12:44
  • OK, my main goal is to get the same functionality as `onclick=updateMap()` would have, BUT with HTML5 form validation. What do I do? – lte__ May 06 '17 at 12:45

3 Answers3

0

var form = document.querySelector('#personal-form'),
    nameField = document.querySelector('#form-name'),
    ageField = document.querySelector('#form-age');

var Main = {
  onFormSubmit: function(e){
    if (Main.formIsValid()) {
      alert('Form is valid, but we will not send it');
      e.preventDefault(); // remove if you want to send the form instead
    } else {
      alert('Form is invalid');
      e.preventDefault();
    }
  },
  formIsValid: function() {
    return nameField.value.length > 0 && parseInt(ageField.value) > 13;
  }
};

form.addEventListener('submit', Main.onFormSubmit);
* {
  box-sizing: border-box;
}

form > div {
  clear: both;
}

form label {
  float: left;
  width: 150px;
  padding: .2em .5em;
  text-align: right;
}

form .actions {
  margin-left: 150px;
}
<form id="personal-form">
  <div>
    <label for="form-name">Name</label>
    <input name="name" id="form-name">
  </div>
  <div>
    <label for="form-age">Age</label>
    <input type="number" name="age" id="form-age" min="0" max="150">
  </div>
  <div class="actions">
    <button type="submit">That's all!</button>
  </div>
</form>
Wiktor Bednarz
  • 1,553
  • 10
  • 15
0

The way <form> elements work is that they contain various form fields (text boxes, checboxes, radio buttons, etc.) as well as a way for all for form field data to be submitted somewhere (via a submit button).

When the submit button is clicked, all the name and value data form field elements within the <form> element (or attached to it via the form attribute) is sent to the location specified in the form's action attribute and the data is sent according to the value specified in the form's method attribute. This means that when the form is submitted, the browser will redirect and load the response from the location specified in the action. This is normal and part of the form submit process. Of course, this does mean that the current page will unload. This unloading/loading process has come to be known as a "postback". More modern approaches to sending data to the server, like AJAX, avoid the postback and allow the response from the server to be received without the current page being unloaded.

Now, to validate entries into a form, you'll want to set up an event handler for the form's submit event - - not the click event of the submit button. This can seem a little counter-intuitive at first but when you click a submit button, two events fire off - the button click and then the form submit.

In the function that is connected to the form's submit event, you do your validation according to whatever logic you want. Only if you determine that there is something invalid about the form data, you cancel the submit event, thus preventing the data from going anywhere and preventing the postback.

Lastly, don't use inline HTML event attributes (onclick, onsubmit, etc.). See this for why. Instead, do all your event binding in a dedicated JavaScript area and use the modern and standard .addEventListener() object method.

Here is a scaled down example:

// Get references to the HTML elements you'll need access to:
var theForm = document.querySelector("form");
var txtUser = document.getElementById("txtUser");
var btnSubmit = document.getElementById("btnSubmit");

// Now, we'll define our validation function.
function validate(evt){
  
  // This will keep track of whether we determine there is an error or not
  var error = false;
  
  // Always call .trim() on user input. It strips off any leading or trailing
  // spaces in the input.
  if(txtUser.value.trim() === ""){
    // There is no data in the text box!
    error = true;
    alert("You didn't enter your name!");
  }
  
  // Other validations would go here and they would set error = true if
  // they fail.
  
  // After all the validations, we determine if the event should be cancelled
  if(error){
    evt.preventDefault();      // Cancel the form submission
    evt.stopPropagation();     // Cancel event propagation to other objects  
  } else {
    // This else section is normally not needed, but you said you wanted to
    // run another function if the form was valid, so this is the place to do that
    otherFunction();
  }
}

// Set up your submit event handler. We do this in JavaScript these days
// not in the HTML with onsubmit.
theForm.addEventListener("submit", validate);

function otherFunction(){
  alert("Other function when data is valid is running!");
}
<form action="#" method="post">

  <input type="text" name="txtUser" id="txtUser">
  <input type="submit" value="Submit" id="btnSubmit">

</form>
Community
  • 1
  • 1
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
-1

use like this onsubmit not in button attribute its a form attribute

<from onsubmit="return updateMap()"> 
  <button type="submit" >Show prediction!</button>
</form>

Try this code

function updateMap(e) {
  e.preventDefault(); //the will prevent from page refresh if not 

  //apply you validation code


  return false; // the will prevent from page refresh .
}
<form onsubmit="return updateMap(event)">
  <div class="group">
    <input type="number" id="hour" min="0" max="23" required>
    <span class="highlight"></span>
    <span class="bar"></span>
    <label>Hour of the day (0-23)</label>
  </div>
  <div class="group">
    <select class="weekselection" id="weekday" required>
      <option value="" disabled selected>Choose the weekday</option>
   <option value="0">Monday</option>
   <option value="1">Tuesday</option>
   <option value="2">Wednesday</option>
   <option value="3">Thursday</option>
   <option value="4">Friday</option>
   <option value="5">Saturday</option>
   <option value="6">Sunday</option>
  </select>
  </div>
  <div class="group">
    <select class="methodelection" id="normalization" required>
   <option value="" disabled selected>Choose data handling</option>
   <option value="0">Normalized data</option>
   <option value="1">Unnormalized data</option>
   <option hidden value="2">Normalization not needed in baseline</option>
  </select>
  </div>

  <div class="group">
    <select class="methodelection" id="method" onchange="setNormSelection()">
   <option value="" disabled selected>Choose the method</option>
   <option value="0">Baseline (daily/hourly mean)</option>
   <option value="1">SGD Regressor</option>
   <option value="2">Decision Tree</option>
   <option value="3">Neural Network - Multi-Layer Perceptron</option>
  </select>
  </div>
  <button type="submit">Show prediction!</button>
</form>
prasanth
  • 22,145
  • 4
  • 29
  • 53
  • But if I do this, `onClick` gets triggered regardless of the field values. So no checking takes place. – lte__ May 06 '17 at 12:38
  • I need `onsubmit`, but then that just reloads the whole page. – lte__ May 06 '17 at 12:39
  • you need to prevent the `onsubmit` event .see my updated answer.I was added snippet for you – prasanth May 06 '17 at 12:45
  • Don't use inline HTML event attributes. – Scott Marcus May 06 '17 at 13:00
  • @ScottMarcus why? – prasanth May 06 '17 at 13:01
  • See: http://stackoverflow.com/questions/43459890/javascript-function-doesnt-work-when-link-is-clicked/43459991#43459991 – Scott Marcus May 06 '17 at 13:03
  • You also should never initiate the validation function from the `click` event of the `submit` button (always do it from the `submit` event of the `form`) because a form can be submitted by pressing ENTER when the focus is on other form elements. This means that if a user did that, your validation code (attached to the `submit` button's `click` event would not be triggered and the validation would be bypassed. – Scott Marcus May 06 '17 at 13:07