Framework One AJAX Method (FW/1)

NOTE: This is now obsolete. Use the method renderData() instead.

I really haven’t found a method I like that returns JSON via FW/1 until I saw a presentation by Steven Neiland the other day. Basically you have a few choices:

  1. Call a service directly: This leaves you w/o any FW/1 features and the service is not initialized.
  2. Create views that return JSON: This can become tedious and seems unnecessary, but FW/1 features are available
  3. Have onMissingView handle it: Views do not need to be created and FW/1 features are available

My approach uses #3.

Example jQuery AJAX call:

$.ajax({
	url: 'index.cfm?action=products.attributesAJAX',
	type: 'GET',
	dataType: 'json',
	data: {parentPartNumber: $('#productForm').data( 'parentpartnumber' )}
});

You’ll notice it requests the section “products” and the action “attributesAJAX”. We will not create the view for the action, but we will create the controller method for it.

component {

	function init( FW ) {
		variables.FW = FW;
		return this;
	}

	// AJAX
	void function attributesAJAX( required struct RC ) {
		FW.service( 'productService.getProductAttributes', 'data', { parentPartNumber = RC.parentPartNumber } );
	}

}

To return JSON data w/o creating a view, we let the Application.cfc’s onMissingView method handle the return:

function onMissingView( required struct RC) {
	// if a data key exists, assume this is for AJAX and render as JSON
	if ( structKeyExists( RC, "data" ) ) {
		request.layout = false; // turn off default layout
		new services.utility().showDebugOutput( false );
		getPageContext().getResponse().getResponse().setContentType('application/json');
		return serializeJSON( RC.data ); // convert data to JSON
	} else {
		return view( 'main/pageNotFound' ); // set view to the missing page message
	}
}

You’ll notice that if the view’s missing it looks for the RC.data value. If it exists it assumes you want to return JSON back. Otherwise it will call the “pageNotFound” view (which you need to create). Note how the layout is turned off, it calls a method to turn off debugging (for development), and sets the content type to JSON.

This is the utility I created to turn off debugging:

<cfcomponent output="false">

	<cffunction name="showDebugOutput" output="false" returntype="void">
		<cfargument name="switch" default="false" type="boolean">
		<cfsetting showdebugoutput="#arguments.switch#">
	</cffunction>

</cfcomponent>