Clicking Back after fancyBox AJAX Form Submission - ajax

Not sure if this is even possible, but I have a AJAX form like this fiddle:
http://jsfiddle.net/nicorellius/GfeEf/
On my website, it is working fine. I do a simple validation in the form with JavaScript, but if the user gets through the JavaScript, the user is presented with a Campaign Monitor webpage: either saying yay or nay to their validation.
When the user subscribes successfully, if the user clicks back or uses the CM back link, the fancyBox remains with data populated. Based on how I have the script written it should close after submission.
This is Firefox behavior in Linux and Windows. Chrome actually clears the page and removes the fancyBox form. 
The AJAX section is here:
$.ajax({
type : "POST",
cache : false,
url : "http://<comapny_name>.createsend.com/a/b/c/abcdef/",
data : $(this).serializeArray(),
// I've tried both of these commented out pieces to no avail.
//beforeSend : function() {
//$.fancybox.close(true);
//},
//success : function(data) {
//$.fancybox.close(true);
//}
});
So despite adding:
success : function() {
$.fancybox.close(true);
}
to the AJAX script, I cannot get it to close after submission.
EDIT
I should note, too, that this phenomenon seems to occur with Firefox, Safari and Opera. Chrome behaves as I would expect (eg, when clicking the back link, I get the fresh page reload). The CM page is using javascript:history.go(-1) to send me back.

