Call AJAX state based on URL - javascript

I am loading content in an overlay with its own URL and it is running pretty good. But I have the problem that when I enter the URL in the browserbar, it links directly to the page of the url, but I want to stay (on the homepage) and the overlay with the project should fade in.
I've tried it with the window.location.href but it killed my function completely. (I am also pretty newbie when it comes to ajax stuff)
My Code
//AJAX Function to fetch project content
var url = $('.load').data('url');
function openUrlInModal(url, target){
$.ajax({
url: url,
type: "GET",
dataType: "html",
contentType: "text/html",
cache: false,
success: function(url) {
$(target).append(url).addClass('modal');
$('.modal').fadeIn('fast');
console.log("target:" + target);
console.log("url:" + url);
}
});
}
// Adds content to the modal on click
$('.load').bind('click', function(e) {
var target = $(this).data("target");
//History Pushstate
fetchedProjectUrl = $(this).attr("href");
history.pushState(null, null, fetchedProjectUrl);
//Call Ajax Function
openUrlInModal($(this).attr('href'), target);
e.preventDefault();
});
//Hitting Back Button
$(window).on("popstate", function(){
history.pushState(null, null, "");
$('.modal').fadeOut('fast');
function empty(){
$('.modal').empty();
}
setTimeout(empty, 300);
});
Thanks for any help in advance :)

I do not understand where the URL for modal come from. If you want to stop the browser to go to the URL which was tipped in the browserbar and then executed - this isn't possible due to security reasons and senseless programming in mind of a browser. In this meaning you must code an own browser, than it's ok - whatever your browser should want to do.
If the URL is a kind of dynamic, you must have a new window reference in your modal, like an iframe, than you can execute a separate location for it.
Otherwise only paste the response-html in your modal innerHTML

Related

Show loader and post AJAX onbeforeunload

I have a settings page with a form. I noticed that people often forget to click the save button, so I decided to send a POST request with $.ajax() on window.onbeforeunload. I'd also like a loader (from Semantic UI) to show before sending the request and hide when it is completed.
This is what I have:
function save(e) {
var msg = 'Your settings were not saved. Please do not leave yet so we can try saving again';
$('form').dimmer('show');
var xhr = $.ajax('settings.php', {type: "POST",
data: $('form').serialize(), async: false});
$('form').dimmer('hide');
if (xhr.status !== 200){
$('form').submit(); //will trigger if the user stays
if (e)
return e.returnValue = msg;
}
}
if ('onbeforeunload' in window)
window.onbeforeunload = save;
else if ('onunload' in window)
window.onunload = save;
else {
var button = $('noscript.submitParent').text();
$('.ui.form.segment').append(button);
}
But now, the loader won't show up until the request is done. I suspect this happens because of async: false, which is necessary so that the page does not unload.
Any suggestions on how to show the loader before sending the request? Is it possible?
I tried $(window).trigger('resize') from here and $('form .dimmer').height() (idea from here), didn't work.
I'm aware of the localStorage alternative, but I'd like not to use it if possible.
I use jQuery 2.1.1

Safari caching my AJAX request

I want one of my pages to fire a javascript AJAX call every time the user loads the page, even if he is coming back to a page in the browser's history. So I've put this function in my jsp (I am using jQuery Mobile):
$(document).on(
"pageinit",
"#base-layout",
function() {
$.ajaxSetup({ cache: false });
myFunction(urlEndpoint);
});
With only this code, and the javascript function:
function myFunction(url) {
var currentTime = new Date();
var n = currentTime.getTime();
var epUrl = url + "?nocache" + n;
$.ajax({
url : epUrl,
dataType: "json",
method: "post",
headers : { "cache-control": "no-cache" },
cache:false,
}).done(function(data) {
//do something
});
}
I managed to get Chrome, Firefox and IE to actually fire the ajax call even when pressing the back button. But I can't manage to get Safari to show this behavior. No matter what I try, it's never going through my server side function.
As you can see, I tried disabling cache for the ajax call, and changing the endpoint url by appendind the current time, to no effect. I even tried to put
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
on my controller method, but it didn't work either. I can't get Safari to call this function when coming back to a page in history.

Chrome window.open after ajax request acts like popup

