1

Based on some JSON I recieve from an ajax request, I wish to either allow or deny a submit button press (return true/false).

I've attempted to implement a promise, however, I can still see 'product unavailable' is called before I recieve my ajax response.

Is the issue down to it being a form/submit button? Or is this still possible?

var oAH = {

    ValidateSubmit : function(self){

        // send request to handler
        $.ajax({
            type: "POST",
            url: "",
            data: aData,
            cache: false})
        .done(function(data) {

            var oJSON = JSON.parse(data);
            if(oJSON.Status === 1){
                // return true to allow form to submit
                return true;
            }else{
                console.log('product unavailable (error message)');
                return false;
            }
        })


    }
}


// click handler
$('#submitButton').on('click', function(){
    return oAH.ValidateSubmit(this);
}
atoms
  • 2,993
  • 2
  • 22
  • 43
  • shouldn't `'product unavailable'` be an `else` statement to your `Status === 1` check? – Adelin Jan 12 '18 at 14:56
  • yeah it should, will update my answer now. Unfortnatly though, thats not the issue – atoms Jan 12 '18 at 14:57
  • 1
    Because of the asynchronous nature of ajax, the validaesubmit function would have already returned before the ajax request finishes. Also returning from a function defined in another function has no effect on the other function. – Musa Jan 12 '18 at 15:00
  • What is the type of your button? Is it `submit` or `button` ? – kiranvj Jan 12 '18 at 15:00
  • its a submit button. Thanks musa, I was actually setting a var and returnign that instead of inside the promise. Didnt think when simplying code fior here, it would be an issue – atoms Jan 12 '18 at 15:00
  • I would suggest doing the validation before the button is pressed, i.e. have the button disabled, uses some other method to trigger the ajax call then when you get the desired response enable the button. – Musa Jan 12 '18 at 15:02
  • Musa is absolutely right. That means you can't use a return from the click event. Instead, invoke the proper result handler from the done function. – erik258 Jan 12 '18 at 15:03
  • please could you provide an example Dan? – atoms Jan 12 '18 at 15:04

2 Answers2

5

You have number of issues. The most obvious one is that you can't just return from asynchronous code (promise) to use its return value (it's undefined!).

What you need to do is

  1. prevent form submission by default for all cases.
  2. treat promise properly and check returned flag. If it's true, submit form manually using DOM API (form submit method).
  3. make sure you use onsubmit event instead of button onclick.

All together it would look something like this:

var oAH = {

  ValidateSubmit: function(self) {

    // send request to handler
    return $.ajax({
      type: "POST",
      url: "",
      data: aData,
      cache: false
    })
      .then(function(data) { // <----- make sure you use .then
        return data.Status === 1;
      });
  }
}


// form onsubmit handler, form has id form for example, etc.
$('#form').on('submit', function(e) {
  var form = this;
  e.preventDefault()

  return oAH.ValidateSubmit(this)
    .then(function(canSubmit) {
      if (canSubmit) {
        form.submit();
      }
    });
});
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • 1
    Also you don't need to parse response, if it's JSON jquery will parse it for you. `return oJSON.Status === 1;` is all you need to return. – dfsq Jan 12 '18 at 15:07
  • you the man! Many thanks dfsq, exactly what I needed :) wondering why the downvotes though... – atoms Jan 12 '18 at 15:16
1

I think what you try to do is not possible. The UI event must be processed at the moment and the ajax request is async. You could prevent form submiting when clicked, disable button and wait for ajax to return a value and then submit form or not in a callback, something like this:

var oAH = {
    ValidateSubmit : function(self){

        // send request to handler
        $.ajax({
            type: "POST",
            url: "",
            data: aData,
            cache: false})
        .done(function(data) {

            var oJSON = JSON.parse(data);
            if(oJSON.Status === 1){
                // return true to allow form to submit
                submitForm();
            }else{
                console.log('product unavailable (error message)');
            }
        })


    }
}

function submitForm() {
    $('#myForm').submit();
    $('#submitButton').removeAttr('disabled');
}

// click handler
$('#submitButton').on('click', function(e){
    //prevent submitting
    e.preventDefault();
    // Disable, you could show a loading animation/gif
    $(this).attr('disabled','disabled');
    // call ajax
    oAH.ValidateSubmit(this);
}
Gonzalo
  • 1,781
  • 15
  • 29