Products

Products
Viewing By Category : ColdSpring / Main
October 16, 2008

Coldbox Framework and Ajax: cfajaxproxy

After working in Coldbox for a while I know your first instinct is to make a cfajaxproxy call to a cfc event just like all the other Coldbox events. However, using cfajaxproxy is just a little different. Here is an example to show you one simple way of doing it, not the only way but one of them.

First let me note that I am using Coldspring version of IOC. It should work the same though with any form of IOC. Mostly we need the IOC to provide the bean to the services your Ajax call requires from within the Coldbox proxy.

After having provided a service in Coldspring like so:

<bean id="usersService" class="model.usersService">
<constructor-arg name="privatemessagesGateway">
<ref bean="privatemessagesGateway"/>
</constructor-arg>
<constructor-arg name="ColdBoxController">
<ref bean="ColdBoxController"/>
</constructor-arg>
</bean>

we can use this "usersService" bean in the coldboxproxy.cfc like this:

<cffunction name="ajxSetPMRead" access="remote" output="false" returntype="void">
      <cfargument name="messageid" type="String" required="true"/>
      <cfset var pm = getBean('usersService').getPrivateMessageByID(int(arguments.messageid))>
      <cfset pm.setRead(1)>
      <cfset getBean('usersService').savePrivateMessage(pm)>
   </cffunction>

The code above is what the Ajax, cfcajaxproxy, will call as a method for Coldbox to perform. It fetches a private message object bean, sets or updates some properties, then uses the gateway to save the object bean. I don't have a return or output but you can do that also here if desired. And here is the actual view and Ajax calling code:

<cfajaxproxy cfc="coldboxproxy" jsclassname="cbProxy">

<a href="##" onClick="showMessageDetails('#privateMessagesQuery.privatemessageid#','#privateMessagesQuery.read#','#privateMessagesQuery.subject#','#privateMessagesQuery.fromUserName#','#privateMessagesQuery.message#')">#privateMessagesQuery.subject#</a>

<$cript>
function showMessageDetails(messageid,read,subject,from,message){
   var e = new cbProxy();
   if(read == 0){
      e.setCallbackHandler(setPrivateMessageRead);
    e.setErrorHandler(ajaxErrorHandler);
    e.ajxSetPMRead(messageid);
   }
   document.getElementById('pmReply').style.display = "none";
   document.getElementById('pmDetails').style.display = "inline";
   document.getElementById('pmDetails_Subject').innerHTML=subject;
   document.getElementById('pmDetails_From').innerHTML=from;
   document.getElementById('pmDetails_Message').innerHTML=message;
}
var setPrivateMessageRead = function(res){
   alert('set to read');
}
var ajaxErrorHandler = function(statusCode, statusMsg){
   alert('Status: ' + statusCode + ', ' + statusMsg);
}
</script>
The cfc attribute is dot notation to the location of your coldboxproxy.cfc, mine here is at the root. Basically I'm showing the private message details in a div but needing to set the read flag in the database to 1 to indicate it has been read. And using Ajax I can set this in the database for each message read without a page refresh. The alerts in the javascript are for demonstration and testing purposes.

The code I provided is a cut down version of actual code and does not include the view event, form code, queries, or other behind the scenes code. I hope this helps to give you a step ahead on how to use Ajax with the Coldbox framework.

May 26, 2008

ColdSpring ColdboxFactory: DSN and Mail settings

My second day into figuring out Coldbox, here's a little something cool. Putting it simply, using ColdSpring, in the CS.xml you can define a 'coldboxFactory' bean to use in creating other beans that define this factory's methods as beans also, then pass that bean into a class bean's property as a bean reference.

Actually, that doesn't sound simple as it is, so here's an example. Remember that I'm a newbie, so be nice.

coldbox.xml.cfm

<MailServerSettings>
   <MailServer>mail.urserver.com</MailServer>
   <MailPort>25</MailPort>
   <MailUsername>username</MailUsername>
   <MailPassword>password</MailPassword>
</MailServerSettings>

<Datasources>
   <Datasource alias="DSNAlias" name="dsnName" dbtype="mysql" username="name" password="pass" />
</Datasources>
I've set mail settings and data source settings here in the main Coldbox config. I'll be using Coldspring for IoC and so I'll need to be able to pass this around in my beans.

Coldspring.xml

<beans>
   <bean id="coldboxFactory" class="coldbox.system.extras.ColdboxFactory" />
   <bean id="ConfigBean" factory-bean="ColdboxFactory" factory-method="getConfigBean" />
   
   <bean id="dsnBean" factory-bean="ColdboxFactory" factory-method="getDatasource">
    <constructor-arg name="alias">
    <value>DSNAlias</value>
    </constructor-arg>
   </bean>
         
   <bean id="cfctest" class="handlers.cfctest">
      <property name="dsnBean">
         <ref bean="dsnBean" />
</property>
      <property name="ConfigBean">
         <ref bean="ConfigBean" />
</property>
   </bean>
</beans>
This coldboxFactory has several methods that interface with the coldbox config file, among other things I'm sure. Check out the API for more info. But basically I create the coldboxFactory bean, then create other beans of the factory's methods. Then notice how I pass those beans into the handler beans by reference. These 'properties', as it turns out, are setters in the cfc, such as setDsnBean and setConfigBean. Then I just put them in variables for my other methods.

cfctest.cfc

<cfcomponent output="false">
   <cffunction name="setDSNBean" access="public" returntype="void">
      <cfargument name="DSNBean" type="Any" required="true"/>
      <cfset variables.dsn = arguments.DSNBean.getName()>
   </cffunction>
   
   <cffunction name="setConfigBean" access="public" returntype="void">
      <cfargument name="configBean" type="Any" required="true"/>
      <cfset variables.mailName = arguments.configBean.getKey("mailUsername")>
   </cffunction>
   
   <cffunction name="capitalize" access="public" returntype="string">
      <cfargument name="string" type="string" required="true"/>
      <cfreturn Ucase(variables.mailName & " - " & arguments.string)/>
   </cffunction>
</cfcomponent>
Don't dis my cfc, I'm just playing around and testing stuff. Notice the setters that I mentioned before. If you do a dump/abort on these at run time you'll see what use they are.

general.cfc

<cffunction name="index" access="public" returntype="void" output="false">
   <cfargument name="Event" type="coldbox.system.beans.requestContext">
   
   <!--- Logic --->
   <cfset string = "Welcome!">
   <cfset string = variables.ioc.getBean("cfctest").capitalize(string)>
   <cfset Event.setValue("welcomeMessage",string)>   
   
   <!--- Display --->
   <cfset Event.setView("home")>
</cffunction>
And finally here's the handler that uses the IoC plugin I set in variables in the handler's init function that gets the bean set in Coldspring and runs the method that utilizes all the stuff we just went through. Check out Coldbox's Coldspring documentation for more information.

There are other factories to use I'm guessing and other factory methods within those. You can use all the methods in the coldbox.system.controller as beans also. But like I said, I'm just discovering this stuff right now. Frankly I need to think over wether or not passing bean reference properties to all my CS beans is the most effective way of using global configs any ways. Seems rather repetative as apposed to putting such things in a request scope through onRequestStart or something.


Copyright © 2005-2006 Clint Willard. All rights reserved.
Aura skin for Clint Willard's BlogCFC inspired by Brooks Bilson's Bolg.
All trademarks property of their owners.