Search code examples
javascriptformshandlebars.js

Form: onsubmit not taking return value from a function


I am currently a beginner in webdevlopment sector(and also new in stackoverflow..srry in advance for poor question format).Basically, i am having issues with the onsubmit event which is not taking the return value from the function which is being called....the function is:

  function checkUnique1() {
var ok = true;
socket.emit('eCheck', {email: document.getElementsByName("email")[0].value});
socket.on('eValidateMessage', function(obj) {
  if(obj.message == false)
  {

    document.getElementsByName("email")[0].style.borderColor = "#E34234";
    document.getElementById("emailExist").innerHTML = "Email has not been registered";
    document.getElementById("emailExist").style.color = "#E34234";
    ok = false;
  }
});


return ok;}

I am using this function to check if email is present in database or not..if it is present the function should return true and onsubmit should fire else it will return false and onsubmit wont fire and the form wont be submitted....here is my form:

<form class="form-horizontal" action="/forgotPass" onsubmit="return checkUnique1()"  method="post" id="formid">
<div class="form-group">
  <label class="control-label col-sm-4"><h1>Creators Space</h1></label>
  <div class="col-sm-8">
  </div>
</div>
<div class="form-group">
  <label class="control-label col-sm-2"></label>
  <div class="col-sm-10">
      <label class="control-label">Please enter the email registered with Creators Space</label>
  </div>
</div>
<div class="form-group">
  <label class="control-label col-sm-2" for="email">Email:</label>
  <div class="col-sm-6">
    <input type="email" class="form-control" name="email" onclick="emailRSet()" onkeypress="emailRSet()" placeholder="Enter email" required title="email (format: [email protected]/[email protected])" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$">
    <span id="emailExist"></span>
  </div>
</div>
<div class="form-group">
  <div class="col-sm-offset-2 col-sm-10">
    <button type="submit" class="btn btn-primary" value="submit">Submit</button>
  </div>
</div>

now this works good in when all the above code is in an html file but when I do the same thing in handlebars template the function doesnt seem to return any value so form is being submitted in both cases. How can I do the same in an handlebars template???What could be the problem??

Please let me know if you need more info


Solution

  • The function on socket.on(function) probably executes asynchronously (that is, not right away, but some time in the future), so when that return ok executes, the function on socket.on(function) has not been executed yet, thus ok still has value of true.

    Maybe something like the below would work:

    function checkUnique1() {
        // make sure only the submit button of that form matches this selector
        var submitButton = document.querySelector("form.form-horizontal button[value='submit']");
        var typedEmail = document.getElementsByName("email")[0].value;
    
        // disable the submit button upon click to prevent multiple submits
        submitButton.disabled = true;
    
        if (window.validatedEmail === typedEmail) {
           // email has been validated, submit form
           return true;
        } else {
          // email has not been validated, request validation
          socket.emit('eCheck', {email: document.getElementsByName("email")[0].value});
          socket.on('eValidateMessage', function(obj) {
            if(obj.message == false)
            {
              document.getElementsByName("email")[0].style.borderColor = "#E34234";
              document.getElementById("emailExist").innerHTML = "Email has not been registered";
              document.getElementById("emailExist").style.color = "#E34234";
    
              // re-enables the submit button, since the email was not validated
              submitButton.disabled = false;
              // clears validatedEmail (since validation failed, no email has been validated)
              window.validatedEmail = null;
            }
            else {
              // 'marks' the typed e-mail as validated
              window.validatedEmail = typedEmail;
    
              // make sure only that form matches this selector
              document.querySelector("form.form-horizontal").submit();
            }
          });
          return false;
        }
    }
    

    The code above creates a global variable window.validatedEmail with the last email that has been validated.

    Link with a demo fiddle for debugging: https://jsfiddle.net/acdcjunior/3v52u69u/2/ (it has some changes from the answer, since I didn't have access to your websocket, I used a different one, so I had to make some adaptations).

    Code breakdown

    Per comment:

    if (window.validatedEmail === typedEmail) part..like what is window.validatedEmail doing and why are you checking if it is equal to typedEmail?

    When the form submits, the code checks if there is a (global) variable window.validatedEmail and, if there is, if it is equal to the typed email (typedEmail).

    When the form is first submitted, that if will be false, since there will be no window.validatedEmail. Now, when that if is false we go to the else part. The else part just makes a validation request to the websocket (socket.emit) and registers a listener function (socket.on('eValidateMessage', function(obj) { ... }) that will be executed when the validation responds.

    When the validation responds and function(obj) { ... } is executed, it does the following: if the validation message tells us that the email was not validated (that is, obj.message == false), then it adds the error messages and enables the submit button back, so the user can press it again after she changes the email.

    Now, on the other hand, if the validation message tells us that the email was validated (which is the else part of the if inside function(obj) { ... }), then we save the typedEmail (which we know has just been validated) in the global variable window.validatedEmail and re-submit the form.

    This time, when the form is re-submitted, it will, as usual, first check if the global variable window.validatedEmail exists and if it is equal to typedEmail. What is different now is that window.validatedEmail do will exist -- because we have saved it in the else part of the function(obj) { ... }.

    And since it exists and is equal to typedEmail, then we simply return true, which will allow the form to be submitted.