How can I set a session variable OR clear all session variables when a user closes a particular template

I want to set a session variable when a user closes a particular template.

I tried

<cfset temp=structclear(session)>
cfif IsDefined("Cookie.CFID") AND IsDefined("Cookie.CFTOKEN")>
 <cfset cfid1 = Cookie.CFID>
 <cfset cftoken1 = Cookie.CFTOKEN>
 <cfcookie name="CFID" value="#cfid1#">
 <cfcookie name="CFTOKEN" value="#cftoken1#">

to close all session variables (I'm using MX) but it givers amn error.

How can I set a session variable OR clear all session variables when a user closes a particular  template?
Who is Participating?
digicidalConnect With a Mentor Commented:
The only way I know you can do this would be using the <BODY ONUNLOAD="... [Call your function here]">

That's how most people do it.  Essentially since you can't pass values back and forth between CF and JS what you would simply need to do is create a template that creates a session variable or deletes all session variables.


<SCRIPT LANGUAGE="Javascript">
closerTemplate = ''

function closerCaller(){,'CloserWin','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,width=100,height=100,top=10,left=10')


<BODY onunload='closerCaller()'>

Now then, all that's left to do is create the 'myclosertemplate.cfm' page on which you simply need to run your function to perform either your variable writing or your destroy your SESSION structure.

And for future referrence, it is usually better to do something like:

<CFLOOP COLLECTION="#Session#" ITEM="sessionVar">
    <CFSET StructDelete(Session, sessionVar)>

If you want to clear the session variables for a particular session.  After that you can simply use a ending <CFLOCATION> tag to call a javascript function to close the window for them or if you're really lazy just display a text message that says something like 'Maintenance Completed... Please close this window'

There are hundreds of ways of approaching this issue... if you give more specific details of what you want to achieve exactly and what logic you maintain to determine the appropriate action, I'll be happy to make a sample that you could actually cut and paste into your template, but this ought to get you going in the right direction.

Good luck.
what's the error?

might be a copy/paste error, but you're missing an opening < in your cfif statement

<cfset temp=structclear(session)>
<cfif IsDefined("Cookie.CFID") AND IsDefined("Cookie.CFTOKEN")>
 <cfset cfid1 = Cookie.CFID>
 <cfset cftoken1 = Cookie.CFTOKEN>
 <cfcookie name="CFID" value="#cfid1#">
 <cfcookie name="CFTOKEN" value="#cftoken1#">
kjuliffAuthor Commented:
I have a template that includes a javascript window  that connects to a chat room on another server. When anyone loads that template (chat.cfm) they are taken to the chat room that appears inside chat.cfm.

In order to have a list of who is in the chat room I lead the time and date and the user name into a table - inchat

So I know who ENTERED the chat room but not who is currently in, as I so far have had no way of deleting the row of someone closing my template. The user could of course leave the chat room from a button inside the java wondow but they don't therefore I could know when they left.
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

kjuliffAuthor Commented:
I have it working but I don't want it to go to a popup - I want another page to load as many have popups blocked. I only need the code (digicidal's) modified for this.
You could just add a link back to a different page in you site which is not included in your session maybe a start page or something and then on that page just use the
<cfset temp=structclear(session)> or whatever your session name is, that'll get rid of any session you're in. And then the user can just start over. So just sending them to a index page for your site that does the clearing should help ya out?

just another idea? hope it helps
You can put the loop I put in there on any page... as soon as it runs you have no more session... even if it's in a page that uses the session variables for display or calculation... you just can't (obviously) put any calls to session variables AFTER that looping snippet. ;)

Even though I should probably be shot for recommending this since it's very bad browser etiquette... you can use the onunload call to essentially make a totally persistent window (one that upon closing spawns the same window again with the same content).  This will definitely piss some people off and won't work on non-javascript browsers... but in that case neither will any of your other javascript based functions.  In this case you should make a VERY clearly defined CLOSE link on the page that will fire your script to clear the session and then close the window for them with window.close.

The more elegant solution to the problem would be to simply put a 'close' link on the page, and set up an automated process to run every 5 minutes or so to requery the userlist... since it's not important that the leaving user be notified, just the current users.  Perhaps store the username as a session variable and then vary the tutorial here:

to list out those names...

You can also simply define a function in your application.cfm file that stores in a structure both the username and the lastupdate time for the record line... then use this logic:
IF (user is online and is indicated in the structure) - update the lastupdate time to Now() ELSE (they are online obviously or they wouldn't have triggered the page) - add their username and the current time to the structure of online users.

As I final step you would simply delete any entries from the structure that had a lastupdate time of equal to or greater than your timeout period.  And add the removal snippet to the logout instance.  That way if they logout - they are instantly removed from the list... if they close their browser window... OR just idle long enough... they are also removed.  Unfortunately there is no way for the server to know whether a user has closed their browser or just idled... unless you put an auto refresh on the page... in which case you can set the scavenger function to delete anyone whose lastupdate timestamp is greater than the autorefresh period.

Note that these possibilities are VERY cumbersome if you have a site with thousands of users or more... be sure in those cases that you have TONS of RAM and that you write anything you don't absoutely need instant access to on the drive rather than in memory variables.

Just food for thought...
Side note... I misread your original intent I think... my loop will DESTROY the session structure for that user... it is the same as using <CFSET temp=structDELETE(session)> and is not the same as structClear... which will leave the variables defined, but simply remove the values from them... if you are doing logout handling this is not as adviseable since essentially the structures themselves will remain until they timeout... for example if you structClear(session,"UserID") session.UserID will still exist in the structure but will contain a NULL value... I believe that it will then still return true to a IsDefined() function... Not totally sure on that, but I will research it more completely.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.