jQuery向导步骤在ajax调用完成之前移动

jQuery向导步骤在ajax调用完成之前移动,jquery,jquery-steps,Jquery,Jquery Steps,如何根据某个ajax调用的结果控制下一步的移动?? data.d返回一个bool值 $("#wizard").steps({ onStepChanging: function (event, currentIndex, newIndex) { var move = false; if (currentIndex == 2) { move = false;

如何根据某个ajax调用的结果控制下一步的移动?? data.d返回一个bool值

$("#wizard").steps({
            onStepChanging: function (event, currentIndex, newIndex) {
                var move = false;
                if (currentIndex == 2) {
                    move = false;
                    $.ajax({
                        type: 'POST',
                        url: "Reservation.aspx/SomeFunction",
                        data: serializeData({  }),
                        contentType: "application/json",
                        dataType: 'json',
                        success: function (data) {
                            move = data.d;
                            return true;
                        },
                        error: ajaxLoadError
                    });
                }
                return move;
            },
            saveState: true

        });

把全局变量$out

您可以将Samy的方法用于同步ajax请求

$("#wizard").steps({
    onStepChanging: function (event, currentIndex, newIndex) {
        if (currentIndex == 2) {
            var requestResult = $.ajax({
                type: 'POST',
                url: "Reservation.aspx/SomeFunction",
                async: false,
                contentType: "application/json",
                dataType: 'json',
                error: ajaxLoadError
            });
            return requestResult.responseJSON.Result == "/*your expected value*/"
        }
    },
    saveState: true
});

我遇到了类似的问题,但我使用parsleyjs进行验证。你可能会在我的代码中得到一个想法

我的代码如下:

             onStepChanging: function (event, currentIndex, newIndex) {

                 // ======== Code that fails 

                 //var step = $wizard_advanced.find('.body.current').attr('data-step'),
                 //$current_step = $('.body[data-step=\"'+ step +'\"]');                        


                // check input fields for errors
                //$current_step.find('[data-parsley-id]').each(function() {
                    //this adds .md-input-danger to inputs if invalid
                    //there is remote validation occurring here via ajax
                    // async: false
                    //$(this).parsley().validate();
                //});

                // this is executed before ajax validation is finished 
                //return $current_step.find('.md-input-danger').length ? false : true;

                // ======== END of Code that fails 

                // FIX
                // waits on ajax validation to finish before returning
                if( $wizard_advanced_form.parsley().validate() ) {
                    return true;
                } else {
                    return false;
                }
                //FIX                    
            }
    var def = $.Deferred();

    $.ajax({
        type: "POST",
        url: url,
        //async: false,
        beforeSend: function (xhr) {
            //ASP CORE Antiforgery token
            xhr.setRequestHeader("RequestVerificationToken",
                $('input:hidden[name="__RequestVerificationToken"]').val());
        },
        data: data,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        failure: function (xhr) {
            failureCallback(xhr);
        }
    }).done(function (response) {
        //Result of server validation
        var responseResult = response.result === "Success" ? true : false;
        // Check response
        def.resolve(responseResult);
        }).fail(function (response) {
            console.log(response);
            return false;
        });

    return def; // This is the Deferred that should be returned and NOT the one from jQuery Ajax

如果不希望$.ajax()函数立即返回,请将async选项设置为false:

为Ajax设置超时,若服务器并没有响应Ajax调用,那个么它将进入下一个进程

$("#wizard").steps({
            onStepChanging: function (event, currentIndex, newIndex) {
                var move = false;
                if (currentIndex == 2) {
                    move = false;
                    $.ajax({
                        type: 'POST',
                        url: "Reservation.aspx/SomeFunction",
                        data: serializeData({  }),
                        contentType: "application/json",
                        dataType: 'json',
                        async: false,
                        cache: false,
                        timeout: 30000,
                        success: function (data) {
                            move = data.d;
                            return true;
                        },
                        error: ajaxLoadError
                    });
                }
                return move;
            },
            saveState: true

        });

我也有同样的问题,我甚至想在ajax加载后使用“setStep”强制执行步骤,然后最新版本的jquery.steps去掉了“setStep”

我最终使用了“next”方法,并且必须使用全局触发器来停止OnChange事件的无限循环,简言之,如果ajax返回有效数据,我将强制向导转到下一步,否则,它将停留在当前步骤,代码如下

var $stopChanging = false; 

.... ....

onStepChanging: function (event, currentIndex, newIndex) {
      if ($stopChanging) {
        return true;
      } else {
        items = $.ajax({
        type: 'POST',
        url: "Reservation.aspx/SomeFunction",
        data: serializeData({  }),
        contentType: "application/json",
        dataType: 'json',
        success: function (data) {
            $stopChanging = true;
            wizard.steps("next");
        },
        error: ajaxLoadError
    });
   },
   onContentLoaded: function (event, currentIndex) {
       $stopChanging = false;
   }
}
逻辑如下:

  • 单击“下一步”按钮触发步骤更改
  • 默认情况下,设置jquery.steps onStepChanging事件返回false,然后$.ajax调用,如果它返回有效数据(成功),则调用jquery.steps 转到下一步,如果不是,onStepChanging将再次触发 有效,不执行任何操作,保持当前步骤
  • 每次触发两个onStepChanging事件听起来不是一个好主意,但这就是我现在可以拥有的


    您可能需要为不同的步骤索引行为添加更多条件

    这是我在多次尝试后才能开始工作的唯一方法,这就是@joe lu在上文中的意思。您只需要启动异步调用&返回false。这将使向导保持在同一步骤上。然后在成功处理程序中,以编程方式进入下一步

    $("#wizard").steps({
                onStepChanging: function (event, currentIndex, newIndex) {
                    if (currentIndex == 2) {
                        //Would be a good idea to start a spinner here!
                        //would be a good idea to disable next button here!
                        $.ajax({
                            type: 'POST',
                            url: "Reservation.aspx/SomeFunction",
                            data: serializeData({  }),
                            contentType: "application/json",
                            dataType: 'json',
                            success: function (data) {
                                //stop spinner here!
                                //programmatically move to next step on success.
                                $("#wizard").steps("next");
                            },
                            error: ajaxLoadError
                        });
                    }
                    //Prevents natural movement to next step.
                    //will be done programmatically
                    return false;
                },
                saveState: true
            });
    

    我找到了解决这个问题的另一种方法
    OnStepChanging
    仅支持
    boolean
    。 有一个pull请求,它正在添加对不同对象的使用。 (我也找到了使用“差异对象”的方法) 我将此修改版本包括到我的项目中,并在
    OnStepChanging
    中使用它,如下所示:

                 onStepChanging: function (event, currentIndex, newIndex) {
    
                     // ======== Code that fails 
    
                     //var step = $wizard_advanced.find('.body.current').attr('data-step'),
                     //$current_step = $('.body[data-step=\"'+ step +'\"]');                        
    
    
                    // check input fields for errors
                    //$current_step.find('[data-parsley-id]').each(function() {
                        //this adds .md-input-danger to inputs if invalid
                        //there is remote validation occurring here via ajax
                        // async: false
                        //$(this).parsley().validate();
                    //});
    
                    // this is executed before ajax validation is finished 
                    //return $current_step.find('.md-input-danger').length ? false : true;
    
                    // ======== END of Code that fails 
    
                    // FIX
                    // waits on ajax validation to finish before returning
                    if( $wizard_advanced_form.parsley().validate() ) {
                        return true;
                    } else {
                        return false;
                    }
                    //FIX                    
                }
    
        var def = $.Deferred();
    
        $.ajax({
            type: "POST",
            url: url,
            //async: false,
            beforeSend: function (xhr) {
                //ASP CORE Antiforgery token
                xhr.setRequestHeader("RequestVerificationToken",
                    $('input:hidden[name="__RequestVerificationToken"]').val());
            },
            data: data,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            failure: function (xhr) {
                failureCallback(xhr);
            }
        }).done(function (response) {
            //Result of server validation
            var responseResult = response.result === "Success" ? true : false;
            // Check response
            def.resolve(responseResult);
            }).fail(function (response) {
                console.log(response);
                return false;
            });
    
        return def; // This is the Deferred that should be returned and NOT the one from jQuery Ajax
    

    我希望这会对其他人有所帮助。:-)

    我没有使用jquery向导步骤,但您的问题发生了,因为ajax是异步调用的。查看另一个接受ajax加载的向导插件(如:),正如我所说,“我想知道是否有任何异步方法”。是的,我读过这篇文章,但我忘了提到,没有异步,很难处理它。可以使用setTimeout(函数(){“您的AJAX代码”},1000);但这不是安全的处理方式。如果您在异步方面没有任何问题,那么上述解决方案是安全的。您从上述答案中得到帮助了吗?没有,这是我实际的方法。我正在寻找一种异步方法。然而,我不确定这个插件是否可行。如果没有,我将继续将
    async
    设置为
    false
    。无论如何,悬赏是为了异步方法。看看@Samy answer。他的回答基本上和你一样。似乎没有办法让它异步工作,所以我会奖励你奖金,因为这是我发现的唯一可行的方法。这看起来不像是一个完整的答案。伙计,这是一个真正的答案,其他什么都不起作用。我花了两天的时间才找到这个答案。谢谢,伙计,每次创建无限循环都浪费了很多时间。。。。。
    var is_async_step = false;
    $("#wizard").steps({
            onStepChanging: function (event, currentIndex, newIndex) {
                //USED TO SEND USER TO NEXT STEP IS ASYNC REQUEST IS PRESENT - FOR AJAX CALL 
                if (is_async_step) {
                    is_async_step = false;
                    //ALLOW NEXT STEP
                    return true;
                }
    
                if (currentIndex == 2) {                
                    $.ajax({
                        type: 'POST',
                        url: "Reservation.aspx/SomeFunction",
                        data: serializeData({  }),
                        contentType: "application/json",
                        dataType: 'json',
                        success: function (data) {
                            move = data.d;
    
                            //Add below 2 lines for every Index(Steps).                            
                            is_async_step = true;
                            //This will move to next step.
                            $(form).steps("next");
                        },
                        error: ajaxLoadError
                    });
                }
                 //Return false to avoid to move to next step
                 return false;
            },
            saveState: true
        });
    
        var def = $.Deferred();
    
        $.ajax({
            type: "POST",
            url: url,
            //async: false,
            beforeSend: function (xhr) {
                //ASP CORE Antiforgery token
                xhr.setRequestHeader("RequestVerificationToken",
                    $('input:hidden[name="__RequestVerificationToken"]').val());
            },
            data: data,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            failure: function (xhr) {
                failureCallback(xhr);
            }
        }).done(function (response) {
            //Result of server validation
            var responseResult = response.result === "Success" ? true : false;
            // Check response
            def.resolve(responseResult);
            }).fail(function (response) {
                console.log(response);
                return false;
            });
    
        return def; // This is the Deferred that should be returned and NOT the one from jQuery Ajax