Question

I have a website with multiple tabs. Each tab runs a separate report based on a set of filters that take their values from session variables.

How things work now:

While the user is inside a report tab they can open a filter menu to select the options that they need to run their report (doctor names, locations, date, etc) and then they can hit the run button to get their report. When the user clicks "run" the form is saving the variables inside the session where they are available to run other reports without having to click "run" or define them again and again.

What I am trying to do:

Instead of having only a "run" button inside the form I need an "Apply" button that will set the session variables from the form without running the current report. This way the user can pre-define their variables without being forced to run a report they don't need.

I tried using ajax that calls a function outside my application which is setting up variables based on the user's selection.

My challenge is to get those variables back from the function in some format where I could use them in updating the current session variables.

This is a sample of my code:

The Apply button:

<a href="#" id="okbutton" class="savebuttons close-reveal-modal" onclick="setSession();">Apply</a>

My Ajax Function:

function setSession(){
    var formData = $('form').serialize();

    $.ajax({
        url:'/mod_example/components/exampleCFCs/xUtility.cfc?method=setSessionVariables',
        data: formData
    }); 
};

And part of my function:

<cfcomponent output="no">
    <cffunction name="setSessionVariables" access="remote" returntype="any">
        <cfargument name="docid" type="string" required="no">

        <cfif isDefined('docid')>
            <cfset session.doctorids = docid>
        </cfif>

        <cfif isDefined('docid')> 
            <cfreturn session.doctorids>
        <cfelse>
            <cfreturn 0>
        </cfif> 
    </cffunction>
</cfcomponent>

What I need is to get the value of session.doctorids to be able to update my session variables with the new value.

Was it helpful?

Solution

It sounds like you have this utility cfc in a shared directory and you are calling it directly. As you've noticed, the problem with that is that you end up with multiple sessions. You can get around this issue be setting up a Facade cfc within your application and make your ajax calls to that cfc.

If you only want to expose the setSessionVariables then you could use this cfc:

<cfcomponent output="no">
    <cffunction name="setSessionVariables" access="remote" returntype="any">
        <cfset var xUtility = createObject('component','mod_example.components.exampleCFCs.xUtility')>
        <cfreturn xUtility.setSessionVariables(argumentCollection=ARGUMENTS)>   
    </cffunction>
</cfcomponent>

If you want to expose all methods of the utility cfc, then you can extend it:

<cfcomponent output="no" extends="mod_example.components.exampleCFCs.xUtility">
</cfcomponent>

This would allow you to call methods on the utility cfc while maintaining a single session scope (per user of course).

EDIT: Been a while since i've worked in wheels...but i remember not liking AJAX in the wheels framework. If you create a new subfolder and call it 'remoting' and put the facade in there, and drop an application.cfc in there that looks like this:

<cfcomponent >
    <cfset this.name = 'whatever_your_wheels_app_name_is'>
    <cfset this.SessionManagement=true> 
</cfcomponent>

You should be able to use that facade and this application.cfc will piggyback on the existing application with the same name. The problem with this approach would be if the application times out, and a remote call is the first request to the application, then the wheels application scope might not get set up properly.

It would be best if you could extend the root application.cfc and just override the onRequestStart method so that the framework will ignore the request. To do that you would need to make a mapping in the cfadmin to the root of your project and use this for your remoting/application.cfc

<cfcomponent extends="mappingName.Application">
    <cffunction name="onRequestStart"> 
        <cfargument name="requestname" required="true" />

        <cfset structDelete(this,'onRequest')>
        <cfset structDelete(this,'onRequestEnd')>
        <cfset structDelete(VARIABLES,'onRequest')>
        <cfset structDelete(VARIABLES,'onRequestEnd')>

        <cfreturn true>
    </cffunction>
</cfcomponent>

The way that wheels uses `cfinclude' all over the place, you may need to look at this post about extending the appliciation: http://techblog.troyweb.com/index.php/2011/09/cfwheels-workarounds-numero-uno-application-proxy/

There are some wheels plugins (http://cfwheels.org/docs/1-1/chapter/wheels-ajax-and-you) that allow you to use the controller actions / views / routes via ajax so you could look into those also.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top