1

I have seen numerous examples on here and have tried for hours to get them to work but can't seem to figure out what I am doing wrong. I am very new to jquery and ajax so please be nice.

I am attempting to use the smartWizard jquery plugin. Here is some code

            function validateStep1()
            {
                var isValid = true;


                // validate first_name
                var first_name = $('#first_name').val();
                if(!first_name && first_name.length <= 0)
                {
                    isValid = false;
                    $('#msg_first_name').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_first_name').html('').hide();
                }

                // validate last_name
                var last_name = $('#last_name').val();
                if(!last_name && last_name.length <= 0)
                {
                    isValid = false;
                    $('#msg_last_name').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_last_name').html('').hide();
                }

                // validate address
                var address = $('#address').val();
                if(!address && address.length <= 0)
                {
                    isValid = false;
                    $('#msg_address').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_address').html('').hide();
                }

                // validate city
                var city = $('#city').val();
                if(!city && city.length <= 0)
                {
                    isValid = false;
                    $('#msg_city').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_city').html('').hide();
                }

                // validate county
                /*
                var county = $('#county').val();
                if(!county && county.length <= 0)
                {
                    isValid = false;
                    $('#msg_county').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_county').html('').hide();
                }
                */

                // validate state
                var state = $('#state').val();
                if(!state && state.length <= 0)
                {
                    isValid = false;
                    $('#msg_state').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_state').html('').hide();
                }

                // validate postal
                var postal = $('#postal').val();
                if(!postal && postal.length <= 0)
                {
                    isValid = false;
                    $('#msg_postal').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_postal').html('').hide();
                }

                // validate home_phone
                var home_phone = $('#home_phone').val();
                if(!home_phone && home_phone.length <= 0)
                {
                    isValid = false;
                    $('#msg_home_phone').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_home_phone').html('').hide();
                }


            if(isValid==true)
            {
                document.getElementById('step_num').value=1;

                loading('<?php echo $LANG['saving']; ?> ',1);

                $.post('editprofile.php',$('#editProfile').serialize(),function(data)
                {
                    unloading();
                    if(!data)
                    {
                        isValid = false;
                        $('#msg_step-1').html("<p style='font-weight:bold;color:#ff0000'><?php echo $LANG['database_update_error']; ?></p>").show();
                    }
                    else if(data.status !=1 )
                    {
                        isValid = false;
        alert(data.message);
                        $('#msg_step-1').html("<p style='font-weight:bold;color:#ff0000'>"+data.message+"</p>").show();
                    }
                    else
                    {
                        $('#msg_step-1').html("<p style='font-weight:bold;color:#ff0000'>"+data.message+"</p>").show();
                        isValid = true;
                    }

                },'json')
                .done(function() { alert("done "+isValid); return isValid;})
                .fail(function() { alert("fail "+isValid); return isValid;})
                ;
            }
            else
            {
                return isValid;
            }
          //Commented out the return so that it will only return when done above.
          //return isValid;
        }

There is other code that checks the return value of this function and acts accordingly. If any of the initial validation checks fail, the other code does not execute because the variable isValid is set to false and that is what is returned. My problem is with the post to editprofile.php - The code moves on as if the function had returned a true value even though it has yet to return anything. It still continues on executing the code in $.post section but only after other code outside of this function has run.

I understand that the code is run in asynchronous fashion; however, I am confused as to why WITHOUT EXCEPTION it always gets the false value when any of the checks for things like $('#address').val() return a false value; however, it doesn't get it from the $.post code. Why wait for all of those to return a value but not wait for the $.post code?

I am also confused on how the calling code can act before a value is returned.

Just to documentation sake, here is the code that calls that function:

          function leaveAStepCallback(obj){
                var step_num= obj.attr('rel');
                return validateSteps(step_num);
          }

            function validateSteps(step)
            {
                var isStepValid = true;
                  // validate step 1
                  if(step == 1){
                        if(validateStep1() == false ){
                          isStepValid = false; 
                          $('#wizardvalidate').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:true});         
                        }else{
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:false});
                        }
                  }

                  // validate step 2
                  if(step == 2){
                        if(validateStep2() == false ){
                          isStepValid = false; 
                          $('#wizardvalidate').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:true});         
                        }else{
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:false});
                        }
                  }

                  // validate step3
                  if(step == 3){
                        if(validateStep3() == false ){
                          isStepValid = false; 
                          $('#wizardvalidate').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:true});         
                        }else{
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:false});
                        }
                  }

          return isStepValid;
        }

Once again, I am new to all of this so please be nice! :)

G-J
  • 1,080
  • 2
  • 16
  • 32
  • Actually, jquery NEVER waits for the returned value from an ajax request unless you make it synchronous. Your alerts are confusing you. You can't return from an ajax request's callback properties, it does nothing. – Kevin B Mar 08 '13 at 21:10
  • Because you have AJAX calls only when `isValid` is true. When it's false it goes straight to the `return isValid` (and `isValid === false`). Using `return` in `.done()` and `.fail()` do nothing--you're returning from the anonymous functions, not from the `validateStep1()` function. – JJJ Mar 08 '13 at 21:12
  • **A** jax. Also, in general, please include the *minimal* amount of code necessary to demonstrate the problem, otherwise it takes a fair chunk of time just to determine where the code in question is. – Dave Newton Mar 08 '13 at 21:14
  • possible duplicate of [How to return the response from an AJAX call from a function?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call-from-a-function) – JJJ Mar 08 '13 at 21:15

2 Answers2

0

As you said in your question, $.post is asynchronous.

Its callback will only run when the server replies, which is guaranteed to be some time after the rest of your code finishes executing.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

I was facing the same problem and resolved after few hours of hair pulling...

var stpflag = false;

function validateSteps(step){
    var isStepValid = true;
    // validate step 1
    if(step == 1){
        var returnstatus = savefunctionality();
        if((returnstatus ==  false ) && (stpflag== false)){
            isStepValid = false; 
            $('#wizard').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
            $('#wizard').smartWizard('setError',{stepnum:step,iserror:true}); 
            // $('#wizard').smartWizard.prototype.goBackward();
        }else if((returnstatus ==  false ) && (stpflag== true)){
            isStepValid = true;
            $('#wizard').smartWizard('setError',{stepnum:step,iserror:false});
             $('#wizard').smartWizard('hideMessage','');
            showstep2(); // here write your logic for render next page on step-2 div.
            stpflag=false;
        }
    }
  return isStepValid;
}

function savefunctionality() {

    var returnVal = false;

$.ajax(

{

        type: 'POST',

        dataType: 'json',

        url: '/mainfolder/folder/savepage/',

        async: true,


        data:  values,                  

        success: function(json) {
            $("#error_msg").html("");
            if(json.result.errors != undefined){
                if(json.result.errors.length > 0){
                    itemData = json.result.errors;
         returnVal = false;
                    stpflag = false;

                } 
            } else if(json.result == 1){
                returnVal = true;
                stpflag = true;
                $('a.buttonNext').trigger('click');
            }
        }
    });
    return returnVal;
}

Here two variables I have used 1. returnVal: is always returning false 2. stpflag: created a new global variable stpflag.

triggered next button explicitly.

Hope will work for you as well

TerryA
  • 58,805
  • 11
  • 114
  • 143