Entries Tagged as “Adobe ColdFusion”

ColdFusion Splendor – When to use invokeCFClientFunction

April 20, 2014 / Ram Kulkarni

  Adobe ColdFusion | ColdFusion 11 | Mobile | Splendor

This post is reproduced from my post at my personal blog ramkulkarni.com.

I have seen some confusion when it comes to using invokeCFClientFunction. I have been asked this question a few times, more recently on LinkedIn, so I thought explaining it in a blog post might be a good idea.

If you don't know already, ColdFusion Splendor has added support for client side CFML (<cfclient>) and this code is translated to JavaScript.  You can call JavaScript functions from cfclient and vice versa.

cfclient also makes calling asynchronous functions of PhoneGap easy by providing synchronous access to them. All device APIs are asynchronous in nature, but in cfclient block you call then as synchronous functions and ColdFusion translates them to asynchronous PhoneGap functions. All function starting with 'cfclient.', e.g. cfclient.camera.getPicture(), are asynchronous. In addition to device APIs, data access function, executeQuery and tag, cfquery, are also asynchronous in cfclient.

When you call asynchronous functions in cfclient, ColdFusion takes care of chaining callback functions - any code following an asynchronous function goes in the success callback function. But if you call asynchronous cfclient function form JavaScript code block, then ColdFusion compiler does not touch it. Note that if a UDF in cfclient block calls any asynchronous function (e.g. cfquery or any device APIs) then that function also becomes asynchronous.

Let's see an example. In the following code, I have a UDF in cfclient block, createDatabase. It does not need any argument, but let's say it takes one argument, arg1. This function calls queryExecute function, which is an asynchronous function - so createDatabase function also becomes asynchronous. If you call it from JavaScript and have some JS code to be executed only after database is created, then calling createDatabase function directly from JavaScript is not going to work as expected -

Read More


Slides of e-seminar - Everything about Mobile Application Development

April 11, 2014 / Ram Kulkarni

  Thunder | Adobe ColdFusion | Adobe ColdFusion Builder | e-seminar | Mobile | Splendor

I presented an e-seminar, Everything about Mobile Application Development, on 10th April. Some of the attendees had asked me to share the presentation and source code of the application. So here are the links

I had added a few useful links at the end of the presentation, but the PDF (linked above) of slides does not show those links. So here they are - 

Downloads

ColdFusion Documentation

CFMobile related Blogs

CFMobile related Videos

Recently PhoneGap Build made some changes in the way they pick up PhoneGap plugins. Because of this if you package the application (CFMobileExpenseTracker) using Public Beta builds, then image attachement feature would not work. We have fixed this issue post public beta. However there is a work around in public beta build- In the PhoneGap project properties of ColdFusion Thunder, select 'Load the configuration from XML' option and use this config.xml.




You can find the recording of this e-seminar here.

-Ram Kulkarni

Adobe ColdFusion Summit 2014

April 11, 2014 / Elishia

  Adobe ColdFusion | Adobe ColdFusion 10 | Announcements | CF Summit | ColdFusion | ColdFusion 11 | General

We are pleased to officially announce the next Adobe ColdFusion Summit to be held October 16th and 17th at Aria Resort & Casino, Las Vegas, Nevada.  It's going to be even better than last year and pricing remains very low at $299 early bird rate through July!

Read More


ColdFusion Splendor Public Beta E-seminar Series

April 07, 2014 / Rakshith Naresh

  Performance | Adobe ColdFusion | Language enhancements | PDF Generation | productivity | Splendor

We have a series of e-seminars lined up that gives you a good understanding of the various features of ColdFusion Splendor, which is now in public beta. If you haven't downloaded ColdFusion Splendor already, here is the link where you download the public beta.

Here are the list of e-seminars:

1. Title- Public Beta E-seminar: ColdFusion Splendor Overview Date: 1st April Time: 8 am pacific. Find the recording for the e-seminar here

2. Title- Public Beta E-seminar: Everything about Mobile Application Development Date: 10th April Time 8 am pacific. Find the recording for the e-seminar here

3. Title- Public Beta E-seminar: Delicious Language Enhancements in ColdFusion Splendor Date: 12nd April Time 8 am pacific. Register here 

4. Title- Public Beta E-seminar: Pixel Perfect PDFs in ColdFusion Splendor Date: 24th April Time 8 am pacific. Register here

 

 

 


CFMobile - How to display CF query data returned from remote CFC

March 29, 2014 / Ram Kulkarni

  Adobe ColdFusion | ColdFusion | Mobile | Splendor

