Link to home
Start Free TrialLog in
Avatar of Solutionabc
Solutionabc

asked on

not sure if Jquery ajax is caching overlay UI

Hi,
I have a script that is using the UI tools overlay with some jquery ajax. the script is below.
http://flowplayer.org/tools/demos/overlay/trigger.html

The problem I am having doesn't seem to be with the ajax as it is returning the correct values and is checking the returned value (var msg) properly.

the script works like this:

1) When someone clicks an image it triggers statify()
2) jquery ajax than calls PHP to mark a record column in the DB as locked and open the overlay UI
3) when the overlay is closed it calls another PHP script to mark that same record as open.

The purpose of this is to prevent multiple people from editing the same record during the same period of time.

I can only get this error to happen after the first person locks the record and then unlocks it, while still keeping the page open without refreshing. Now when person 2 on a different computer comes and locks the record Person 1 should not get the overlay because ajax will show it as locked. BUT when person 1 clicks it they still get the overlay as if it is not locked.

I have troubleshooted the issue by inserting alert() all over the place to check the value of var msg in different places and have concluded that the ajax, nested ajax and if statement are functioning 100% accurately.

For some odd reason when " if (msg === "1")" FAILS it will still open the overlay UI.... it's like the broswer has cached the action of opening the overlay and doesn't listen to the IF statement that checks if it should display it or not.

Does anybody know the reason why, when the if statement "if (msg === "1")" FAILS it will still perform the actions inside of the statement as if it has PASSED?

oh yeah, and I have set the jquery ajax property "cache" to false ;)

thanks.
function statify(id){

/*
var data = $.get("lockdown.php?num="+id);
*/
$.ajax({
   url: "lockdown.php?num="+id,
   cache: false,
   success: function(msg){
   alert(msg);
   if (msg === "1"){
   alert(msg);
     var triggers = $('.modalInput').overlay({

	// some mask tweaks suitable for modal dialogs
	mask: {
		color: '#68DBA0',
		loadSpeed: 200,
		opacity: 0.9
	},load: true,

	closeOnClick: true,
	onClose: function(){
	javascript_countdown.setTimeLeft(0);
	alert("on close alert"+msg);
	 $.ajax({
   url: "stable.php?num="+id,
   cache: false
   
   
 });}, onLoad: function(){ //time to countdown in seconds, and element ID
javascript_countdown.init(180, 'javascript_countdown_time'); }

});
} else { alert("this is locked");}

   }
 });
document.getElementById('id').value = id;

}

Open in new window

Avatar of OmniUnlimited
OmniUnlimited
Flag of United States of America image

You will always have problems like this because of what you surmised.  Several browsers (Firefox expecially) will cache the page meaning that the ajax will produce the wrong result.

The only possibility of overcoming this problem would be to set some sort of a timing mechanism that would constantly check the database for lock status and update your page accordingly.
Avatar of Solutionabc
Solutionabc

ASKER

could you please elaborate on the timing mechanism work around?

The problem isn't checking the db for lock status because it does it accurately as confirmed by outputting the response on each ajax call.

The problem is that it doesn't always follow the if statement to check whether or not to show the overlay. You can check the first time and if the record is locked than you can keep checking until it is unlocked. and that method works fine.

The problem arises when a person first locks it, then unlocks it, then someone else locks it, then person 1 tries to use it again and it will ignore the locked status sent back and display the overlay anyways.
Sorry, I misunderstood.  You might try checking your response type and see what you get:

 
$.ajax({
   url: "lockdown.php?num="+id,
   cache: false,
   success: function(msg){
   alert(typeof(msg));
   if (msg === "1"){
   alert(msg);
     var triggers = $('.modalInput').overlay({

	// some mask tweaks suitable for modal dialogs
	mask: {
		color: '#68DBA0',
		loadSpeed: 200,
		opacity: 0.9
	},load: true,

	closeOnClick: true,
	onClose: function(){
	javascript_countdown.setTimeLeft(0);
	alert("on close alert"+msg);
	 $.ajax({
   url: "stable.php?num="+id,
   cache: false
   
   
 });}, onLoad: function(){ //time to countdown in seconds, and element ID
javascript_countdown.init(180, 'javascript_countdown_time'); }

});
} else { alert("this is locked");}

   }
 });
