I know that this question is asked in many ways, I'm also able to make it work. It only doesn't work in combination with a key* event...
Why doesn't .abort() work in this function?
function setGlobalSearch(){
var xhr;
$('#globalSearch').keyup(function(){
if(xhr && xhr.readystate != 4){
xhr.abort();
}
var searchVal = $(this).val();
xhr = $.ajax({
type: "GET",
url: "/ajax.actions?i=globalSearch&q="+searchVal,
success: function(data) {
$('#globalSearchResults').html(data);
},
dataType:"html",
cache:false
});
});
}
The abort() function will only fire if the request has been sent. I can only suggest that this is possibly not the case.
However, I would recommend a different pattern which negates the need to abort requests, which is, as you've seen, occasionally a little flaky. Instead I would only fire the request once typing has ceased for a set number of milliseconds. Try this:
var timer;
$('#globalSearch').keyup(function() {
clearTimeout(timer);
timer = setTimeout(function() {
var searchVal = $(this).val();
$.ajax({
type: "GET",
url: "/ajax.actions?i=globalSearch&q="+searchVal,
success: function(data) {
$('#globalSearchResults').html(data);
},
dataType:"html",
cache:false
});
}, 150); // fire the AJAX request 150ms after typing stops.
});
Related
I have developed an ASP.NET MVC Application using JavaScript, jQuery.
I have implemented to be restrict multiple user logins at same time using onbeforeunload/beforeunloadevent.
It works fine, but sometimes not working in onbeforeunload/beforeunloadevent.
var myEvent = window.attachEvent || window.addEventListener;
var chkevent = window.attachEvent ? 'onbeforeunload' : 'beforeunload'; /// make IE7, IE8 compitable
myEvent(chkevent, function (e) { // For >=IE7, Chrome, Firefox
if (!validNavigation)
{
$.ajax({
url: '#Url.Action("ClearSession", "Account")',
type: 'Post',
data: "",
dataType: "json",
success: function (data)
{
console.log("onbeforeunload Success")
},
error: function (data) {
console.log("onbeforeunload Error")
}
});
}
return null;
});
There is one also function in AJAX - jQuery is called complete: function(){};
This function checks weather request is running for same user id and password on browser or not, Like this here
complete: function() {
$(this).data('requestRunning', false);
}
Whole AJAX-jQuery implementation here see and implement accordingly, I hope it will work fine for you
Code Here
$('#do-login').click(function(e) {
var me = $(this);
e.preventDefault();
if ( me.data('requestRunning') ) {
return;
}
me.data('requestRunning', true);
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
me.data('requestRunning', false);
}
});
});
See this me.data('requestRunning', false); if it will get any request running for same user id and password it returns false and cancel login.
For more help see here link Duplicate, Ajax prevent multiple request on click
This is not perfect solution but you can implement like this
Is it possible to tell if a jquery ajax request has been going on for more than a certain length of time? I would like to prompt users of my site if the request has been going on for 10 seconds to reload and retry, but I cant find anything in the documentation to meet my request.
Try setting timeout property and get the error handler parameter. The possible values are
"timeout", "error", "abort", and "parsererror"
$.ajax({
url: "/ajax_json_echo/",
type: "GET",
dataType: "json",
timeout: 1000,
success: function(response) { alert(response); },
error: function(x, t, m) {
if(t==="timeout") {
alert("got timeout");
} else {
alert(t);
}
}
});
So for all ajax requests in your site... you should do something like this...
$.ajaxSetup({
beforeSend: function(jqXHR, settings){
/* Generate a timer for the request */
jqXHR.timer = setTimeout(function(){
/* Ask the user to confirm */
if(confirm(settings.url + ' is taking too long. Cancel request?')){
jqXHR.abort();
}
}, 10000);
}
});
Set a timeout and then cancel it once it ajax call completes.
var timer = setTimeout(function() {
alert('Too long!');
}, 10000);
$.getJSON(url, function() {
clearTimeout(timer);
});
I am relatively new to AJAX and javascript and I am using ajax to generate search suggestions using an onkeyup event. I am trying to use a timer to regulate the number of ajax requests, and the abort function to improve performance. I never used these two functions before and I am unsure if they are set up correctly. I was wondering if someone can take a look and let me know if I am on the right track with these functions? Many thanks in advance.
var ajaxReq = null;
$(".prod-name-input").keyup(function(){
searchword = $(this).val();
//alert(searchword);
if((searchword.length) > 3) {
clearTimeout(timer);
timer = setTimeout(function(){
if (ajaxReq != null) ajaxReq.abort();
var ajaxReq = $.ajax({
url: "invoice-get-data.php?searchword=" + searchword,
dataType: "html",
success: function(data){
$(".smart-suggestions").html(data);
}
});
}, 350);
}
});
I suggest you to have a look on the excellent article of Ben Alman on throttling / debouncing : http://benalman.com/projects/jquery-throttle-debounce-plugin/ .
What you want to achieve is a debouncing, so with Ben Alman's plugin, you can use :
var ajaxReq = null;
$(".prod-name-input").keyup($.debounce(350, function(){
searchword = $(this).val();
if((searchword.length) > 3) {
if (ajaxReq != null) ajaxReq.abort();
ajaxReq = $.ajax({
url: "invoice-get-data.php?searchword=" + searchword,
dataType: "html",
success: function(data){
$(".smart-suggestions").html(data);
}
});
}
}));
EDIT :
In fact, it was a debouncing and not a throttling in your case.
I have added a jsfiddle : http://jsfiddle.net/scaillerie/2AFp3/ .
I have a procedure running on a timeout to load data in the background:
(function getSubPage() {
setTimeout(function() {
if (cnt++ < pagelist.length) {
loadSubPage(pagelist[cnt]);
getSubPage();
}
}, 500);
})();
In loadSubPage() I'm making $.ajax() calls:
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
$.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
}
});
initSubPages[page] = true;
}
}
The problem I'm having is that the error handler is being hit when the user navigates away if any ajax requests are open. I'm trying to get around this by .stop()ing the requests on window.onbeforeunload, but I'm not sure what object to call .stop() on?
jQuery exposes the XMLHttpRequest object's abort method so you can call it and cancel the request. You would need to store the open request into a variable and call abort().
activeRequest = $.ajax({...
and to stop it
activeRequest.abort()
Abort Ajax requests using jQuery
This should come in handy.. You have a jQuery method for doing just that.
The $.ajax returns XMLHTTPRequestObject which has .abort function. This function will halt the request before it completes.
var xhr = $.ajax({ /*...*/
..
..
/* Later somewhere you want to stop*/
xhr.abort();
Read more: How to cancel/abort jQuery AJAX request?
Here is the solution I used based on the feedback:
window.onbeforeunload = function() {
for (page in ajaxing) {
if (ajaxing[page] != null)
ajaxing[page].abort();
}
};
var ajaxing = {};
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
var ajaxRequest = $.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
},
complete: function() {
ajaxing[lot] = null;
}
});
ajaxing[page] = ajaxRequest;
initSubPages[page] = true;
}
}
function checkuser(user) {
var ret = false;
$.ajax({ type:'POST', url:'user.php',
async:false,
data:{'user':user},
success:function (data) {
if (data == 1) ret = true
} });
return ret;
}
I use bvalidator to validate fields. It seems to fire this function on every keypress and the user is not able to continue typing before the ajax call is competed. I'm not really sure what to do here.
How could I make the function not be ran more than once every two seconds for example?
You need to get rid of async:false but you also need to modify your code to work asynchronously. The synchronicity is what is causing your UI to 'freeze'.
Maybe you could try setting a timeout that will run 2 seconds after a key is pressed on your input, but if another key is pressed it restarts that timer. So in essence it will only after two seconds of no keystrokes.
var validateTimeout;
$('#target').keydown(function() {
clearTimeout(validateTimeout);
validateTimeout = setTimeout(function(){checkuser(user);},2000);
});
You'll need to update the checkuser ajax call to have a smarter callback to work async:
function checkuser(user) {
$.ajax({ type:'POST', url:'user.php',
async:false,
data:{'user':user},
success:function (data) {
if(data == 1){
//something to indicate sucess
}else{
//something to indicate failure
}
} });
}
You could throttle the call with a throttle plugin:
jQuery Throttle Plugin