In a previous post I created a CFC to save simple variables into the session scope. In that CFC I had set up two functions, "SetSessionVar" and "GetSessionVar". However I ended up only needing the "SetSessionVar" function for my example so I never really tested the "GetSessionVar" function. Someone asked me today how to invoke it, and that is when I realized there were a couple little problems that I needed to fix.
Here is the updated Session.cfc code, I had to modify the output and returntype attributes in the "GetSessionVar" function:
<cfcomponent name="session" hint="Performs Session Functions">
<cffunction name="SetSessionVar" access="remote" output="false" returntype="Boolean">
<cfargument name="Name" type="string" required="true">
<cfargument name="Value" type="string" required="true">
<cfset session[arguments.Name] = arguments.Value>
<cfreturn true>
</cffunction>
<cffunction name="GetSessionVar" access="remote" output="true" returntype="String">
<cfargument name="Name" type="string" required="true">
<cfreturn session[arguments.Name]>
</cffunction>
</cfcomponent>
In my previous post using this CFC, I demonstrated how to execute the SetSessionVar function, but since that function did not return anything it was a tad bit simpler to do. If you are using cfajaxproxy to connect to a CFC function that returns a string or JSON object or something, you will need to set up a callback handler function that will get excecuted if the function is invoked successfully. Then you specify it using the setCallbackHandler function in the CFC proxy object.
Here is my working Save Active Tab Example that now has a button that when clicked will call the GetSessionVar function and use a callback handler that just pops up an alert box with the value of the session variable.
<html>
<head>
<title>Save Active Tab Example</title>
<cfajaxproxy cfc="session" jsclassname="CFCs.session">
<cfset AjaxOnLoad("addTabChangeListener")>
<script language="JavaScript">
addTabChangeListener = function(){
myTabs = ColdFusion.Layout.getTabLayout("MyTabLayout");
myTabs.on('tabchange',SaveActiveTab);
}
SaveActiveTab = function(){
myTabs = ColdFusion.Layout.getTabLayout("MyTabLayout");
actTab = myTabs.getActiveTab();
var SessionObj = new CFCs.session();
SessionObj.setErrorHandler(errorHandler);
SessionObj.SetSessionVar("ActiveTab", actTab.id);
}
errorHandler = function(statusCode,statusMsg) {
alert(statusCode+': '+statusMsg)
}
//Here is the Callback Handler that puts the response into an alert
AlertResponse = function(res){
alert(res);
}
//Here's how to call the GetSessionVar function
CheckActiveTab = function(){
var SessionObj = new CFCs.session();
SessionObj.setErrorHandler(errorHandler);
SessionObj.setCallbackHandler(AlertResponse);
SessionObj.GetSessionVar("ActiveTab");
}
</script>
</head>
<body>
<table width="95%" align="center"><tr><td>
<cflayout type="tab" name="MyTabLayout">
<cfif session.activetab eq "tab1"><cfset isSelected="true"><cfelse><cfset isSelected="false"></cfif>
<cflayoutarea name="tab1" selected="#isSelected#" title="Tab 1" style="height:100%">
This is Tab 1
</cflayoutarea>
<cfif session.activetab eq "tab2"><cfset isSelected="true"><cfelse><cfset isSelected="false"></cfif>
<cflayoutarea name="tab2" selected="#isSelected#" title="Tab 2" style="height:100%">
This is Tab 2
</cflayoutarea>
<cfif session.activetab eq "tab3"><cfset isSelected="true"><cfelse><cfset isSelected="false"></cfif>
<cflayoutarea name="tab3" selected="#isSelected#" title="Tab 3" style="height:100%">
This is Tab 3
</cflayoutarea>
<cfif session.activetab eq "tab4"><cfset isSelected="true"><cfelse><cfset isSelected="false"></cfif>
<cflayoutarea name="tab4" selected="#isSelected#" title="Tab 4" style="height:100%">
This is Tab 4
</cflayoutarea>
</cflayout>
</td></tr></table>
<input type="Button" value="alert active tab" name="alertactivetab" onclick="CheckActiveTab();">
</body>
</html>
I need to re-look over my code and figure it out what I'm doing wrong.
That being said, if I were to build what you are describing, then in application.cfc I would set up a variable in the onSessionStart function called "session.jsenabled", with a defaul value of "NO". Then I would use my session.cfc above to set the variable to be "YES", by including the following snippet of code in any request where the session:
<cfajaxproxy cfc="session" jsclassname="CFCs.session">
<cfset AjaxOnLoad("checkJSEnabled")>
<script language="JavaScript">
checkJSEnabled = function(){
var SessionObj = new CFCs.session();
SessionObj.setErrorHandler(errorHandler);
SessionObj.SetSessionVar("JSEnabled", "YES");
}
errorHandler = function(statusCode,statusMsg) {
alert(statusCode+': '+statusMsg)
}
</script>
Then I could put some conditional logic on the necessary pages to check the session variable and let the user know if they are missing out on my cool AJAX features.
Although after writing that out I'm not sure how practical it is. If the very first page they view is an AJAX enabled page and you haven't set the value in their session to "Yes" yet, then your message telling them that javascript is needed for this page would be displayed until they refreshed. so you would have to add some more logic to that checkJSEnabled function that will hide your message if javascipt is actually enabled.
I would just use the noscript tag if I were you.
I didn't finish explaining my logic above. :) After I had attempted to check at least once, the code wouldn't ever run again. Easy enough to do, only need to check once and keep the "message" in their face or perhaps give them the option to dismiss the message.
I need to give this code another stab still, but I'm buried on a project at work still. When I last attempted, everything was running properly, but when the script part ended, it was retaining it's old value instead of the new one that I assigned it inside.
There are two conditions that must be met in order to require the use of CFLock:
1. A shared resource is being accessed or updated.
2. There must be the possibility of a race condition resulting in a NEGATIVE outcome.
This particular sample code was developed as part of an article that demonstrated how to interact with the session scope via the new cfajaxproxy tag.
http://www.coldfusionguy.com/ColdFusion/blog/index...
Since in that example I did not feel that a race condition would cause a negative outcome, I did not need to worry about locking the session scope. If you feel that a race condition in your application would cause a negative outcome, then by all means you should use cflock.
I wrote a fairly detailed article on CFlock several months ago that you may want to read through, and I would recommend reading through the comments and checking out all the links to other resources and information that was brought up in the discussion as well.
http://www.coldfusionguy.com/ColdFusion/blog/index...
Thanks for this. I was chasing my tail all morning trying to figure this out. Once I made sure that the ajax calls resided within the head tags, everything lit up as described. Thanks again!
I used your example but I'm getting a 404:not found, is this because a mapping issue with Ajax? can you help? thanks