document.getElementById('id').value = id;

}

Open in new window

so the typeof is always a string.

Where you inserted typeof the var msg always returns the correct value based on the db record.

and even the if statement right after it (line 6) will always compare the msg var correctly. BUT even when the if statement is false it will still show the overlay. And I have proven that the if statement is going false properly.

what makes me think it is caching the overlay action is because when the if statement is false it won't alert(msg) (line 7) but it will still show the overlay meaning that it is not following the if statement instructions.

does this help?

thanks!
and to add to the proof of the if statement returning false:

it will alert("this is locked") (line 30) which is the else to the if statement on line 6.
You could be right.  Have you considered doing a check in the onBeforeLoad handler?
good point.

I tried adding this but no luck:

onBeforeLoad: function(){ if ( msg != "1"){$('.modalInput').overlay().close();} },
ASKER CERTIFIED SOLUTION
Avatar of OmniUnlimited
OmniUnlimited
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache-control" content="no-store">
just tried that if thats what you meant... didn't work..

I guess I need to find a new way to do what I want to accomplish.

Any ideas?

thx
What scripting are you using on your site?  Meta tags don't work very well.

If you are using PHP, this header sequence works:

header("Cache-Control: no-cache, no-store");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Pragma: no-cache");

Don't forget to use ob_start and ob_finish or you will get a "Headers already defined" error.
Yeah I'm using php, will give it a shot in a bit thx!
would I do it like this?

<?
ob_start();
header("Cache-Control: no-cache, no-store");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Pragma: no-cache");
ob_finish();
?>
<HTML><HEAD> .... etc

thx
No.  Like this:

<?
ob_start();
header("Cache-Control: no-cache, no-store");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Pragma: no-cache");
?>
<HTML><HEAD> .... etc
</body></html>
<?php
ob_finish();
?>
when I do that I get:

Call to undefined function ob_finish()
Boy am I embarrassed.

ob_flush();

not

ob_finish();  (don't know what I was thinking)
no problem, but still it didn't help.

I also just realized something... I alert var msg before if performs the if statement. but when you click the trigger for the second time the overlay has a chance to load and then the alert pops up.

so the overlay is displaying before it even performs the check. Is it possible that the browser cached the overlay trigger and doesn't even wait for the if statement check?

If so, is there a way to make javascript perform like it's the first time running the code everytime it is run?

The issue is that your browser is caching a static version of your code.  That is the reason it is even possible that the overlay could be seen without executing your code.  The only way to get around that is to prevent the browser from caching.

Do you know if you are using an Apache server?  If so, you can set expires by placing the following code in your .htaccess file like so:

ExpiresActive On
ExpiresByType application/javascript A2592000
Oops, copied and pasted the wrong code.  Should be:

NameVirtualHost *
<VirtualHost>
...
   <Directory /var/www/mysite>
      ExpiresActive On
      ExpiresDefault "access plus 10 minutes"
      ExpiresByType text/html "access plus 1 day"
      ExpiresByType text/javascript "access plus 1 day"
      ExpiresByType text/x-json "access plus 1 day"

      ExpiresByType image/gif "access plus 1 month"
      ExpiresByType image/png "access plus 1 month"
      ExpiresByType image/jpg "access plus 1 month"


      <FilesMatch "index.php">
            Header set Cache-control "no-cache, no-store, must-revalidate"
      </FilesMatch>

   </Directory>
...
</VirtualHost>
   
Thanks for your help! I wasn't able to get the browser to stop caching the action.

Instead I gave up on the Ajax and used $.GET() instead. It now works perfectly. I'll award you the points for
Your assistance in helping come to a resolution. Thanks again!
Wow, well I am glad that you were able to resolve it.  Thanks for the points!