In my last blog post, CFMobile Example – Accessing remote data from mobile application, I explained how to access data returned by a remote CFC. The CFC queried a database table, but returned array of struct/object to cfclient. 

In a comment on that blog post, Tayyab posted a problem, where in he returned a query object from CFC and tried to access it from cfclient. I thought instead of posting the answer as a comment, it deserved a separate post.
This is what he asked - 

These are the 2 most simplest coldfusion files. One is a cfc and the other a CFM but when I wrap the cfm into <cfscript> tag I get a blank page.

I think he meant wrapping CFML code in <cfclient>. The code in two files he posted were -

listCustomers.cfm

<cfinvoke component="customer" method="retrieveCustomers" returnvariable="allCustomers">
</cfinvoke>
<table width="100%" border="1" cellspacing="0" cellpadding="3">
	<tr>
		<td>
			First Name
		</td>
		<td>
			Last Name
		</td>
		<td>
			Email
		</td>
	</tr>
	<cfoutput query="allCustomers">
		<tr>
			<td>
				#firstName#
			</td>
			<td>
				#lastName#
			</td>
			<td>
				#email#
			</td>
		</tr>
	</cfoutput>
</table>

customer.cfc

<cfcomponent displayname="Customer" hint="ColdFusion Component for Customers">
	<cfset this.dsn = "books">
	<!--- This function retrieves all customers from the database --->
	
	<cffunction name="retrieveCustomers" hint="Gets all customer from the database" returntype="query" 
	            access="remote">
		<cfquery name="getCustomers" datasource=#this.dsn#>
			select * from Customers
		</cfquery>
		<cfreturn getCustomers>
	</cffunction>
	
</cfcomponent>

If you just wrapped code in listCustomers.cfm in <cfclient> block then nothing would be displayed.

The reason is that when you return CF Query from server to cfclient, it is serialized to a JavaScript Object, which is not really a CF Query object. This is also in fact different object than the query object that you get by executing client side query (see Creating database mobile application with ColdFusion Splendor) .


Loop iteration and query column access would not work on this object the way it works on the server side, or on the client side query object. You can see the structure of deserialized query object by logging the object to JavaScript console - insert <cfset console.log(books)> just after <cfinvoke> in listCustomers.cfm, run the page with JavaScript console of the browser open and observe its value.

So you need to access query rows and columns differently for CF query returned from the server. I have created a similar example as above - not using Customer database, but using cfbookclub data source that is shipped with Splendor. I have two files now - book.cfc and listBooks.cfm.

book.cfc

<cfcomponent displayname="Book" hint="ColdFusion Component for Books">
	<cfset this.dsn = "cfbookclub">
	<!--- This function retrieves all books from the database --->
	
	<cffunction name="getBooks" hint="Gets all books from the database" returntype="query" 
	            access="remote">
		<cfquery name="books" datasource=#this.dsn#>
			select * from books
		</cfquery>
		<cfreturn books>
	</cffunction>
	
</cfcomponent>

listBooks.cfm

<script >
	//Helper function to get value at given row and column of the query object
	function getQueryColumnValue (queryObj, rowNum, colName)
	{
				var defaulValue = "";
				
				if (typeof queryObj.__QUERY__ == 'undefined')
					return defaulValue;
				
				rowNum--;
				if (rowNum >= queryObj.length)
					return defaulValue;
					
				var row = queryObj.DATA[rowNum];
				
				var index = queryObj.COLUMNS.indexOf(colName);
				
				if (index < 0)
					return defaulValue;
					
				
				return row[index];
	}	
</script>

<cfclient>
	<cfinvoke component="book" method="getBooks" returnvariable="books">
	</cfinvoke>
	
	<table width="100%" border="1" cellspacing="0" cellpadding="3">
		<tr>
			<td>
				Title
			</td>
			<td>
				Description
			</td>
		</tr>
		<cfoutput >
			<cfloop index="i" from="1" to="#books.recordCount#">
				<tr>
				<td>
					#getQueryColumnValue(books,i,"TITLE")#
				</td>
				<td>
					#getQueryColumnValue(books,i,"BOOKDESCRIPTION")#
				</td>
				</td>
			</cfloop>
		</cfoutput>
	</table>
</cfclient>

Notice that I have created a helper function in JavaScript block to get value from query object at given a row and column. Also cfloop does not treat the value returned by CFC as query; it now iterates it using index. And lastly, query column names are all in upper case, because column names are upper-cased on the server.

We could probably simplify it a bit, but as of now this is how you can access server side CF query data in cfclient. If you are going to run the above example, make sure that cfbookclub data source is created on the server.

-Ram Kulkarni


Blue Mango Theme Design By Mark Aplet

Super Powered by Mango Blog