I have a situation where, when a user pushes a button I perform an ajax request, and then use the result of the ajax request to generate a URL which I want to open in a new tab. However, in chrome when I call window.open in the success handler for the ajax request, it opens in a new window like a popup (and is blocked by popup-blockers). My guess is that since the the success code is asynchronous from the click handling code that chrome thinks it wasn't triggered by a click, even though it is causally related to a click. Is there any way to prevent this without making the ajax request synchronous?
EDIT
Here is some minimal code that demonstrates this behaviour:
$('#myButton').click(function() {
$.ajax({
type: 'POST',
url: '/echo/json/',
data: {'json': JSON.stringify({
url:'http://google.com'})},
success: function(data) {
window.open(data.url,'_blank');
}
});
});
http://jsfiddle.net/ESMUA/2/
One note of clarification: I am more conerned about it opening in a separate window rather than a tab, than I am about it being blocked by a popup blocker.
Try to add
window.open(url,'_blank');
Edit
Well, I don't think you can get around popup-blockers when opening a page that's not the immediate result of a user action (i.e. not async).
You could try something like this though, it should look like a user action to a popup-blocker:
var $a = $('<a>', {
href: url,
target: '_blank'
});
$(document.body).append($a);
$a.click();
Edit 2
Looks like you're better of keeping things sync.
As long as the new window is "same origin" you have some power to manipulate it with JS.
$('#a').on('click', function(e){
e.preventDefault();
var wi = window.open('about:blank', '_blank');
setTimeout(function(){ // async
wi.location.href = 'http://google.com';
}, 500);
});
Try adding async: false. It should be working
$('#myButton').click(function() {
$.ajax({
type: 'POST',
async: false,
url: '/echo/json/',
data: {'json': JSON.stringify({
url:'http://google.com'})},
success: function(data) {
window.open(data.url,'_blank');
}
});
});
What worked for me was:
var win = window.open('about:blank', '_blank');
myrepository.postmethod('myserviceurl', myArgs)
.then(function(result) {
win.location.href = 'http://yourtargetlocation.com/dir/page';
});
You open the new window tab before the sync call while you're still in scope, grab the window handle, and then re-navigate once you receive the ajax results in the promise.
The answer posted by #pstenstrm above (Edit 2) mostly works, but I added just one line to it to make the solution more elegant. The ajax call in my case was taking more than a second and the user facing a blank page posed a problem. The good thing is that there is a way to put HTML content in the new window that we've just created.
e.g:
$('#a').on('click', function(e){
e.preventDefault();
var wi = window.open('about:blank', '_blank');
$(wi.document.body).html("<p>Please wait while you are being redirected...</p>");
setTimeout(function(){ // async
wi.location.href = 'http://google.com';
}, 500);
});
This fills the new tab with the text "Please wait while you are being redirected..." which seems more elegant than the user looking at a blank page for a second. I wanted to post this as the comment but don't have enough reputation.
There is no reliable way. If your tab/window has been blocked by a pop-blocker in FF and IE6 SP2 then window.open will return the value null.
https://developer.mozilla.org/en-US/docs/Web/API/Window/open#FAQ
How can I tell when my window was blocked by a popup blocker? With the
built-in popup blockers of Mozilla/Firefox and Internet Explorer 6
SP2, you have to check the return value of window.open(): it will be
null if the window wasn't allowed to open. However, for most other
popup blockers, there is no reliable way.

Preloading images with AJAX for AJAX

My site structure is sequential (as in page1.html leads to page2.html, page2.html leads to page3.html, etc.). I'm wanting to preload some images from the third page on the second page. I've found this wonderful bit of code here on SO:
$.ajax({
url : 'somePage.html',
dataType : "html",
success : function(data) {
$(data).hide().appendTo('#someDiv');
var imagesCount = $('#someDiv').find('img').length;
var imagesLoaded = 0;
$('#someDiv').find('img').load( function() {
++imagesLoaded;
if (imagesLoaded >= imagesCount) {
$('#someDiv').children().show();
}
});
var timeout = setTimeout(function() {
$('#someDiv').children().show();
}, 5000);
}
});
It works beautifully at dumping the entire contents of page3.html onto page2.html. The problem is, I don't want the entire contents; I just want the images, and I want them hidden and ready for when the user actually loads page3.html. The above snippet brings audio and, well, everything else along with it. So my question is, will this hacked up version below work for my purposes?
$.ajax({
url : 'page3.html',
dataType : "html",
success : function(data) {
var imagesCount = $(data).find('img').length;
var imagesLoaded = 0;
$(data).find('img').load( function() {
++imagesLoaded;
if (imagesLoaded >= imagesCount) {
//halt? do something?
}
});
}
});
Again, all I want is for page3.html's images to be preloaded on page2.html. Will this do the trick? And how can I test to verify?
I believe the simplest way, in your case, is just to use jQuery.get and specify the images (or any other objects) you want to preload.
For example,
$.get('images/image1.jpg');
$.get('images/image2.jpg');
// etc
This way, you can specify which images from the next page you want to preload in the browser.
The $.get function is just an abbreviated version of the $.ajax function. In your case, you just want to "get" the images so that they are in the browser's cache, so that when you get to the next html page, the images are already loaded.
How to verify
If you were to add the sample code above to your page2, then visit that page while having the Network tab open in Firebug, or Chrome dev tools, you'll see that GET requests are sent for the images and they are loaded to the browser's cache.

window.open popup getting blocked during click event

What I ultimately need to do is run an $.ajax() call and then after that is run, open a new window.
A use clicks on a "Preview" button that saves their current form then opens a new window that shows a preview of the item with the data that was just saved.
But as-is, the window.open function gets blocked by popup blockers.
Here's the basic parts of my code:
HTML:
Preview
JavaScript:
$('.preview').live('click', function(event){
save_survey($(this).attr('href'));
event.preventDefault();
});
function save_survey(url) {
$.ajax({
type: "POST",
url: form_url,
dataType: 'json',
data: form_data,
success: function(data) {
window.open(url, '_blank');
}
});
}
I ran into this problem recently and found this work-around:
1) call window.open just before calling $.ajax and save window reference:
var newWindow = window.open(...);
2) on callback set location property of the saved window reference:
newWindow.location = url;
Maybe it will help you too.
Popup blockers usually works blocking every popup shown not triggered by a direct user action, like clicking on a button or a link.
If you use a ajax request on your click event, the request is fired asyncronous from the click event, that's why by the time the ajax request has done its job and you get your event with the response from the request you have lost your chance to trigger a window.open withouth the popup blocker getting in the way, the original click event it's long dead by that time.
According this this post, it looks like you would have to open your window in direct response to the click (to avoid getting hit by the popup blockers) rather than waiting until the AJAX call completes to open the new window.
I solved my case by making the Ajax call synchronous. E.g. (with jQuery):
$("form").submit(function(e){
e.preventDefault();
$.ajax({
async: false,
url: ...,
data: ...,
success: function(results){
if(results.valid){
window.open(...);
}
}
});
return false;
});
const newWin = window.open(`${BASE_URL}`, 'expampleName')
if (newWin) {
newWin.onload = () => {
const currentOpenWindow = newWin
const href = newWin.location.href
}
}

Categories

Resources