I have no idea about Campaign Monitor but why not force close your fancybox on document load?
$(document).ready(function(){
$.fancybox.close(true);
}

It looks like you might be wanting the code from the answer to this: How to close fancybox after Ajax Submit?
(Here is the part extracted & modified)
var fancyboxProxy = $.fancybox; //declared before $.ajax
//and then modify your success to:
success : function() {
fancyboxProxy.close();
}
I would also try a simple alert() or conosle.log() in your success function to determine you are receiving the success event, if you are receiving the event then you know it is specifically a problem with the code you are using to hide the fancybox.

Related

HTML 5 - Ajax popstate and pushstate

I am trying to figure out how to use this pushstate and popstate for my ajax applications. I know there are some plug ins but i am trying to learn how to use it in it's raw form at the moment. I am also aware that in the raw form it is not supported by IE. All that aside, I need some help understanding how to use it.
the pushstate portion of it is pretty simple. Right now i have:
function loadForm(var1,var2){
string = "xyz="+var1+"&abc="+var2;
history.pushState("", "page 1", string);
}
This changes my url just fine and adds it to my url stack. I have another function that looks like the following:
function loadForm2(var1,var2, var3){
string = "xyz="+var1+"&abc="+var2+"&123="+var3;
history.pushState("", "page 2", string);
}
The second function also changes the url when called. Now that i have that part i am trying to figure out how to use the popstate. Right now i have it as follows
window.popState = ajax;
function ajax(){
jQuery.ajax({
type: "get",
url: "../html_form.php",
data: string,
dataType: "html",
success: function(html){
jQuery('#Right_Content').hide().html(html).fadeIn('slow');
validate();
toolTip();
}
})
}
So if you can image my page with two links, one calls the loadForm function and the other link calls loadForm2 function. When i click each of the links the forms loads via ajax just fine and the url changes as it should. When I hit the back button, the url will roll back to the previous page's url BUT the page content loads the current form again instead of the previous form. When i hit the back button it is making an ajax call (firebug) as if it is trying to load the previous form but instead of running the previous ajax call it runs the current ajax call. So my url goes back to the previous url but the form that is loaded or the ajax call that is called is the same as the most recent page load (not the previous page load).
I am not sure what i am doing wrong and any help would be much appreciated.
You are doing something weird.
window.popState = ajax;
I am even surprised that ajax() gets even called.
The normal way of doing it is to register an event handler.
$(window).bind('popstate', function(event) {
var state = event.originalEvent.state;
}
See How to trigger change when using the back button with history.pushstate and popstate?
EDIT:
Basically you need to know which form to load when your state is changed. .originalEvent.state will contain this information which you can then pass on to your ajax call. It should also contain the respective string.
The problem in your approach is that string, always remained the one of the last newly loaded page. You need to read that string in event.orginalEvent.state. use console.log() to find it in that object.
EDIT 2:
Is there a way you can give me an example of what my code should look like. I think you understand what i am trying to accomplish.
Everytime the back button (or forward button) of the browser is clicked, you need to load the page from AJAX.
You have attempted to do this by saying:
window.popState = ajax;
This is dangerous as you are replacing a system function.
Instead you should register an event handler for when the state changes.
jQuery(window).bind('popstate', ajax);
Now everytime the back button is pressed, your ajax() function (should) get called.
So far this will only improve your approach to it, but not fix your problem.
The problem is that your original ajax() function refers to a global variable called string. This global variable has no memory of the previous states. Therefore everytime the original form gets loaded again and again.
But you already are correctly storing string in the state by doing:
history.pushState("", "page 1", string);
So when ajax is called, the browser will give it an event object, which contains all this information.
So all you need to do now is change your ajax() as follows:
function ajax(){
jQuery.ajax({
type: "get",
url: "../html_form.php",
data: document.location.search.substr(1),
dataType: "html",
success: function(html){
jQuery('#Right_Content').hide().html(html).fadeIn('slow');
validate();
toolTip();
}
})
}
Finally you should also stop using string as a global variable by using the var keyword and make sure the string contains a "?":
function loadForm(var1,var2){
var string = "?xyz="+var1+"&abc="+var2;
history.pushState("", "page 1", string);
}
This will reduce any future confusion about something almost working, but not working properly.

jquery prevent functions form executing, while an ajax post is in progress

I´m looking for a possibillity to prevent all functions from being executet while an ajax post is in progress. For example: I have a modal box where you can switch between two forms with a simple tab-navigation. When a user submits one of the forms, the data will be sent via ajax. So how can I avoid that the user can switch between the forms till the post is finished.
Is there a simple way to do that?
something like event.stopImmediatePropagation() during the ajax post.
Simple way to do that is just display an overlay. An element that takes up the whole screen and has no event handlers. The most popular option seems to be semi transparent div with a loading indicator to give user an idea about what's happening and that nothing will work on the website until request finishes.
Example: http://jsfiddle.net/NezTc/11/
i am not sure if other methods exist but i would bind a listener for all submits and check there if a flag for ongoingAjax request is set. This flag would be set by my ajax calls.
something like
$(function(){
var onGoingAjaxRequest = false;
$('form').submit(function() {
if(!onGoingAjaxRequest) {
return true;
}
return false;
});
});
I'm not sure you can "cut off" all functions until a given point in time, but I know you can always:
Header all functions with if(isPosting) return; and add
var isPosting = true
$.ajax({ [...], complete:function(r){ // this is the ajax function
isPosting=false;
}});
Or, overlay the whole thing and add a big preloader and a Please wait... message.

Loading forms with .load kills the submit button in Firefox

I am currently loading several forms into a webpage with:
$(document).ready(function () {
$('#content').load('php_script.php', function() {
$(this).find('#someForm').ajaxForm(function() {
alert('Success!');
});
$(this).find('.someOtherForm').ajaxForm(function() {
alert('Success!');
});
});
});
This works in Chrome, Chromium and IE who loads the forms and everything works as it should (Clicking submit sends a request to the php-script defined in the form's action, which adds stuff to a db, and shows the alert dialog). In Firefox (v10.0.2) this code loads the forms into the DOM and displays them, but when clicking submit on any of the forms nothing happens.
At first I suspected ajaxForm, but changing the above code to:
$(document).ready(function () {
$('#content').load('php_script.php');
});
yields almost the same result, the difference being that the user is sent to the script defined as the action (Except for Firefox, where nothing happens).
How do I make Firefox not kill the submit button?
I solved it, bad HTML from my side:
<table><form ...>
<tr>...</tr>
</form></table>
Instead it should look like:
<form ...><table>
<tr>...</tr>
</table></form>
The validator did not catch this since it was loaded via jQuery (and I forgot to validate the page serving the forms), and Firefox buggered out.
The code above looks ok to me...
Have you had a look in firebug if there are any errors? Maybe there is a conflicting Id or something.
Maybe the form isnt completely loaded into the dom yet, might be worth giving live binding a try
Found this in the docs:
...jQuery uses the browser's .innerHTML property to parse the retrieved document and insert it into the current document. During this process, browsers often filter elements from the document such as , , or elements. As a result, the elements retrieved by .load() may not be exactly the same as if the document were retrieved directly by the browser...
If you inspect the form is it the same as in other browsers?

JQuery Mobile and JSONP

I have my jquery mobile app pulling data from our mysql db using JSONP. The data is pulling fine, but the problem comes when I go back to the previous "page" in my app then click on a different option, it doubles the data on the next screen, and it will just keep stacking the data as many times as I do that. What am I missing?
The app doesn't look right in any browsers, but it looks fine in the ios simulator or appmobi simulator. I can post some code if needed, just know it won't look right in your browser.
Thank you for any help you can provide
$('#two').bind('pagecreate',function(event){
var img = getUrlVars()["st"];
var photo = $('#img');
$.ajax({
type: 'GET',
url: 'http://serverhidden/json/img.php?st='+img,
dataType: 'jsonp',
success: function(data) {
$.each(data, function(i,item){
var image = '<img class="stmap" src="images/states/lrg/'+item.img+' "/>';
photo.html(image);
});
},
error: function(e) {
//called if there is an error
//console.log(e.message);
}
});
});
Make sure you are not subscribing your event multiple times. It seems silly but is easy to do.
I would recommend you add logs to your JQM site so that you can see how many times your site is being updated.
You should also be aware that updating a JQMobile page often requires a call to a method to update content after a page is rendered. See here: jQuery Mobile rendering problems with content being added after the page is initialized
Hope those help.
So without any code from your project this is a shot in the dark but it seems like you populate a pseudo-page with information on pageshow with an .append() call. Instead of using .append(), use .html() as it will replace the information already present rather than add to it.
If each state has an individual page then you can bind to the pagecreate (or similar) event so the data will only be appended once rather than on each pageshow event.

Cannot make unload event fire in Firefox 4

I have run ajax-calls on the unload event for about a year.
It has generally worked in FF and IE but not to 100%, I cannot say when it has failed.
I register the event by writing in the bodytag:
onunload="...."
I got error messages in FF4 since the unload event also wanted to write in a div-tag of the page that just had unloaded. Fixed this by making the ajax-routine write nothing if the id of the target div is 'dummy'
I am no expert on AJAX, but the following code has worked:
http://yorabbit.info/e-dog.info/tmp/ajax_ex.php (the link is a text-page)
(You call ajaxfunction2 with the following arguments: filename, queryString for PHP, string to show in target div during update, name of target div)
I don't get any error messages in the FF error console and IE9 works. Is there any way I can make it work in FF too?? I have just started trying FF4, but my impression is that it works less well than in FF3.
Thanks.
(I am on a trip and ay not have the possibility to reply immediately, but I really appreciate suggestions and will reply in due course)
EDIT:
I had bettter add this:
The AJAX-call I make on unload does only send some data (how long time the user stayed on the page) to the PHP-MySQL server
I don't know what is happening here, but Firefox 4 has made notable changes to how unloading works: For example, if you do an alert() during a link click event, it will no longer freeze the page, but load the new location anyway. Maybe this is something similar.
However, you are never guaranteed for the Ajax call to finish if it is not synchronous in any browser anyway - the request may or may not come back with a response until the page has been closed. Whether this works will be down to chance, and the user's network speed.
Try using a synchronous request first, as outlined here: How does jQuery's synchronous AJAX request work?
this will usually guarantee that the request comes back. However, use it very sparingly - blocking behaviour at page unload can be very annoying for the user, and even freeze the browser.
I suggest to use jQuery instead of keeping track of browser changes yourself.
Solution:
Find working sample here: http://jsfiddle.net/ezmilhouse/4PMcc/1/
Assuming that your internal links are set relatively, and your external links therefore set starting with 'http':
Leave ...
Stay ...
You could hijack 'a' tags via jQuery events and ask the user to confirm the leaving (in case of external links). In 'ok' case you kick off your 'onleave' ajax call (async=true) and redirect user to external link:
$('a').live('click', function(event){
// cache link
var link = $(this).attr('href');
// check if external link (assuming that internal links are relative)
if (link.substr(0,4) === "http") {
// prevent default a tag event
event.preventDefault();
// popup confirm message
var reply = confirm('Do you really want to leave?');
if (reply) {
var url = 'http:mydomain.com/ajax.php';
var data = {'foo': 'bar', 'fee':'bo'};
// kick off your 'onleave' ajax call
// forced to be synchronous
$.ajax({
type: "POST",
async: false,
url: url,
data: data,
success: function( data ) {
// ok case: leave page, cached link
window.location.href = link;
}
});
}
return false;
}
});

Resources