问题
How can I control the move to next step according to the result of some ajax call?? the data.d returns with a bool value
$("#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
});
回答1:
$.ajax({
type: 'POST',
url: "Reservation.aspx/SomeFunction",
async: false,
contentType: "application/json",
dataType: 'json',
success: function (data) {
move = data.d;
return true;
},
error: ajaxLoadError
});
回答2:
you can use Samy's approach with synchronous ajax request
$("#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
});
回答3:
If you don't want the $.ajax() function to return immediately, set the async option to false:
Set Timeout for Ajax if server not responding of your ajax call then it will move on next process.
$("#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
});
回答4:
I have the same problem, I was even thinking to use the "setStep" to force the steps after ajax load, then the latest version of the jquery.steps took out the "setStep"..
I end up by using the "next" method, and have to use a global trigger to stop the infinite loop for onChanging event, in short, I force the wizard go to next step if the ajax returns valid data, otherwise, it stays to the current step, here's the code
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;
}
}
The logic is like:
- Click "next" button to trigger onStepChanging
- By default, set the jquery.steps onStepChanging event returns false, then the $.ajax calls, if it returns the valid data (success), call jquery.steps to go to next step, and the onStepChanging triggers again, if it's not valid, do nothing, stay at current step
trigger two onStepChanging event every time does not sounds a good idea, but that's what I can have for now
You may need to add more conditions for different step index behaviors
回答5:
I found another how to solve this problem. OnStepChanging
supports only boolean
.
There is pull request #232 which is adding usage of deffered object.
(I found way how to use deffered object also on GitHub)
I included this modified version to my project and used it in OnStepChanging
like this:
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
I hope this will help someone else. :-)
回答6:
$("#wizard").steps({
onStepChanging: function (event, currentIndex, newIndex) {
var $out= false;
if (currentIndex == 2) {
$out= false;
$.ajax({
type: 'POST',
url: "Reservation.aspx/SomeFunction",
data: serializeData({ }),
contentType: "application/json",
dataType: 'json',
success: function (data) {
move = data.d;
$out = true;
},
error: ajaxLoadError
});
}
return $out;
},
saveState: true
});
Put global variable $out!
回答7:
I encountered a similar problem, but i was using parsleyjs for validation. You might get an idea in my code.
My code is like this:
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
}
回答8:
var items;
$("#wizard").steps({
onStepChanging: function (event, currentIndex, newIndex) {
var move = false;
if (currentIndex == 2) {
move = false;
items = $.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
});
items.success(function (data) {
//if can log in go to logged in page
if (data.success == true) {
alert("Working");
var move = data.d;
return true;
} else {
alert("didnt work");
}
// output of data
alert(JSON.stringify(data));
});
回答9:
Here's the only way I could get to work after several attempts this is what @joe-lu was getting at above. You just want to kick off the async call & return false. This will keep the wizard on the same step. THEN in the success handler you programmatically move to the next step.
$("#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
});
回答10:
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
});
来源:https://stackoverflow.com/questions/20203037/jquery-wizard-steps-move-before-ajax-call-completed