How to execute JS function after successfull ajax call? - javascript

I want to demonstrate my window in a full screen.
I have a working function, but I have a problem:
I'm sending an AJAX call after user's click on some button in UI, to get some data and prepare it, after this ajax call (on success I want to demonstrate my data in the full screen, but I can't do that, because it raises an error:
Failed to execute 'requestFullScreen' on 'Element': API can only be initiated by a user gesture.
As you understand, I had user action - click on button, but it's not enough, if I' trying to execute fullscreen function in ajax call.
I was trying to use global variable too, to have a state(do I need to show fullscreen or not(it depends on result of response parsing(after AJAX call)), but it doesn't work too.I was trying in this way:
ISFULLSCREEN = false;
function get_ajax() {
ajax_call ()
.success(response) {
if (response.fullscreen) {
ISFULLSCREEN = true;
}
}
}
function useFullscreen() {
if (ISFULLSCREEN) {
use_fullscreen();
}
}
and my button looks like:
<button onclick="get_ajax();useFullscreen()" value="click me" />
but function useFullscreen runs faster, than the value of ISFULLSCREEN changes to true
Do somebody have any idea how to resolve this issue?
Thanks a lot!

Perhaps in your ajax request, use async: false to make the fetch synchronous, therefore keeping all the execution within the same event (from the user click).
The downside to this is that it may hang the page if it takes a long time

You can use callback function, a callback function is a function passed into another function as an argument, so you can utilize it, and it will execute after your awaited ajax response comes, see below example:
ISFULLSCREEN = false;
function get_ajax(useFullscreenCallback) {
ajax_call ()
.success(response) {
if (response.fullscreen) {
ISFULLSCREEN = true;
useFullscreenCallback();
}
}
}
function useFullscreen() {
if (ISFULLSCREEN) {
use_fullscreen();
}
}
get_ajax(useFullscreen);
Reference: Callback Function Mozilla web docs

Does this help you?: Run a website in fullscreen mode
The answer basically says that you cannot force a fullscreen change without user interaction but there are some alternate suggestions

Add async : false to ajax call and call the function useFullscreen on ajax success and remove this from the button onclick event

Related

unlike following queries first ajax query returns undefined

Have a bit of an issue here. I checked the different answers which seemed related to my problem but cannot seem to get this working.
I've got a page with a link like so :
View
And here's the javascript
var queryResult;
function getData(id, callbackfn){
$.ajax({
type:"POST",
url:"http://url/to/query",
data:{id: id },
success: function(data){
callbackfn(data);
},
error: function(){
return "err";
}
});
}
function showData(id){
getData(id, Callback);
if(queryResult)
{
alert("Yahoooooo !");
}
else
{
alert("Nope !!!");
}
}
function Callback(data){
queryResult = data.length;
}
When clicked for the first time the link launches the alert box and I get "Nope !!!" but any subsequent click will show a "Yahoooooo !"
If I reload the page then again "Nope !!!" for the first time and then it's fine afterwards. So it seems that queryResult is undefined on the first call but first call only. Any idea ?
Thanx
Put your control in Callback function
function Callback(data){
queryResult = data.length;
if(queryResult)
{
alert("Yahoooooo !");
}
else
{
alert("Nope !!!");
}
}
You're using .ajax
this method is asyncronous by default.
So you call "getData" then your Data is loaded.
While it is loaded you check if queryResult exists
Then the data has been loaded and your global flag is set
(At the moment you are checking if the previous request was successful)
The ajax call executes ansynchronously. Therefore when you call getData(), the method call returns instantly (and the ajax call is executing in another thread). This means the first time you click the link, there won't be anything in queryresult because the ajax call hasn't had time to finish before you hit your if block, but the subsequent times there (probably) will be, assuming the call has finished before the next time you click the link.
If you have any logic, such as that if block which depends on the data being returned from the ajax call, you must include it in (or call it from) your callback function.
So in this case you must move the block:
if(queryResult)
{
alert("Yahoooooo !");
}
else
{
alert("Nope !!!");
}
from the getData to the Callback function.

How to unblock a blocked page with jquery-blockui?

I start to using jQuery BlockUI Plugin to block user activity for the page until complete a button process on C#/ASP.NET side.
So I wrote this;
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.io/min/jquery.blockUI.min.js" ></script>
<script type="text/javascript">
$(document).ready(function () {
$('#MyButtonID').click(function () {
$.blockUI({ message: '<h1>Please wait..</h1>' });
});
});
</script>
As you can see, this is a simple code that blocks UI when I click asp:button which ID is MyButtonID until it finish it's process. This works great.
Now I try to create some alert based on a condition while on this click process. If I understand clearly, now I need to unblock my page as a first, show the alert and keep it blocked again until complete button process.
That's why I wrote two function (maybe I can call these $.unblockUI and $.blockUI directly without them?) in my javascript side for that;
function UnblockUI() {
$.unblockUI();
}
function BlockUI() {
$.blockUI({ message: '<h1>Please wait..</h1>' });
}
As far as I search, most common way to call Javascript function on server side is using ClientScriptManager.RegisterStartupScript method in C#. So I tried to alert something on C# side as an example with;
if(condition)
{
string script = string.Format("alert('{0}');", "Some error message");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "alert", script, true);
}
and it worked. After that, I tried to unblock page with calling UnblockUI function in my javascript side but it didn't unblock it.
if(condition)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "unblock", "UnblockUI", true);
string script = string.Format("alert('{0}');", "Some error message");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "alert", script, true);
}
If I understand correctly, this UnblockUI parameter calls my UnblockUI javascript function which I defined above and this function calls $.unblockUI(); and unblock my page which is blocked but as expected, it didn't work.
What am I missing here? Or am I didn't even understand that This plugin lets you simulate synchronous behavior when using AJAX, without locking the browser sentence?
Try using the function call as follows:
function unblockUI() {
$(function() {
$.unblockUI();
});
}
function blockUI() {
$(function() {
$.blockUI({ message: '<h1>Please wait..</h1>' });
});
}
I hope I have helped...
Here is what i am using in my current project.
$(document).ready(function () {
// unblock when ajax activity stops when DOM gets updated, means Ajax is completed
$(document).ajaxStop($.unblockUI);
//Block when trying for Ajax Activity
$('ul#Appdropdown').click(function (ev) {
$.blockUI();
//Add ajax call to get data
}
});
Implement the same and it will do the block and unblock for you.
I had an issue when using the $ajax complete function to stop the animation, If the ajax call fails i was resubmitting the ajax call, and wanted to block UI on resubmitting. But when making the call $.unblockUI inside of complete it was not animating correctly. It would flicker and disapear and not continue to block. However using global call to stop did work, allowing for blocking to re occur with a updated message on blocked UI.
$(document).ajaxStop($.unblockUI); // this works
instead of inside of the complete function of ajax
$.ajax({
complete: function(jqXHR, textStatus) {
$.unblockUI();// this did not always work
}
});
If you block user interface on this way :
BlockUI.Component(".page-content");
Then this is a working solution:
BlockUI.UnblockComponent(".page-content");

How to execute multiple, chained $.post() calls in consecutive order?

What I'm Trying To Accomplish
I need to trigger 1 to 3 different $.post() requests, and whether it's 1 call, 2 consecutive calls, or 3 consecutive calls is decided by some basic user selection. Each call must only start after the previous is completely finished.
I am dealing with 3 simple behavior cases -- the user, being presented with "Checkbox 1," "Checkbox 2," and a "Continue" button," opts to
Select nothing and then press "Continue" button, which makes an XHR call to '/remote.php',
The user opts to only select "Checkbox 1" or "Checkbox 2," and then presses "Continue" button, which calls $.post() Function 1 that is bound to Checkbox 1, or $.post() Function 2 that is bound to Checkbox 2, and then makes an XHR call to '/remote.php',
Or the user selects both Checkbox 1 + 2 and then presses Continue, which calls $.post() Function 1, then calls $.post() Function 2, and then makes an XHR call to '/remote.php'.
I need to make sure that the Continue-button $.post() function does not fire until the Checkbox-bound $.post() functions fire and complete.
The Problem
The problem is that if Checkbox 1 is selected and Checkbox 2 is selected, and then the Continue button is pressed, as I understand it, the loading order should be:
Checkbox 1 bound $.post() request fires and completes, then
Checkbox 2 bound $.post() request fires and completes, then
Continue button bound $.post() fires, and pages is changed via AJAX at the end of the function tied to "Continue" button bound function.
So, where the result should look like:
XHR finished loading: POST "/cart.php?action=add&product_id=1280".
XHR finished loading: POST "/cart.php?action=add&product_id=1284".
XHR finished loading: POST "/remote.php".
It instead often comes out like this:
XHR finished loading: POST "/cart.php?action=add&product_id=1280".
XHR finished loading: POST "/remote.php".
XHR finished loading: POST "/cart.php?action=add&product_id=1284".
So when the page changes due to the AJAX at the end of the "last"/"Continue-button function, either neither of the Checkbox 1 or Checkbox 2 actions have taken place, or one of the two or both do register in the backend (ie, added to cart) but do not reflect in the AJAXified DOM as they should as the final AJAX fires and completes before the previous $.post() calls have completed.
My Code
The HTML
The HTML is basic:
<form method="post" action="#" onsubmit="newChooseShippingProvider(); return false;">
<label for="delSigCheck" class="del-sig-text"><input id="delSigCheck" type="checkbox" onchange="addDelSigToCart();" title="Add Delivery Signature"></label>
<label for="addInsCheck" class="ins-add-calc"><input id="addInsCheck" type="checkbox" onchange="addInsToCart();" title="Add Delivery Signature" data-ins-id="1284"></label>
<input type="submit" value="Continue" class="btn Small">
</form>
The Javascript/jQuery
This is my latest--4th or 5th--attempt, and still does not work:
function addDelSigToCart() {
$('#delSigCheck').toggleClass('checked');
}
function addInsToCart() {
$('#addInsCheck').toggleClass('checked');
}
function newChooseShippingProvider() {
var originalCheckout = ExpressCheckout.ChooseShippingProvider();
if ($('.ShippingProviderList .radio span').hasClass('checked')) {
var addInsCheck = $('#addInsCheck').hasClass('checked');
var delSigCheck = $('#delSigCheck').hasClass('checked');
var insId = $('#addInsCheck').attr('data-ins-id');
var addDelSigUrl = '/cart.php?action=add&product_id=1280';
var addInsUrl = '/cart.php?action=add&product_id=' + insId;
if (delSigCheck && addInsCheck) {
$.post(addDelSigUrl, function() {
$.post(addInsUrl, function() {
originalCheckout;
});
});
} else if (!delSigCheck && !addInsCheck) {
originalCheckout;
} else if (delSigCheck && !addInsCheck) {
$.post(addDelSigUrl, function() {
originalCheckout;
});
} else if (!delSigCheck && addInsCheck) {
$.post(addInsUrl, function() {
originalCheckout;
});
}
} else {
originalCheckout;
}
What I've Tried
I've gone through several version of chaining the $.post() calls, but nothing seems to work consistently.
What I am using now and what seems to work the best for me with extensive testing is using setTimeout to chain the function with some delay, like this:
...
if (delSigCheck && addInsCheck) {
$.post(addDelSigUrl);
setTimeout(function() {
$.post(addInsUrl);
setTimeout(function() {
ExpressCheckout.ChooseShippingProvider();
}, 1300);
}, 1300);
} else if ...
And this version above is what I'm using now, as it seems to give the most consistent results, seeing the scripts load typically as 1,2,3, followed by a DOM AJAXified with appropriate changes based on function 1 and 2. However, I don't think the setTimeout is working as even when I increase it to 5000 or 10000, the action is performed "instantaneously" and no delay takes place (at least certainly nothing close to 5-10 seconds).
I've also tried putting the functions inside $.post()'s success callback:
...
if (delSigCheck && addInsCheck) {
$.post(addDelSigUrl, function() {
setTimeout(function() {
$.post(addInsUrl, function() {
setTimeout(function() {
originalCheckout;
}, 1300);
});
}, 1300);
});
} else if ...
And finally I've also tried:
$.when($.post(addDelSigUrl)).then(originalCheckout);
as well as .done and success: but none of it works, and the $.posts()'s load in an unexpected order, failing.
The Question
What am I doing wrong?
How can I make it so 1 loads fully, then 2 loads fully, and only then 3 fires and loads?
UPDATE 1:
I just tried jfriend00's answer:
$.post(addDelSigUrl, { cache: false }).then(function(data1) {
//CONSOLE.LOGing HERE
console.log(data1);
return $.post(addInsUrl, { cache: false });
}).then(function(data2) {
//CONSOLE.LOGing HERE
console.log(data2);
return originalCheckout;
});
But it still resulted in:
XHR finished loading: POST "/cart.php?action=add&product_id=1280".
XHR finished loading: POST "/remote.php".
XHR finished loading: POST "/cart.php?action=add&product_id=1284".
and both console.logs fire immediately after the first "XHR ...", THEN /remote.php fires (though it should fire last as part of originalCheckout), THEN the 3rd XHR fires.
UPDATE 2
Now that we got the XHRs firing and loading in the correct order via .then(), the second part of the problem I am having is that the 3rd XHR to /remote.php updates the DOM via AJAX with data from the backend. Part of that data is the 1st and 2nd $.posts.
I think the 3rd AJAX call is firing and completing milliseconds before some action is taken on the backend via server-side PHP, and because of this more than 50% of the time, the DOM update via the 3rd AJAX call is missing the data from the 1st and/or 2nd call (most often the DOM changes include Checkbox 1/AJAX call 1, but not 2).
How can I fix this? I've tried setTimeout but it doesn't seem to work as even when I set it to like 30000, the 3rd AJAX fires as soon as the 1st/2nd complete.
Latest front-end code:
function newChooseShippingProvider() {
if ($('.ShippingProviderList .radio span').hasClass('checked')) {
var addInsCheck = $('#addInsCheck').hasClass('checked');
var delSigCheck = $('#delSigCheck').hasClass('checked');
var insId = $('#addInsCheck').attr('data-ins-id');
var addDelSigUrl = '/cart.php?action=add&product_id=1280';
var addInsUrl = '/cart.php?action=add&product_id=' + insId;
if (delSigCheck && addInsCheck) {
$.post(addDelSigUrl).then(function(data1) {
return $.post(addInsUrl);
}).then(function(data2) {
return ExpressCheckout.ChooseShippingProvider();
});
} else if (!delSigCheck && !addInsCheck) {
ExpressCheckout.ChooseShippingProvider();
} else if (delSigCheck && !addInsCheck) {
$.post(addDelSigUrl).then(function(data1) {
return ExpressCheckout.ChooseShippingProvider();
});
} else if (!delSigCheck && addInsCheck) {
$.post(addInsUrl).then(function(data1) {
return ExpressCheckout.ChooseShippingProvider();
});
}
} else {
ExpressCheckout.ChooseShippingProvider();
}
}
The simplest way to sequence jQuery ajax operations is to use the built-in promises:
$.post(...).then(function(data1) {
return $.post(...);
}).then(function(data2) {
return $.post(...);
}).then(function(data3) {
// everything done here
});
Working demo that shows you the precise sequencing: http://jsfiddle.net/jfriend00/zcfr2xy0/
OK, it appears that the problem is that you're doing this:
var originalCheckout = ExpressCheckout.ChooseShippingProvider();
And, then you think that sometime later, you can just do:
originalCheckout;
and that will somehow execute the former. That's not the case. Your ExpressCheckout.ChooseShippingProvider() function is executed immediately and the return result from executing that function is assigned to originalCheckout.
You simply can't do it that way. When you have () after a function name, that means to execute it NOW. I would suggest that you just replace all instances of originalCheckout; with ExpressCheckout.ChooseShippingProvider();.
If you "chain" AJAX post operations (meaning that you do your process once receiving the data from the previous call) then nothing strange should happen.
From the symptom I'd think more to some cache-related problem. Adding an extra random value to the query is a quick'n dirty way to get rid of whoever is caching the result and responding instead of who should. Also using a POST request instead of a GET (if possible) may help on this issue and better conveys the idea that the operation is a mutation that should not be skipped or done out of order.
Note that a stale response problem could be at several levels: browser, proxy, web server, cms plugin...

How to make casperJS wait until .change() event is finished?

I am triggering a change event in my casperJS script which triggers an AJAX request like such:
casper.evaluate(function(i) {
$("form:eq(2) select option:eq(" + i + ")").attr("selected", "selected").change();
},i);
How can I make casperJS wait until the underlying AJAX request has been finished? Already tried to look at the docs but I am more or less stuck. Can anyone guide me into the right direction?
You can always do this in a static way using casper.wait.
casper.thenEvaluate(function(i) {
// change()
},i).wait(5000).then(function(){
// further processing
});
And hope that the request is done in 5 seconds, but maybe you lose some time waiting when the request is done much sooner than 5 seconds. The problem is that as soon as the request is finished doesn't mean that the page is ready/changed.
Another possibility would be to wait for the request to finish, but for this to work you will need to register for the success event of the request somehow. Most of the time you don't have access to this from the global scope. If you do then you can use
casper.thenEvaluate(function(i) {
window._someUniqueVariable = false;
registerSuccessEvent(function(data){
window._someUniqueVariable = true;
});
},i).waitFor(function check(){
return this.evaluate(function(){
window._someUniqueVariable = true;
});
}, function(){
// further processing
});
A more Casper-way of doing that would be to use casper.waitForResource, but then you would need to know the url beforehand or at least able to deduce it from the page.
In the general case, when the request comes back it does something to your page. So you should be able to waitForSelector with a new element or waitForSelectorTextChange or waitUntilVisible etc.
you probably missed waitForResource
from the docs: http://casperjs.readthedocs.org/en/latest/modules/casper.html#waitforresource
casper.waitForResource("you url here", function()
{
// place your code here
});

WCF Service methods + Synchronous calls from javascript

I have written a WCF service and am trying to call the service methods in a script in my ASPX page.
Eg:
<script language="javascript" type="text/javascript">
<!--
function Test() {
**// The following call is an Async call.
tempuri.org.IService.GetData(1,OnRequestComplete, OnError, "");**
}
function OnRequestComplete(result, state) {
var textBox = $get("txtInput");
textBox.value = result;
}
function OnError(result) {
var textBox = $get("txtInput");
textBox.value = result;
}
//-->
</script>
What I want is to be able to call the service method "synchronously"
eg: var result = tempuri.org.IService.GetData(1);
Is this possible?
I believe there's no ability to do synchronous calls in Javascript - the AJAX libraries will always return while waiting for a remote response.
Can you explain why you want to do this?
Edit:
In answer, you should use this method:
In the onclick event handler for your form submit button: Make the webservice validation call, and immediately return false (so the form does not submit). It would be a good idea to display to the user a 'Validating' type message, so they know what is happening here.
If you get a valid response, then use document.form.submit(); to submit the form to the server.
If you get an invalid response, or a server error, then display to the user a message to that effect.
If you use regular AJAX you can make your call synchronous.
See: http://www.w3schools.com/Ajax/ajax_xmlhttprequest_send.asp
and scroll down to the part "Asynchronous - True or False?"
Here I use AJAX but sometimes it hangs
www.DomainGuarder.com

Categories

Resources