0

Why is this marked as a duplicate for how to get a response from AJAX? I got the response in the callback function?

I'm using AJAX with PHP to check if a user's authorisation code (basically a password) is valid. This works in so far as it doesn't allow the form to be submitted if the user's input is incorrect against the stored database value. However, it also doesn't allow form submission when correct, despite the JS reaching the callback function and changing the input class's styling to indicate the input is correct.

<form name="auth_form" id="auth_form" method="post" action="auth-action.php">
  <p>Please enter authorisation code.</p>
  <div style="width:400px;" class="form-group has-feedback" id="feedback" name="feedback">
    <input class="form-control" id="authcode" autocomplete="new-password" name="authcode" type="password" required>
    <span id="glyph" name="glyph" class="glyphicon form-control-feedback"></span>
  </div>
  </div>
  <button class="btn btn-primary" name="submit" type="submit">Submit</button>
  </div>
</form>
 $(document).ready(function() {
  $("#authcode").blur(function(e) {
    if (!checkValid()) {
      e.preventDefault();
    }
  });

  $('#auth_form').on('submit', function(e) {
    if (!checkValid()) {
      e.preventDefault();
    }
  });
});

function checkValid() {
  var authcode = $("#authcode").val();
  $.ajax({
    url: 'auth-action.php',
    type: 'POST',
    data: { 'authcode' : authcode },
    success: callback
  })
}

function callback(response) {
  var data = response;
  var IsValid = false;

  if (data.indexOf("success") > -1) {
    $('#feedback').addClass('has-success');
    $('#glyph').addClass('glyphicon-ok');
     $('#feedback').removeClass('has-error');
     $('#glyph').removeClass('glyphicon-remove');
     IsValid = true;
  } else {
     $('#feedback').addClass('has-error');
     $('#glyph').addClass('glyphicon-remove');
     $('#feedback').removeClass('has-success');
     $('#glyph').removeClass('glyphicon-ok');
     IsValid = false;
  }

  return IsValid;
}
sinesine
  • 183
  • 1
  • 11
  • 1
    `checkValid()` doesn't return any value so can't be evaluated true/false. And in any case Ajax is async, so your callback will run at an arbitrary time and you have to wait for a response from that before you know if the data is valid or not. You need to cancel the submit action in all cases, and then use your callback to programmatically submit the form if appropriate. Only in the "callback" function can you decide what to do, before that runs (and afterwards, outside that context) you don't have the necessary information in order to decide. – ADyson Aug 14 '17 at 13:33
  • 1
    As a side note, I would not rely on JS based solutions for validation like this. The code which processes the form submission itself must also validate the data in the same way. Otherwise a malicious user could easily bypass your existing validation (in the simplest scenario, trivially by disabling JS in the browser just before pressing the submit button) and send whatever they like to the server. – ADyson Aug 14 '17 at 13:36
  • @ADyson Thanks for answering. There will be server-side validation but for now I'm just working on the front-end JS. Would you suggest I put something like `$("#auth_form").submit()` below `IsValid = true;`? – sinesine Aug 14 '17 at 13:40
  • Almost. First change. Submit handler simplified to: `$('#auth_form').on('submit', function(e) { e.preventDefault(); checkValid(); });` – ADyson Aug 14 '17 at 13:42
  • callback simplified to: `function callback(response) { var data = response; var IsValid = false; if (data.indexOf("success") > -1) { $("#auth_form").submit(); } else { $('#feedback').addClass('has-error'); $('#glyph').addClass('glyphicon-remove'); $('#feedback').removeClass('has-success'); $('#glyph').removeClass('glyphicon-ok'); } }` No need to have a return value, since it's all async (nowhere to return to). And no need to tediously remove all the error field UI stuff if we're just going to submit the form immediately and destroy it all. – ADyson Aug 14 '17 at 13:43
  • @ADyson Thank you, testing it now. – sinesine Aug 14 '17 at 13:45
  • @ADyson It's still not submitting even after those changes. I still don't understand why `IsValid` is always returning false? – sinesine Aug 14 '17 at 13:50
  • ?? IsValid does not get returned to anywhere. the `checkvalid()` function doesn't return a value. Your original version of "callback" returned true/false, but that return value doesn't go anywhere, because that function is executed asynchronously outside the flow of your normal control. Are you now in fact saying that inside the "callback" function, it always shows the error UI, and doesn't submit the form? If so, I would check that the value of `response` is what you expected. – ADyson Aug 14 '17 at 13:54

0 Answers0