Closing lightbox sometimes fires faster than onblur() on input - javascript

I'm running this code on blur() on an input. It works great, as long as you don't click on anything that takes you to a different page or closes the lightbox (div in an overlay) where the ajax function and input was loaded from, since there is a chance that the ajax script will be aborted. I get that it may be hard to make sure that the content is saved on blur() if you close the browser window, but is there any way I can wait until the ajax request (and any link click) is finished before I close the lightbox (or move on to a different page)?
I guess another option would be to have on input() instead/as well as on blur(), but then I get a lot of ajax requests and need to start throttling right? My lightbox plugin (fancybox) has an event called beforeClose, can I run something in there that checks if the ajax request was sent?
Please let me know if I'm thinking about this the wrong way. I know that async false is not really recommended, but maybe what I need?
$.ajax({
type: "POST",
dataType: "json",
url: "?a=ajax",
data: { value: $self.val() },
error: handleError
}).done(function(data) {
if( data == "0" )
{
// no success
}
else
{
// success
}
});

Related

document.form.submit() is too slow to complete before window.close()

I am having an issue with saving a form. The form itself has about 40 rows with around 12 inputs for each row in this style:
On save, it should POST and then close the window. However, it never truly saves it. This makes me think that it is closing the window before it saves. Here's the code in question:
$('#save-btn').click(function() {
document.form.submit();
window.close();
};
If I remove the window.close() and use the inspector than I see in the parameters field that all the values save correctly. This is again what lead me to think that the window is closing to early.
I have tried using the following in the above #save-btn function:
setTimeout('window.close()',5000)
Yet this never seemed to execute the window.close() after the 5 seconds and all around seems like bad programming to force it to wait 5 seconds and then close when it could take any amount of time.
I then attempted to use an AJAX request like:
var _url = 'submit?nameParam="+nameParam+"&com=editlist&'+$('form').serialize();
console.log(_url); //just to see what its pushing out
$.ajax({
url: _url,
error: function(){
alert('Error submitting form.');
},
success: function() {
window.close();
}
});
This resulted in 414 Request-URI Too Long. I know the case for this is it should be a POST to begin with, but I was just trying to make it work.
Just because, this is how our form is set up:
<form name="form" action="submit" method="post">
Our solution was to close the page from our action page
Remove the serialized data from your _url and instead pass it through the .ajax() request with the data setting:
var _url = 'submit?nameParam="+nameParam+"&com=editlist';
$.ajax({
url: _url,
method: "POST",
data: $('form').serialize(),
error: function() {
alert('Error submitting form.');
},
success: function() {
window.close();
}
});
Your ajax approach is correct because you can understand that form submit done correctly with code, on success post it is easy to close the window.
For sending a POST request, you have to make some small changes in your code...
Don't serialize your form and add URL, it is not safe (not working for your situation).
Post your values as "post data".
Here is documentation about it.
https://api.jquery.com/jquery.post/
Please try and update your question if you cannot understand how.

Waiting for success of Jquery.trigger

I have a form that has a set of drill-downs so one drop down will fill in another. I have a script set up to remember the form values and reset them for that page. My issue comes in when I execute on the trigger for the element, I can't figure out any way to wait on the other dropdown to refresh and then setting its value. Is there any way I can wait for the success result of a function that's kicked off by trigger('change') (or similar function) besides listening for the ajax request. My fall back plan is to do this with cookies and then fill in the form server side. Which might look better anyway, I'm just wondering if it can be done.
I have it saving the values from each drop down and loading them when I get back, I'm wondering if there's some way I can
listen for the ajax call in dropdown_a to finish if I load the value from session storage and call $('#dropdown_a').trigger('change')
the more I think about it I'd probably have to store some sort of value in the program that tracks any request made so I can await them
which would defeat the purposes of the self contained script I have for this
$('#dropdown_a').on('change', function() {
//Ajax call I want to wait for
$.ajax({
url: 'someendpoint',
data: 1,
success: function(response) {
util.fillsInSelectBox(response, $('#dropdown_b'));
},
error: function() {
showErrorModal();
}
});
});
$('#dropdown_b').on('change', function() {
$('#table').bootstrapTable('refresh');
});

jQuery json Ajax call no longer works after first time (including form submit, setTimeout)

I have a rather long running submit, so I implemented a modal dialog with a progress bar to show the progress. The first time I submit the form everything works fine. The progress bar is being updated (I use setTimeout in the success handler to check the progress every 500 ms) and shown in the modal dialog. The contents of the div below it are also updated, and when everything is done the form submits. That's where it gets tricky...
After the first time I submitted the form, it is impossible to get the progress bar to update again other than to reset my IIS Express. The modal dialog is showm, I can see the first json request being fired but it just waits and aborts as soon as the submit is through. I tried adding a timeout to the $.ajax call, adding headers to not have the result of the json call cached, I tried clearing the timeouts but all to no avail.
I think the problem has something to do with setTimeout being aborted by the form submit (and the redirect done after the form was submitted). Somehow I can't seem to find the real culprit.
function DoSomething() {
$.ajax(
{
type: "POST",
contentType: "application/json;charset=utf-8",
url: "/Controller/Action",
dataType: "json",
timeout: 400,
success: function (data) {
if (data) {
if ($('progress').prop('max') !== data.total) {
$('progress').attr({ max: data.total });
}
$('progress').attr({ value: data.current });
$('#progressText').html(data.current + ' / ' + data.total);
}
setTimeout(DoSomething, 500);
}
});
}
And in the view where I'm using this...
$("form").submit(function () {
$('#thisIsMyModal').modal({
backdrop: 'static',
keyboard: false
});
DoSomething();
});
To your ajax request add a cache: false. I had the same problem in my MVC application until setting that to false. You won't find good documentation on it though, it was something I dug up on a obscure website a while back.
EDIT: I stand corrected, http://api.jquery.com/jQuery.ajax/

Display loading as the page is redirecting in Django

I am not trying to ask for free ride, but I don't seem to know how to do this at all.
My recent posts are about running jobs in the background, but I have no luck in doing that.
So...
User clicks run inside a form and it fires a job.
It takes about 30 seconds to complete the job, returns, and tells Django view function to return HttpResponseRedirect(....).
So while the page is being redirect (it takes 30 seconds to signal "GO AHEAD").... I want to show user like an Ajax loading gif picture.
I don't have Ajax implemented and the system is way too complicated to hack on.
Can we actually do this with javascript? The problem is that it hasn't load any page yet because it needs heavy_work to finish.
result = heavy_work(....)
.... more code ....
return HttpResponseRedirect(go to this page...)
Thanks!
Why don't you use a regular ajax call?
javascript
function do_heavy_lifting(argument) {
$.ajax({
type: 'GET',
data: { argument: argument }, // if necesarry
url: '/heavy_lifting_django_view_url/',
beforeSend: function() {
$('#loading').show();
},
success: function(data) {
...redirect...
},
cache: false
});
}
html
<div id="loading" style="display:none">
<button onclick="do_heavy_lifting('argument');">
Using AJAX is simple: just show a 'loader' animated gif before the actual ajax call, and in 'on_success' response callback to hide the loader gif.
Bu without AJAX - the only solution so far is using iterators - look at this: How to stream an HttpResponse with Django

AJAX and user leaving a page

I'm working on a chat and I'm trying to figure out how I can detect that the user has left the page or not. Almost everything is being handled by the database to avoid the front end from messing up.
So what I'm trying to do is once the page is left for any reason (window closed, going to another page, clicking a link, etc.) an ajax call will be fired before a person leaves so I can update the database.
This is what I've tried:
$(window).unload(function(){
$.post("script.php",{key_leave:"289583002"});
});
For some odd reason, it wouldn't work, and I've checked the php code, and it works fine. Any suggestions?
Try this:
$(window).unload(function(){
$.ajax({
type: 'POST',
url: 'script.php',
async:false,
data: {key_leave:"289583002"}
});
});
Note the async:false, that way the browser waits for the request to finish.
Using $.post is asynchronous, so the request may not be quick enough before the browser stops executing the script.
This isn't the correct way of doing this... Suppose the OS just hangs or something happens in the browsers process then this event wont be fired. And you will never ever know when the user has left, showing him/her online ever after he/she has disconnected. Instead of this, what you can do is.
Try connecting a socket so that you can know the user is disconnected when the socket is disconnected
You can send a request to the server (say after every 1 sec) so that you can know that the user is still connected. If you didn't receive the request - even after 2 secconds - disconnect the user.
Try to add popup (prompt("leaving so early?")) after $.post. It may work. Tho it may be bad user experience. :)
This is related to the answer above. https://stackoverflow.com/a/10272651/1306144
This will execute the ajax call every 1 sec. (1000)
function callEveryOneSec() {
$jx.ajax({}); // your ajax call
}
setInterval(callEveryOneSec, 1000);
The unload event is not recommended to detect users leaving the page. From MDN:
Developers should avoid using the unload event ... Especially on mobile, the unload event is not reliably fired.
Instead, use the visibilitychange event on document and/or the pagehide event on window (see links for details). For example:
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'hidden') {
$.ajax({
type: 'POST',
url: 'script.php',
async:false,
data: {key_leave: "289583002"}
});
}
});
Better yet, use Navigator.sendBeacon, which is specifically designed for the purpose of sending a small amount of analytics data to a server:
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('script.php', {key_leave: "289583002"});
}
});

Categories

Resources