<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jensbits.com &#187; ColdFusion</title>
	<atom:link href="http://www.jensbits.com/category/coldfusion/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jensbits.com</link>
	<description></description>
	<lastBuildDate>Wed, 21 Jul 2010 03:44:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Clicks and Impressions from Google Adwords API using ColdFusion</title>
		<link>http://www.jensbits.com/2010/07/18/clicks-and-impressions-from-google-adwords-api-using-coldfusion/</link>
		<comments>http://www.jensbits.com/2010/07/18/clicks-and-impressions-from-google-adwords-api-using-coldfusion/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 18:28:22 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Adwords]]></category>
		<category><![CDATA[ColdFusion]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=814</guid>
		<description><![CDATA[Requests for simple data like clicks and impressions from the Google Adwords API can be made via SOAP requests. For more complex data and calculations, the client libraries are more aptly suited. This example does not use the sandbox. Calls to it will counts against the Adwords units. It also uses the latest version of [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>Requests for simple data like clicks and impressions from the <a href="http://code.google.com/apis/adwords/v2009/docs/start.html">Google Adwords API</a> can be made via SOAP requests. For more complex data and calculations, the <a href="http://code.google.com/apis/adwords/v2009/docs/clientlibraries.html">client libraries</a> are more aptly suited.</p>
<p>This example does not use the sandbox. Calls to it will counts against the Adwords units. It also uses the latest version of the API, version v201003.</p>
<p>The requests require an authorization token which can be obtained via the ClientLogin method. Store this token in a session or application variable to prevent a CAPTCHA challend from Google for multiple authorization requests.</p>
<pre class="brush: coldfusion;">
&lt;cfif NOT StructKeyExists(application, &quot;adw_loginAuth&quot;)&gt;
	&lt;cfset googleLogin(api.email,api.password) /&gt;
&lt;/cfif&gt;

&lt;cffunction name=&quot;googleLogin&quot; access=&quot;private&quot; hint=&quot;GA account authorization&quot;&gt;
        &lt;cfargument name=&quot;email&quot; type=&quot;string&quot; required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;password&quot; type=&quot;string&quot;required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;gaLoginUrl&quot; type=&quot;string&quot; required=&quot;no&quot; default=&quot;https://www.google.com/accounts/ClientLogin&quot;&gt;

        &lt;cfset var loginAuth = &quot;&quot; /&gt;

        &lt;cfhttp url=&quot;#arguments.gaLoginUrl#&quot; method=&quot;post&quot;&gt;
            &lt;cfhttpparam name=&quot;accountType&quot; type=&quot;url&quot; value=&quot;GOOGLE&quot;&gt;
            &lt;cfhttpparam name=&quot;Email&quot; type=&quot;url&quot; value=&quot;#arguments.email#&quot;&gt;
            &lt;cfhttpparam name=&quot;Passwd&quot; type=&quot;url&quot; value=&quot;#arguments.password#&quot;&gt;
            &lt;cfhttpparam name=&quot;service&quot; type=&quot;url&quot; value=&quot;adwords&quot;&gt;
            &lt;cfhttpparam name=&quot;source&quot; type=&quot;url&quot; value=&quot;my-adwords-not-yours&quot;&gt;
        &lt;/cfhttp&gt;

        &lt;cfif NOT FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent)&gt;
            &lt;cfset loginAuth = &quot;Authorization Failed&quot; /&gt;
        &lt;cfelse&gt;
            &lt;cfset loginAuth = Mid(cfhttp.filecontent, FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent) + (Len(&quot;Auth=&quot;)), Len(cfhttp.filecontent)) /&gt;
        &lt;/cfif&gt;
        &lt;!--- authToken in application var to prevent Google from sending captcha request (recommended by Google) ---&gt;
        &lt;cflock scope=&quot;application&quot; type=&quot;exclusive&quot; timeout=&quot;5&quot;&gt;
			&lt;cfset application.adw_loginAuth = loginAuth /&gt;
		&lt;/cflock&gt;
&lt;/cffunction&gt;
</pre>
<p>The Adwords API is called with an http post request to the appropriate service with the data request specified using SOAP. </p>
<pre class="brush: xml;">
&lt;cfsavecontent variable=&quot;CampaignRequestXML&quot;&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns=&quot;https://adwords.google.com/api/adwords/cm/v201003&quot;&gt;
	&lt;soapenv:Header&gt;
		&lt;RequestHeader&gt;
            &lt;authToken&gt;#application.adw_loginAuth#&lt;/authToken&gt;
            &lt;userAgent&gt;V2010 Get All Campaign Info&lt;/userAgent&gt;
            &lt;developerToken&gt;ADWORDS-API-DEV-TOKEN&lt;/developerToken&gt;
            &lt;clientEmail&gt;CLIENT-EMAIL&lt;/clientEmail&gt;
        &lt;/RequestHeader&gt;
    &lt;/soapenv:Header&gt;
    &lt;soapenv:Body&gt;
    	&lt;get&gt;
        	&lt;selector&gt;
            	&lt;ids&gt;&lt;/ids&gt;
					&lt;statsSelector&gt;
						&lt;dateRange&gt;
							&lt;min&gt;20100101&lt;/min&gt;
							&lt;max&gt;20100715&lt;/max&gt;
						&lt;/dateRange&gt;
                        &lt;startDate/&gt;
						&lt;endDate/&gt;
                        &lt;network&gt;ALL&lt;/network&gt;
						&lt;clicks/&gt;
						&lt;impressions/&gt;
					&lt;/statsSelector&gt;
            &lt;/selector&gt;
        &lt;/get&gt;
    &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;
&lt;/cfsavecontent&gt;
</pre>
<p>Clicks and impressions are obtained using the campaign service. Data returned from the Adwords API is also in the SOAP format. After stripping the prefixes out of the SOAP response that will prevent the XMLSearch function in ColdFusion from working as expected, the data can be extracted and stored in variables and displayed.</p>
<pre class="brush: coldfusion;">
&lt;!--- http SOAP request and xml parse ---&gt;
&lt;cfset CampaignResponseXML = adwordsSOAPresponse(CampaignRequestXML) /&gt;

&lt;cffunction name=&quot;adwordsSOAPresponse&quot; access=&quot;private&quot; returnType=&quot;string&quot;&gt;
	&lt;cfargument name=&quot;xmlSOAPrequest&quot; type=&quot;string&quot; required=&quot;yes&quot; default=&quot;&quot;&gt;

	&lt;cfif application.adw_loginAuth NEQ &quot;Authorization Failed&quot;&gt;
        &lt;cfhttp url=&quot;https://adwords.google.com/api/adwords/cm/v201003/CampaignService&quot; method=&quot;post&quot;&gt;
           &lt;cfhttpparam name=&quot;SOAPAction&quot; type=&quot;header&quot; value=&quot;&quot;/&gt;
           &lt;cfhttpparam type=&quot;xml&quot; value=&quot;#trim(arguments.xmlSOAPrequest)#&quot;/&gt;
        &lt;/cfhttp&gt;
        &lt;cfset responseXML = cfhttp.filecontent /&gt;
    &lt;cfelse&gt;
        &lt;p&gt;Google Authorization Failed.&lt;/p&gt;
        &lt;cfabort /&gt;
    &lt;/cfif&gt;

    &lt;!---remove soap: prefix or any other prefix from nodes that have it ---&gt;
    &lt;cfset responseXML = responseXML.ReplaceAll(&quot;(&lt;/?)(\w+:)&quot;,&quot;$1&quot;) /&gt;
    &lt;!--- remove xmlns: ---&gt;
    &lt;cfset responseXML = responseXML.ReplaceAll(&quot;xmlns(:\w+)?=&quot;&quot;[^&quot;&quot;]*&quot;&quot;&quot;,&quot;&quot;) /&gt;
    &lt;!--- remove xsi element prefixes ---&gt;
    &lt;cfset responseXML = responseXML.ReplaceAll('(/?)(xsi:)','$1') /&gt;

    &lt;cfreturn responseXML /&gt;
&lt;/cffunction&gt;
</pre>
<p>Now the data can be extracted to an array using XMLSearch. Then put into an array of structures to make it easy to dump.</p>
<pre class="brush: coldfusion;">
&lt;cfset CampaignResponseXML = adwordsSOAPresponse(CampaignRequestXML) /&gt;

&lt;cfset CampaignEntryNodes = XmlSearch(CampaignResponseXML, '//entries/') /&gt;

&lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(CampaignEntryNodes)#&quot; index=&quot;num&quot;&gt;
	&lt;cfset entryStruct = StructNew() /&gt; 

    	&lt;cfset entryStruct.id = CampaignEntryNodes[num].id.XmlText /&gt;
        &lt;cfset entryStruct.name = CampaignEntryNodes[num].name.XmlText /&gt;
        &lt;cfset entryStruct.status = CampaignEntryNodes[num].status.XmlText /&gt;
        &lt;cfset entryStruct.clicks = CampaignEntryNodes[num].campaignStats.clicks.XmlText /&gt;
        &lt;cfset entryStruct.impressions = CampaignEntryNodes[num].campaignStats.impressions.XmlText /&gt;

		&lt;cfset totalClicks = totalClicks + CampaignEntryNodes[num].campaignStats.clicks.XmlText /&gt;
        &lt;cfset totalImpressions = totalImpressions + CampaignEntryNodes[num].campaignStats.impressions.XmlText /&gt;
        &lt;cfset arrayAppend(campaignStatsArray,duplicate(entryStruct)) /&gt;

&lt;/cfloop&gt;

&lt;cfdump var=&quot;#campaignStatsArray#&quot;&gt;
&lt;p&gt;Total clicks: #totalClicks#&lt;br /&gt;
Total Impressions: #totalImpressions#&lt;/p&gt;
</pre>
<p>Code in its entirety:</p>
<pre class="brush: coldfusion;">
&lt;!--- cfapplication is not needed if application.cfc exists ---&gt;
&lt;cfapplication name=&quot;adwordsapi&quot; applicationtimeout=&quot;#createtimespan(2,0,0,0)#&quot; /&gt;

&lt;cfset totalClicks = 0 /&gt;
&lt;cfset totalImpressions = 0 /&gt;
&lt;cfset campaignStatsArray = ArrayNew(1) /&gt;
&lt;cfset campaignID = &quot;&quot; /&gt;
&lt;cfset campaignStatusArray = ArrayNew(1) /&gt;
&lt;!---
	Adwords API parameters:
	Set email and password to adwords account
	Dev token is from MCC API details
---&gt;
&lt;cfscript&gt;
   api = structnew();
   api.email = &quot;GMAIL-ADDRESS-HERE&quot;;
   api.password = &quot;GMAIL-PASSWORD&quot;;
   api.devtoken = &quot;API-DEV-TOKEN&quot;;
   api.campaignService = &quot;https://adwords.google.com/api/adwords/cm/v201003/CampaignService&quot;;
   api.clientEmail = &quot;CLIENT-EMAIL-HERE&quot;;
   api.startDate = DateFormat(Now(), 'yyyymmdd');
   api.endDate = DateFormat(Now(), 'yyyymmdd');
&lt;/cfscript&gt;

&lt;cfif NOT StructKeyExists(application, &quot;adw_loginAuth&quot;)&gt;
	&lt;cfset googleLogin(api.email,api.password) /&gt;
&lt;/cfif&gt;

&lt;cffunction name=&quot;googleLogin&quot; access=&quot;private&quot; hint=&quot;GA account authorization&quot;&gt;
        &lt;cfargument name=&quot;email&quot; type=&quot;string&quot; required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;password&quot; type=&quot;string&quot;required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;gaLoginUrl&quot; type=&quot;string&quot; required=&quot;no&quot; default=&quot;https://www.google.com/accounts/ClientLogin&quot;&gt;

        &lt;cfset var loginAuth = &quot;&quot; /&gt;

        &lt;cfhttp url=&quot;#arguments.gaLoginUrl#&quot; method=&quot;post&quot;&gt;
            &lt;cfhttpparam name=&quot;accountType&quot; type=&quot;url&quot; value=&quot;GOOGLE&quot;&gt;
            &lt;cfhttpparam name=&quot;Email&quot; type=&quot;url&quot; value=&quot;#arguments.email#&quot;&gt;
            &lt;cfhttpparam name=&quot;Passwd&quot; type=&quot;url&quot; value=&quot;#arguments.password#&quot;&gt;
            &lt;cfhttpparam name=&quot;service&quot; type=&quot;url&quot; value=&quot;adwords&quot;&gt;
            &lt;cfhttpparam name=&quot;source&quot; type=&quot;url&quot; value=&quot;adwords-clicks-impressions&quot;&gt;
        &lt;/cfhttp&gt;

        &lt;cfif NOT FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent)&gt;
            &lt;cfset loginAuth = &quot;Authorization Failed&quot; /&gt;
        &lt;cfelse&gt;
            &lt;cfset loginAuth = Mid(cfhttp.filecontent, FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent) + (Len(&quot;Auth=&quot;)), Len(cfhttp.filecontent)) /&gt;
        &lt;/cfif&gt;
        &lt;!--- authToken in application var to prevent Google from sending captcha request (recommended by Google) ---&gt;
        &lt;cflock scope=&quot;application&quot; type=&quot;exclusive&quot; timeout=&quot;5&quot;&gt;
			&lt;cfset application.adw_loginAuth = loginAuth /&gt;
		&lt;/cflock&gt;
&lt;/cffunction&gt;

&lt;cffunction name=&quot;adwordsSOAPresponse&quot; access=&quot;private&quot; returnType=&quot;string&quot;&gt;
	&lt;cfargument name=&quot;xmlSOAPrequest&quot; type=&quot;string&quot; required=&quot;yes&quot; default=&quot;&quot;&gt;

	&lt;cfif application.adw_loginAuth NEQ &quot;Authorization Failed&quot;&gt;
        &lt;cfhttp url=&quot;#api.campaignService#&quot; method=&quot;post&quot;&gt;
           &lt;cfhttpparam name=&quot;SOAPAction&quot; type=&quot;header&quot; value=&quot;&quot;/&gt;
           &lt;cfhttpparam type=&quot;xml&quot; value=&quot;#trim(arguments.xmlSOAPrequest)#&quot;/&gt;
        &lt;/cfhttp&gt;
        &lt;cfset responseXML = cfhttp.filecontent /&gt;
    &lt;cfelse&gt;
        &lt;p&gt;Google Authorization Failed.&lt;/p&gt;
        &lt;cfabort /&gt;
    &lt;/cfif&gt;

    &lt;!---remove soap: prefix or any other prefix from nodes that have it ---&gt;
    &lt;cfset responseXML = responseXML.ReplaceAll(&quot;(&lt;/?)(\w+:)&quot;,&quot;$1&quot;) /&gt;
    &lt;!--- remove xmlns: ---&gt;
    &lt;cfset responseXML = responseXML.ReplaceAll(&quot;xmlns(:\w+)?=&quot;&quot;[^&quot;&quot;]*&quot;&quot;&quot;,&quot;&quot;) /&gt;
    &lt;!--- remove xsi element prefixes ---&gt;
    &lt;cfset responseXML = responseXML.ReplaceAll('(/?)(xsi:)','$1') /&gt;

    &lt;cfreturn responseXML /&gt;
&lt;/cffunction&gt;

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;Adwords API&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;cfoutput&gt;

&lt;!---Campaign Info ---&gt;
&lt;cfsavecontent variable=&quot;CampaignRequestXML&quot;&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns=&quot;https://adwords.google.com/api/adwords/cm/v201003&quot;&gt;
	&lt;soapenv:Header&gt;
		&lt;RequestHeader&gt;
            &lt;authToken&gt;#application.adw_loginAuth#&lt;/authToken&gt;
            &lt;userAgent&gt;V2010 Get All Campaign Info&lt;/userAgent&gt;
            &lt;developerToken&gt;#api.devtoken#&lt;/developerToken&gt;
            &lt;clientEmail&gt;#api.clientEmail#&lt;/clientEmail&gt;
        &lt;/RequestHeader&gt;
    &lt;/soapenv:Header&gt;
    &lt;soapenv:Body&gt;
    	&lt;get&gt;
        	&lt;selector&gt;
            	&lt;ids&gt;&lt;/ids&gt;
					&lt;statsSelector&gt;
						&lt;dateRange&gt;
							&lt;min&gt;#api.startDate#&lt;/min&gt;
							&lt;max&gt;#api.endDate#&lt;/max&gt;
						&lt;/dateRange&gt;
                        &lt;startDate/&gt;
						&lt;endDate/&gt;
                        &lt;network&gt;ALL&lt;/network&gt;
						&lt;clicks/&gt;
						&lt;impressions/&gt;
					&lt;/statsSelector&gt;
            &lt;/selector&gt;
        &lt;/get&gt;
    &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;
&lt;/cfsavecontent&gt;

&lt;!--- http SOAP request and xml parse ---&gt;
&lt;cfset CampaignResponseXML = adwordsSOAPresponse(CampaignRequestXML) /&gt;

&lt;cfset CampaignEntryNodes = XmlSearch(CampaignResponseXML, '//entries/') /&gt;

&lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(CampaignEntryNodes)#&quot; index=&quot;num&quot;&gt;
	&lt;cfset entryStruct = StructNew() /&gt; 

    	&lt;cfset entryStruct.id = CampaignEntryNodes[num].id.XmlText /&gt;
        &lt;cfset entryStruct.name = CampaignEntryNodes[num].name.XmlText /&gt;
        &lt;cfset entryStruct.status = CampaignEntryNodes[num].status.XmlText /&gt;
        &lt;cfset entryStruct.clicks = CampaignEntryNodes[num].campaignStats.clicks.XmlText /&gt;
        &lt;cfset entryStruct.impressions = CampaignEntryNodes[num].campaignStats.impressions.XmlText /&gt;

		&lt;cfset totalClicks = totalClicks + CampaignEntryNodes[num].campaignStats.clicks.XmlText /&gt;
        &lt;cfset totalImpressions = totalImpressions + CampaignEntryNodes[num].campaignStats.impressions.XmlText /&gt;
        &lt;cfset arrayAppend(campaignStatsArray,duplicate(entryStruct)) /&gt;

&lt;/cfloop&gt;

&lt;cfdump var=&quot;#campaignStatsArray#&quot;&gt;
&lt;p&gt;Total clicks: #totalClicks#&lt;br /&gt;
Total Impressions: #totalImpressions#&lt;/p&gt;

&lt;/cfoutput&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/07/18/clicks-and-impressions-from-google-adwords-api-using-coldfusion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples</title>
		<link>http://www.jensbits.com/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/</link>
		<comments>http://www.jensbits.com/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/#comments</comments>
		<pubDate>Sat, 29 May 2010 20:41:53 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=730</guid>
		<description><![CDATA[As requested, this post covers using one jquery autocomplete to populate another jquery autocomplete on the same page. This example will use a jquery autocomplete to choose a state then, based on the state, another jquery autocomplete will be populated with zip codes for that state. Basically, the state chosen gets used as a filter [...]


Related posts:<ol><li><a href='http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion'>jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2010/03/18/jquery-ui-autocomplete-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with ColdFusion'>jQuery UI Autocomplete Widget with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2009/10/04/jquery-ajax-and-jquery-post-form-submit-examples-with-php/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with PHP'>jQuery.ajax and jQuery.post Form Submit Examples with PHP</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>As requested, this post covers using one jquery autocomplete to populate another jquery autocomplete on the same page. This example will use a jquery autocomplete to choose a state then, based on the state, another jquery autocomplete will be populated with zip codes for that state. Basically, the state chosen gets used as a filter in the query for the second autocomplete.</p>
<h2>Form</h2>
<p>The form for the examples is the same with fields for the autocompletes (state and zip_code) plus input fields for the values returned by the autocompletes.</p>
<pre class="brush: xml;">
&lt;form action=&quot;YOUR-FILE-HERE&quot;  method=&quot;post&quot;&gt;
&lt;fieldset&gt;
&lt;legend&gt;jQuery UI Multi-Autocomplete Example&lt;/legend&gt;
&lt;p&gt;Start typing the name of a state or territory of the United States&lt;/p&gt;

&lt;p&gt;&lt;label for=&quot;state&quot;&gt;State (abbreviation in separate field): &lt;/label&gt;
&lt;input type=&quot;text&quot; id=&quot;state&quot;  name=&quot;state&quot; /&gt; &lt;input readonly=&quot;readonly&quot; type=&quot;text&quot; id=&quot;abbrev&quot; name=&quot;abbrev&quot; maxlength=&quot;2&quot; size=&quot;2&quot;/&gt;&lt;/p&gt;

&lt;input type=&quot;hidden&quot; id=&quot;state_id&quot; name=&quot;state_id&quot; /&gt;

&lt;p&gt;&lt;label for=&quot;zip_code&quot;&gt;Zip (only Zips from state selected above): &lt;/label&gt;
&lt;input type=&quot;text&quot; id=&quot;zip_code&quot; name=&quot;zip_code&quot; maxlength=&quot;5&quot; size=&quot;15&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;ui-widget&quot;&gt;&lt;label for=&quot;city&quot;&gt;City:&lt;/label&gt;
&lt;input readonly=&quot;readonly&quot; type=&quot;text&quot; id=&quot;city&quot; name=&quot;city&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot; /&gt;&lt;/p&gt;
&lt;/fieldset&gt;
&lt;/form&gt;
</pre>
<h2>jQuery</h2>
<p>The jquery is also the same for each example. Notice that the zip_code field is initially disabled to prevent entry before the results have been filtered.</p>
<p>Also, note that the source and secondary URL extension will have to be modified depending on the language you are using.</p>
<pre class="brush: jscript;">
$(function() {

			//clear values on refresh
			$('#abbrev').val(&quot;&quot;);
			$('#city').val(&quot;&quot;);

			$(&quot;#zip_code&quot;).attr('disabled', true);

			$(&quot;#state&quot;).autocomplete({
				source: &quot;states.[cfm|aspx|php]&quot;,
				minLength: 2,
				select: function(event, ui) {
					$('#state_id').val(ui.item.id);
					$('#abbrev').val(ui.item.abbrev);
					$(&quot;#zip_code&quot;).attr('disabled', false);
				},
				change: function(event, ui){
					secondary_url = &quot;zips.[cfm|aspx|php]?filter=&quot; + ui.item.abbrev;
					$(&quot;#zip_code&quot;).autocomplete(&quot;option&quot;, &quot;source&quot;, secondary_url);
				}
			});

			$(&quot;#zip_code&quot;).autocomplete({
				source: &quot;&quot;,
				minLength: 2,
				select: function(event,ui){
					$('#city').val(ui.item.city);
				}
			});

		});
</pre>
<h2>Processing</h2>
<p>Each programming language differs slightly in the processing. And, since there are hundreds of zip codes per state, the results are limited to 20. If the zip code desired is not returned in the top 20 after entering the minimum 2 characters, typing more characters will yield more precise results.</p>
<h3>ASP.NET</h3>
<p>Refer to the <a href="/2010/04/14/jquery-ui-autocomplete-widget-with-asp-net/">complete example of using the jquery autocomplete with ASP.NET</a> for more information. </p>
<pre class="brush: vb;">
&lt;%@ Page Language=&quot;VB&quot; Debug=&quot;false&quot; %&gt;
&lt;%@ Import Namespace=&quot;System.Web.Script.Serialization&quot; %&gt;
&lt;%@ Import Namespace=&quot;System.Data&quot; %&gt;
&lt;%@ Import Namespace=&quot;System.Data.SqlClient&quot; %&gt;

&lt;script runat=&quot;server&quot;&gt;
    Dim serializer As JavaScriptSerializer

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        serializer = New JavaScriptSerializer()
        Response.Write(JSONData(Request.QueryString(&quot;Term&quot;)))
    End Sub

    Public Class Zip
        Public zipcode As String
		Public label As String
		Public value As String
        Public city As String
    End Class

    Private Function JSONData(ByVal term As String) As String

        Dim zipArray As New ArrayList
        Dim index As Integer = 0

        Dim mySql As String
        Dim objConn As New SqlConnection(&quot;Server=YOUR-SERVER;Database=YOUR-DATABASE;User ID=YOUR-USERID;Password=YOUR-PASSWORD&quot;)
        Dim myds As New DataSet(&quot;Zips&quot;)
        mySql = &quot;SELECT TOP 20 zip, city FROM zips WHERE abbrev = '&quot; + Request.QueryString(&quot;filter&quot;) + &quot;' AND zip like '&quot; + term + &quot;%'&quot;

        objConn.Open()

        Dim adapter As New SqlClient.SqlDataAdapter(mySql, objConn)
        adapter.Fill(myds, &quot;Zips&quot;)
        For Each dr As DataRow In myds.Tables(0).Rows
            Dim zp As New Zip()
            zp.label = dr(&quot;zip&quot;).ToString() &amp; &quot; &quot; &amp; dr(&quot;city&quot;).ToString()
            zp.value = dr(&quot;zip&quot;).ToString()
            zp.city = dr(&quot;city&quot;).ToString()
            zipArray.Add(zp)
        Next

        objConn.Close()

        Return serializer.Serialize(zipArray)
    End Function

&lt;/script&gt;
</pre>
<p id="demo"><a href="http://cf-jensbits.com/demos/autocomplete_asp/zipselect.aspx" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/autocomplete_asp/zipselect.aspx']); return false;"><br />
<span>Demo</span></a></p>
<h3>ColdFusion</h3>
<p>Refer to the <a href="/2010/03/18/jquery-ui-autocomplete-with-coldfusion/">complete example of using the jquery autocomplete with ColdFusion</a> for more information.</p>
<p>ColdFusion&#8217;s serializeJSON function has an odd bug that will not let you send numbers as strings. This turns the zip codes into numbers which we do not want. To workaround this, I added a space in front of the zip code then removed it from the JSON output with the Replace function. Not the best idea, but it works.</p>
<pre class="brush: coldfusion;">
&lt;cfset returnArray = ArrayNew(1) /&gt;

&lt;cfquery name=&quot;qryStates&quot; dataSource=&quot;autocomplete&quot;&gt;
	SELECT TOP 20 zip, city FROM zips WHERE abbrev = '#URL.filter#' AND zip like '#URL.term#%'
&lt;/cfquery&gt;

&lt;cfloop query=&quot;qryStates&quot;&gt;
	&lt;cfset zipsStruct = StructNew() /&gt;
    &lt;cfset zipsStruct[&quot;label&quot;] = ToString(zip) &amp; &quot; &quot; &amp; city /&gt;
    &lt;!---Had to add leading space to prevent serializeJSON from turning zip into number---&gt;
    &lt;cfset zipsStruct[&quot;value&quot;] = &quot; &quot; &amp; zip /&gt;
    &lt;cfset zipsStruct[&quot;city&quot;] = city /&gt;

    &lt;cfset ArrayAppend(returnArray,zipsStruct) /&gt;
&lt;/cfloop&gt;

&lt;cfoutput&gt;
&lt;!---replaced all spaces after quotes with just quotes in JSON to remove leading space applied to zip---&gt;
#Replace(serializeJSON(returnArray),'&quot; ','&quot;',&quot;all&quot;)#
&lt;/cfoutput&gt;
</pre>
<p id="demo"><a href="http://cf-jensbits.com/demos/autocomplete/zipselect.cfm" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/autocomplete/zipselect.cfm']); return false;"><br />
<span>Demo</span></a></p>
<h3>PHP</h3>
<p>Refer to the <a href="/2010/03/29/jquery-ui-autocomplete-widget-with-php-and-mysql/">complete example of using the jquery autocomplete with PHP</a> for more information.</p>
<p>This PHP example using SQL Server as the database. The complete example linked above uses MySQL.</p>
<pre class="brush: php;">
&lt;?php
$dbhost = 'YOUR_SERVER';
$dbuser = 'YOUR_USERNAME';
$dbpass = 'YOUR_PASSWORD';
$dbname = 'YOUR_DATABASE_NAME';

$conn = mssql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mssql');
mssql_select_db($dbname);

$return_arr = array();

if ($conn)
{
	$fetch = mssql_query(&quot;SELECT TOP 20 zip, city FROM zips WHERE abbrev = '&quot; . $_GET['filter'] . &quot;' AND zip like '&quot; . $_GET['term'] . &quot;%'&quot;); 

	/* Retrieve and store in array the results of the query.*/

	while ($row = mssql_fetch_array($fetch)) {
		$row_array['label'] = $row['zip'] . &quot; &quot; . $row['city'];
		$row_array['value'] = $row['zip'];
		$row_array['city'] = $row['city'];

        array_push($return_arr,$row_array);
    }

}
/* Free connection resources. */
mssql_close($conn);

/* Toss back results as json encoded array. */
echo json_encode($return_arr);

?&gt;
</pre>
<p id="demo"><a href="http://cf-jensbits.com/demos/autocomplete_php/zipselect.php" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/autocomplete_php/zipselect.php']); return false;"><br />
<span>Demo</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>Related posts:<ol><li><a href='http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion'>jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2010/03/18/jquery-ui-autocomplete-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with ColdFusion'>jQuery UI Autocomplete Widget with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2009/10/04/jquery-ajax-and-jquery-post-form-submit-examples-with-php/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with PHP'>jQuery.ajax and jQuery.post Form Submit Examples with PHP</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Generating Signatures in ColdFusion with RSA-SHA1 for Secure AuthSub in Google Analytics</title>
		<link>http://www.jensbits.com/2010/05/16/generating-signatures-in-coldfusion-with-rsa-sha1-for-secure-authsub-in-google-analytics/</link>
		<comments>http://www.jensbits.com/2010/05/16/generating-signatures-in-coldfusion-with-rsa-sha1-for-secure-authsub-in-google-analytics/#comments</comments>
		<pubDate>Sun, 16 May 2010 21:24:38 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Google Analytics]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=726</guid>
		<description><![CDATA[To send secure AuthSub requests to Google Analytics, you have to sign the request with a private key that is verified against the certificate you upload to Google. Google has a library where this can be done in Java that is specific to Google Analytics and, provided you can add .jar files to your ColdFusion [...]


Related posts:<ol><li><a href='http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/' rel='bookmark' title='Permanent Link: ColdFusion and Google Analytics: Getting Out What You Put In'>ColdFusion and Google Analytics: Getting Out What You Put In</a></li>
<li><a href='http://www.jensbits.com/2009/05/02/hooking-into-google-analytics-with-coldfusion/' rel='bookmark' title='Permanent Link: Hooking into Google Analytics with ColdFusion'>Hooking into Google Analytics with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2009/05/10/google-analytics-api-login-authentication-with-coldfusion/' rel='bookmark' title='Permanent Link: Google Analytics API Login Authentication with ColdFusion'>Google Analytics API Login Authentication with ColdFusion</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>To send secure AuthSub requests to Google Analytics, you have to sign the request with a private key that is verified against the certificate you upload to Google. Google has a library where this can be done in Java that is specific to Google Analytics and, provided you can add .jar files to your ColdFusion server or use <a href="http://javaloader.riaforge.org/">javaloader</a>, you can run them using ColdFusion. If you need to roll your own or simply want to control the process, this example may help.</p>
<p>Before you implement any code that signs requests, the keys and certificate must be generated and then registered with Google you are attempting to access. Google has <a href="http://code.google.com/apis/gdata/docs/auth/authsub.html#Registered">instructions on how to generate the keys and certificate using OpenSSL</a> and <a href="http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html">how to register the certificate with Google</a>. You will need the private key in the PKCS#8 format.</p>
<p>Google also supplies <a href="http://code.google.com/apis/accounts/docs/AuthSub.html#signingrequests">instructions for signing the AuthSub requests</a> which is what we will step through here.</p>
<p>To get a single-use token for secure AuthSub, you send the user to authenticate through Google with a link similar to this:</p>
<pre class="brush: xml;">
&lt;a href=&quot;https://www.google.com/accounts/AuthSubRequest?next=YOUR_PAGE_HERE?secureAuth=yes&amp;scope=https://www.google.com/analytics/feeds/&amp;secure=1&amp;session=1&quot;&gt;Log in using Secure AuthSub through Google&lt;/a&gt;
</pre>
<p>Notice that secure is set to 1 indicating we want to send secure requests. Session is also set to 1 indicating we want a multi-use authorization token for multiple calls to the Google Analytics Data Export API. If you are only making one call to the API, you can set session to 0 (zero).</p>
<p>Google will then the user to your page designated by the next parameter with the token attached as a URL parameter called &#8220;token.&#8221; After getting this single-use token back from Google, you then need to send it back to Google to exchange for your multi-use token. This is where the signing begins. Every request from this point forward needs to be signed.</p>
<p>Secure AuthSub differs from AuthSub in that it requires several parameters to be added to the Authorization header of the request. They are:</p>
<ol>
<li>token: single-use token (or multi-use token once you get it) from Google</li>
<li>sigalg: rsa-sah1</li>
<li>data: the http-method, request URL, timestamp, and nonce all separated by a space.</li>
<li>sig: the signature made by the private key generated against the data parameter above.</li>
</ol>
<p>Generating this only requires a few lines of ColdFusion code:</p>
<pre class="brush: coldfusion;">
        &lt;cfset Math = createObject('java','java.lang.Math') /&gt;
        &lt;cfset randNum = createObject('java', 'java.security.SecureRandom') /&gt;
        &lt;cfset numeric_nonce = Math.abs(JavaCast(&quot;long&quot;,randNum.nextLong())) /&gt;
        &lt;cfset nonce = numeric_nonce.toString() /&gt;
        &lt;cfset timestmp = DateDiff(&quot;s&quot;,DateConvert(&quot;utc2Local&quot;, &quot;January 1 1970 00:00&quot;), Now()) /&gt;

        &lt;cfset appSignature = rsa_sha1(rsaPrivateKey, 'GET https://www.google.com/accounts/AuthSubSessionToken ' &amp; timestmp &amp; ' ' &amp; nonce) /&gt;

        &lt;cfset authHeaderValue = 'AuthSub token=&quot;' &amp; URL.token &amp; '&quot; data=&quot;GET https://www.google.com/accounts/AuthSubSessionToken ' &amp; timestmp &amp; ' ' &amp; nonce &amp; '&quot; sig=&quot;' &amp; appSignature &amp; '&quot;  sigalg=&quot;rsa-sha1&quot;' /&gt;
</pre>
<p>The rsa_sha1 function creates the signature. It was written by Sharad Gupta and used here with permission.</p>
<pre class="brush: coldfusion;">
&lt;cffunction name=&quot;rsa_sha1&quot; returntype=&quot;string&quot; access=&quot;public&quot; descrition=&quot;RSA-SHA1 computation based on supplied private key and supplied base signature string.&quot;&gt;
    &lt;!---Written by Sharad Gupta sharadg@gmail.com (used with permission)---&gt;
           &lt;cfargument name=&quot;signKey&quot; type=&quot;string&quot; required=&quot;true&quot; hint=&quot;base64 formatted PKCS8 private key&quot;&gt;
           &lt;cfargument name=&quot;signMessage&quot; type=&quot;string&quot; required=&quot;true&quot; hint=&quot;msg to sign&quot;&gt;
           &lt;cfargument name=&quot;sFormat&quot; type=&quot;string&quot; required=&quot;false&quot; default=&quot;UTF-8&quot;&gt;

           &lt;cfset var jKey = JavaCast(&quot;string&quot;, arguments.signKey)&gt;
           &lt;cfset var jMsg = JavaCast(&quot;string&quot;,arguments.signMessage).getBytes(arguments.sFormat)&gt;

           &lt;cfset var key = createObject(&quot;java&quot;, &quot;java.security.PrivateKey&quot;)&gt;
           &lt;cfset var keySpec = createObject(&quot;java&quot;,&quot;java.security.spec.PKCS8EncodedKeySpec&quot;)&gt;
           &lt;cfset var keyFactory = createObject(&quot;java&quot;,&quot;java.security.KeyFactory&quot;)&gt;
           &lt;cfset var b64dec = createObject(&quot;java&quot;, &quot;sun.misc.BASE64Decoder&quot;)&gt;

           &lt;cfset var sig = createObject(&quot;java&quot;, &quot;java.security.Signature&quot;)&gt;

           &lt;cfset var byteClass = createObject(&quot;java&quot;, &quot;java.lang.Class&quot;)&gt;
           &lt;cfset var byteArray = createObject(&quot;java&quot;,&quot;java.lang.reflect.Array&quot;)&gt;

           &lt;cfset byteClass = byteClass.forName(JavaCast(&quot;string&quot;,&quot;java.lang.Byte&quot;))&gt;
           &lt;cfset keyBytes = byteArray.newInstance(byteClass, JavaCast(&quot;int&quot;,&quot;1024&quot;))&gt;
           &lt;cfset keyBytes = b64dec.decodeBuffer(jKey)&gt;

           &lt;cfset sig = sig.getInstance(&quot;SHA1withRSA&quot;, &quot;SunJSSE&quot;)&gt;
           &lt;cfset sig.initSign(keyFactory.getInstance(&quot;RSA&quot;).generatePrivate(keySpec.init(keyBytes)))&gt;
           &lt;cfset sig.update(jMsg)&gt;
           &lt;cfset signBytes = sig.sign()&gt;

           &lt;cfreturn ToBase64(signBytes)&gt;
     &lt;/cffunction&gt;
</pre>
<p>The request for and parsing out of the multi-use token looks like this:</p>
<pre class="brush: coldfusion;">
&lt;cfhttp url=&quot;https://www.google.com/accounts/AuthSubSessionToken&quot; method=&quot;GET&quot;&gt;
 &lt;cfhttpparam name=&quot;Authorization&quot; type=&quot;header&quot; value=&quot;#authHeaderValue#&quot;&gt;
&lt;/cfhttp&gt;

&lt;cfset output = cfhttp.filecontent /&gt;

&lt;cfset authSubSessionToken = Mid(output, FindNoCase(&quot;Token=&quot;,output) + (Len(&quot;Token=&quot;)), Len(output)) /&gt;
</pre>
<p>Any more requests of the Data Export API have to be made in the same manner except now you will use the multi-use token (authSubSessionToken) as the token in the Authorization header.</p>
<h2>Recommended</h2>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=032166034X" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470529393" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470562315" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470531282" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>Related posts:<ol><li><a href='http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/' rel='bookmark' title='Permanent Link: ColdFusion and Google Analytics: Getting Out What You Put In'>ColdFusion and Google Analytics: Getting Out What You Put In</a></li>
<li><a href='http://www.jensbits.com/2009/05/02/hooking-into-google-analytics-with-coldfusion/' rel='bookmark' title='Permanent Link: Hooking into Google Analytics with ColdFusion'>Hooking into Google Analytics with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2009/05/10/google-analytics-api-login-authentication-with-coldfusion/' rel='bookmark' title='Permanent Link: Google Analytics API Login Authentication with ColdFusion'>Google Analytics API Login Authentication with ColdFusion</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/05/16/generating-signatures-in-coldfusion-with-rsa-sha1-for-secure-authsub-in-google-analytics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ColdFusion Session Timeout with Warning and jQuery Session Refresh</title>
		<link>http://www.jensbits.com/2010/04/18/coldfusion-session-timeout-with-warning-and-session-refresh/</link>
		<comments>http://www.jensbits.com/2010/04/18/coldfusion-session-timeout-with-warning-and-session-refresh/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 19:05:08 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=681</guid>
		<description><![CDATA[There are times when a user needs to sit on a page for a while either to read or fill out a long form. If their visit is controlled by a session timeout, for example a member site, then the session needs to be refreshed without refreshing the page. My previous post on user session [...]


Related posts:<ol><li><a href='http://www.jensbits.com/2009/09/12/session-timeout-warning-with-coldfusion-and-jqueryjs/' rel='bookmark' title='Permanent Link: ColdFusion Example: Session Timeout Warning with jQuery/JS'>ColdFusion Example: Session Timeout Warning with jQuery/JS</a></li>
<li><a href='http://www.jensbits.com/2009/07/29/coldfusion-dropping-losing-or-resetting-session-variables-and-cfidcftoken/' rel='bookmark' title='Permanent Link: ColdFusion Dropping, Losing, or Resetting Session Variables and CFID/CFTOKEN'>ColdFusion Dropping, Losing, or Resetting Session Variables and CFID/CFTOKEN</a></li>
<li><a href='http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion'>jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>There are times when a user needs to sit on a page for a while either to read or fill out a long form. If their visit is controlled by a session timeout, for example a member site, then the session needs to be refreshed without refreshing the page. My <a href="/2009/09/12/session-timeout-warning-with-coldfusion-and-jqueryjs/">previous post on user session warning</a> used a page refresh to renew the session. This example will refresh the session with a jquery .post so the browser maintains state. </p>
<p>Much of what happens here is very similar to the previous page reload session refresh so you will see some of the same explanatory text. Changes to the code mainly affect the jquery/javascript since the variables and timers need to be reset without refreshing the page.</p>
<p>Javascript is needed to keep track of the time the user has been sitting on the page. The server does not know how long they have been sitting there. It only knows whether or not a request comes in during a session or after the session has expired and acts accordingly at that time. Too late for a warning.</p>
<h3>Session Defined: Start to Finish</h3>
<p>A session is defined as when a user begins and ends using or visiting a web site. It can be unlimited in length or strictly defined by a timeout period. If the site requires a log in or accesses sensitive data, it should time out after a period of inactivity. They can end a session by logging out or closing the browser.</p>
<p>Inactivity means the user has done nothing, made no requests of the web server, during a specified time. Ajax requests usually do not count. </p>
<h3>Demo</h3>
<p>The session time left is determined by the server, and, if you want to poll the server with an Ajax request, go for it. Javascript is used to keep track of the time left in the session.</p>
<p>The demo uses a simple log in with session timing handled by jquery and javascript. When the session expiration approaches, the user is warned and given an opportunity to restart the session. If the session time limit is reached, the user is prompted to log in again. If they ignore that prompt, the page automatically redirects to the log in form. In the demo this sequence of events takes 40 seconds to complete and is broken down as follows:</p>
<ol>
<li><em>Session timeout:</em> 30 seconds</li>
<li><strong>Timeout warning:</strong> 20 seconds</li>
<li><strong>Session expired warning:</strong> 10 seconds</li>
<li><strong>Redirect to log in page: </strong>10 seconds</li>
</ol>
<h3>Interrupting the User</h3>
<p>The user&#8217;s attention can be diverted away from other open windows to the eminent session expiration by using a javascript alert in place of the jquery dialog box. Personal preference.</p>
<h3>Code Breakdown</h3>
<p>The application.cfc controls the session by creating non-persistent cookies for CFID and CFTOKEN so the session expires when the user&#8217;s browser closes. It also sets the session variable sessionStartTime. The sessionStartTime variable is used to illustrate the fact that the application.cfc function OnSessionStart only fires once. It does not fire every time a session is renewed or restarted.</p>
<p>RequestStartTime is set in the OnRequestStart function to provide a reference for comparison later. See &#8220;Just for Fun&#8221; section below.</p>
<pre class="brush: coldfusion;">
&lt;cfcomponent
    displayname=&quot;Application&quot;
    output=&quot;false&quot;
    hint=&quot;Handle the application.&quot;&gt;

    &lt;!--- Set up the application. ---&gt;
    &lt;cfset THIS.Name = &quot;sessionrefreshtest&quot; /&gt;
    &lt;cfset THIS.ApplicationTimeout = CreateTimeSpan(0,1,0,0) /&gt;
    &lt;!--- CreateTimeSpan(days, hours, minutes, seconds) ---&gt;
    &lt;cfset THIS.SessionTimeout = CreateTimeSpan(0,0,0,30) /&gt;
    &lt;cfset THIS.SessionManagement = true /&gt;
    &lt;cfset THIS.SetClientCookies = false /&gt;

    &lt;cffunction
        name=&quot;OnSessionStart&quot;
        access=&quot;public&quot;
        returntype=&quot;void&quot;
        output=&quot;false&quot;
        hint=&quot;Fires ONLY ONCE when session first created and not when session renewed/restarted.&quot;&gt;       

        &lt;!---set cfid/cftoken as non-persistent cookies so session ends on browser close ---&gt;
        &lt;cfif not IsDefined(&quot;Cookie.CFID&quot;)&gt;
            &lt;cflock scope=&quot;session&quot; type=&quot;readonly&quot; timeout=&quot;5&quot;&gt;
                &lt;cfcookie name=&quot;CFID&quot; value=&quot;#session.CFID#&quot;&gt;
                &lt;cfcookie name=&quot;CFTOKEN&quot; value=&quot;#session.CFTOKEN#&quot;&gt;
                 &lt;cfset session.SessionStartTime = Now() /&gt;
            &lt;/cflock&gt;
        &lt;/cfif&gt;

        &lt;cfreturn /&gt;
    &lt;/cffunction&gt;

    &lt;cffunction
        name=&quot;OnRequestStart&quot;
        access=&quot;public&quot;
        returntype=&quot;boolean&quot;
        output=&quot;true&quot;
        hint=&quot;Fires at first part of page processing.&quot;&gt;

        &lt;!--- Define arguments. ---&gt;
        &lt;cfargument
            name=&quot;TargetPage&quot;
            type=&quot;string&quot;
            required=&quot;true&quot;
            /&gt;

        &lt;cfset session.RequestStartTime = Now() /&gt;

        &lt;cfreturn true /&gt;

    &lt;/cffunction&gt;    

&lt;/cfcomponent&gt;
</pre>
<p>The log in page checks for a query string variable called &#8216;expired&#8217; and, if present, deletes the session loggedin variable. This is there because the code is going to control the expiration of the session eliminating the need to compensate for browser latency. The actual session start time the time the page loads can differ by several seconds. To avoid having to add time to the session or any other fancy guesswork, when the allotted session time has expired according to the javascript timer on the page, they are done &#8211; session over.</p>
<p>If they are logged in, they get bumped to the index page. The rest is the logic that handles the log in form.</p>
<p>Note: I would not recommend handling a log in form this way. This is for demonstration only.</p>
<pre class="brush: coldfusion;">
&lt;cfif isDefined(&quot;url.expired&quot;) AND url.expired&gt;
    &lt;cfset StructDelete(session,&quot;loggedin&quot;) /&gt;
&lt;/cfif&gt;

&lt;cfif isDefined(&quot;form.username&quot;) AND isDefined(&quot;form.pw&quot;) AND form.username EQ &quot;session&quot; AND form.pw EQ &quot;test&quot;&gt;
    &lt;cfset session.loggedin = true /&gt;
&lt;/cfif&gt;

&lt;cfif StructKeyExists(session, &quot;loggedin&quot;) AND session.loggedin&gt;
    &lt;cflocation url=&quot;index.cfm&quot; addToken=&quot;no&quot; /&gt;
&lt;/cfif&gt;
</pre>
<p>Other than the log in form and a message for the user, that&#8217;s all there is to the log in page.</p>
<h3>Handling Session Timeout</h3>
<p>The index page handles the session timeout code. This could be a separate javascript included in every page. The first block simply determines if they are logged in. If they are not, send them to the login page. If they are, load the index page.</p>
<pre class="brush: coldfusion;">
&lt;!---if not logged in, send them to login page, else load the index page---&gt;
&lt;cfif NOT StructKeyExists(session, &quot;loggedin&quot;) OR NOT session.loggedin&gt;
    &lt;cflocation url=&quot;login.cfm&quot; addToken=&quot;no&quot; /&gt;
&lt;cfelse&gt;
 &lt;!---Load the page ---&gt;
&lt;/cfif&gt;
</pre>
<p>Now the time variables are set and the a javascript timer is set to check the session every 10 seconds.<br />
Javascript uses milliseconds so for clarity the time intervals multiply the number of seconds by 1,000. You could put 10000 in for 10 seconds but I think 10*1000 helps me determine that it is 10 seconds quite a bit faster. Do what is comfortable for you.</p>
<p>Also, a flag is set to determine if the warning dialog box has been opened and the countdown has begun.</p>
<pre class="brush: jscript;">
//Your timing variables in number of seconds
//total length of session in seconds
var sessionLength = 30;
//time warning shown (10 = warning box shown 10 seconds before session starts)
var warning = 10;
//time redirect forced (10 = redirect forced 10 seconds after session ends)
var forceRedirect = 10; 

$(document).ready(function() {
	//event to check session time left (times 1000 to convert seconds to milliseconds)
    checkSessionTimeEvent = setInterval(&quot;checkSessionTime(requestTime)&quot;,10*1000);
});

//event to check session time variable declaration
var checkSessionTimeEvent = &quot;&quot;;

//time session started
var requestTime = new Date();

//initial set of number of seconds to count down from for countdown ticker (10,9,8,7...you get the idea)
var countdownTime = warning;
//create event to start/stop countdownTicker
var countdownTickerEvent = &quot;&quot;; 

//initially set to false. if true - warning dialog open; countdown underway
var warningStarted = false;

function checkSessionTime(reqTime)
{
	//get time now
	var timeNow = new Date(); 

	//clear any countdownTickerEvents that may be running
	clearInterval(countdownTickerEvent);

	//difference between time now and time session started variable declartion
	var timeDifference = 0;

	//session timeout length
	var timeoutLength = sessionLength*1000;

	//set time for first warning, ten seconds before session expires
	var warningTime = timeoutLength - (warning*1000);

	//force redirect to log in page length (session timeout plus 10 seconds)
	var forceRedirectLength = timeoutLength + (forceRedirect*1000);

	timeDifference = timeNow - reqTime;

     if (timeDifference &gt; warningTime &amp;&amp; warningStarted === false)
        {
            //reset number of seconds to count down from for countdown ticker
			countdownTime = warning;

			//call now for initial dialog box text (time left until session timeout)
            countdownTicker(); 

            //set as interval event to countdown seconds to session timeout
            countdownTickerEvent = setInterval(&quot;countdownTicker()&quot;, 1000);

            $('#dialogWarning').dialog('open');
			warningStarted = true;
        }
    else if (timeDifference &gt; timeoutLength)
    	{
    		//close warning dialog box if open
            if ($('#dialogWarning').dialog('isOpen')) $('#dialogWarning').dialog('close');

            $('#dialogExpired').dialog('open');

        }

     if (timeDifference &gt; forceRedirectLength)
     	{
        	//clear (stop) checksession event
            clearInterval(checkSessionTimeEvent);

            //force relocation
            window.location=&quot;login.cfm?expired=true&quot;;
        }
}
</pre>
<p>The countdownTicker function provides a countdown inside the warning dialog box to prompt the user to act now. It uses a timer that fires every second for a 5,4,3,2,1 effect inside the dialog box.</p>
<pre class="brush: jscript;">
function countdownTicker()
{
	//put countdown time left in dialog box
	$(&quot;span#dialogText-warning&quot;).html(countdownTime);

	//decrement countdownTime
	countdownTime--;
}
</pre>
<p>And, the dialog boxes either allow the user to restart the session or, if they did nothing when the warning popped up, it logs them out by redirecting to the log in page with the expired variable in the query string. Also, it redirects to the log in if they hit the close button on the dialog box rather than the Login button on the dialogExpired dialog box.</p>
<pre class="brush: jscript;">
$(function(){
        // jQuery UI Dialog
        $('#dialogWarning').dialog({
            autoOpen: false,
            width: 400,
            modal: true,
            resizable: false,
            buttons: {
                &quot;Restart Session&quot;: function() {
		   //reset session on server
                  $.post(&quot;restart_session.cfm&quot;);

		   //reset the variables
		   requestTime = new Date();
		   warningStarted = false;
		   countdownTime = warning;

		   //clear current checkSessionTimeEvent and start a new one
		   clearInterval(checkSessionTimeEvent);
		   checkSessionTimeEvent = &quot;&quot;;
		   checkSessionTimeEvent = setInterval(&quot;checkSessionTime(requestTime)&quot;,10*1000);

		    $('#dialogWarning').dialog('close');
                }
            }
        });

        $('#dialogExpired').dialog({
            autoOpen: false,
            width: 400,
            modal: true,
            resizable: false,
            close: function() {
                   window.location=&quot;login.cfm?expired=true&quot;;
            },
            buttons: {
                &quot;Login&quot;: function() {
                    window.location=&quot;login.cfm?expired=true&quot;;
                }
            }
        });
});
</pre>
<p>The &#8220;Restart Session&#8221; button sends a post request to a ColdFusion page that sets a session variable. That act alone refreshes the session.</p>
<pre class="brush: coldfusion;">
&lt;!---Setting the give_me_more_time session variable refreshes the session.---&gt;
&lt;cfset session.give_me_more_time = true /&gt;
&lt;!--- Below is optional. There just so you can see a response from the server in firebug. ---&gt;
&lt;cfoutput&gt;session.RequestStartTime: #session.RequestStartTime# session.loggedin: #session.loggedin#&lt;/cfoutput&gt;
</pre>
<p>The dialog box contents are at the bottom of the page but they could be just about anywhere in the body.</p>
<pre class="brush: xml;">
&lt;!--Dialog box contents--&gt;
&lt;div id=&quot;dialogExpired&quot; title=&quot;Session (Page) Expired!&quot;&gt;&lt;p&gt;&lt;span class=&quot;ui-icon ui-icon-alert&quot; style=&quot;float:left; margin:0 7px 0 0;&quot;&gt;&lt;/span&gt; Your session has expired!&lt;p id=&quot;dialogText-expired&quot;&gt;&lt;/p&gt;&lt;/div&gt;

&lt;div id=&quot;dialogWarning&quot; title=&quot;Session (Page) Expiring!&quot;&gt;&lt;p&gt;&lt;span class=&quot;ui-icon ui-icon-alert&quot; style=&quot;float:left; margin:0 7px 0 0;&quot;&gt;&lt;/span&gt; Your session will expire in &lt;span id=&quot;dialogText-warning&quot;&gt;&lt;/span&gt; seconds!&lt;/div&gt;
</pre>
<h3>Just for Fun</h3>
<p>You can view the response from the restrart_session.cfm in Firebug and compare it to the time on the page from the dumped session vars.<br />
<img src="/images/CFsessionFirebug.gif" alt="session time compare" /></p>
<p>Usual recommended jQuery and CF reading:</p>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0596159773" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0321647491" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847195121" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=032151548X" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="http://cf-jensbits.com/demos/sessionrefresh/login.cfm" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/sessionrefresh/login.cfm']); return false;"><span>Demo</span></a></p>
<p id="download"><a href="/media/code/sessionrefresh.zip"><span>Download zip of all files</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>Related posts:<ol><li><a href='http://www.jensbits.com/2009/09/12/session-timeout-warning-with-coldfusion-and-jqueryjs/' rel='bookmark' title='Permanent Link: ColdFusion Example: Session Timeout Warning with jQuery/JS'>ColdFusion Example: Session Timeout Warning with jQuery/JS</a></li>
<li><a href='http://www.jensbits.com/2009/07/29/coldfusion-dropping-losing-or-resetting-session-variables-and-cfidcftoken/' rel='bookmark' title='Permanent Link: ColdFusion Dropping, Losing, or Resetting Session Variables and CFID/CFTOKEN'>ColdFusion Dropping, Losing, or Resetting Session Variables and CFID/CFTOKEN</a></li>
<li><a href='http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion'>jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/04/18/coldfusion-session-timeout-with-warning-and-session-refresh/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jQuery UI Autocomplete Widget with ColdFusion</title>
		<link>http://www.jensbits.com/2010/03/18/jquery-ui-autocomplete-with-coldfusion/</link>
		<comments>http://www.jensbits.com/2010/03/18/jquery-ui-autocomplete-with-coldfusion/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 19:58:35 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=649</guid>
		<description><![CDATA[You may also be interested in the jQuery UI Autocomplete Widget with PHP and MySQL or the jQuery UI Autocomplete Widget with ASP.NET VB post. Also, check out the Using jQuery Autocomplete to Populate Another Autocomplete post. The jQuery UI folks have released an autocomplete widget that is pretty slick. Using it with ColdFusion is [...]


Related posts:<ol><li><a href='http://www.jensbits.com/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/' rel='bookmark' title='Permanent Link: Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples'>Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples</a></li>
<li><a href='http://www.jensbits.com/2010/04/14/jquery-ui-autocomplete-widget-with-asp-net/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with ASP.NET VB'>jQuery UI Autocomplete Widget with ASP.NET VB</a></li>
<li><a href='http://www.jensbits.com/2010/03/29/jquery-ui-autocomplete-widget-with-php-and-mysql/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with PHP and MySQL'>jQuery UI Autocomplete Widget with PHP and MySQL</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<blockquote><p>You may also be interested in the <a href="/2010/03/29/jquery-ui-autocomplete-widget-with-php-and-mysql/"> jQuery UI Autocomplete Widget with PHP and MySQL</a> or the <a href="/2010/04/14/jquery-ui-autocomplete-widget-with-asp-net/">jQuery UI Autocomplete Widget with ASP.NET VB</a> post. Also, check out the <a href="/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/">Using jQuery Autocomplete to Populate Another Autocomplete post</a>.</p></blockquote>
<p>The jQuery UI folks have released an <a href=" http://jqueryui.com/demos/autocomplete/">autocomplete widget</a> that is pretty slick. Using it with ColdFusion is a snap. This example uses the serializeJSON function in ColdFusion 8. If you have an earlier version of CF, you will have to find a <a href="http://www.epiphantastic.com/cfjson/">cfc that can build a JSON string</a> for you. There are several freely available cfc&#8217;s that do it for you.<br />
<img src="/images/autocomplete.gif" alt="autocomplete" /><br />
This example will use US states and territories to populate the autocomplete. It will also demostrate how to fill other fields with data returned from the database. This data can be used to fill a visible text box or a hidden form field. It also demonstrates the basic autocomplete functionality which may be fine for some applications.</p>
<p>Of course, you will need the jQuery core file, the jQuery UI core file, and the jQuery UI style sheet of choice. The style sheet comes from the themes available in the jQuery UI website and can be <a href="http://jqueryui.com/download">downloaded with the core file</a>:</p>
<pre class="brush: xml;">
&lt;link type=&quot;text/css&quot; href=&quot;jquery-ui-1.8rc3.custom.css&quot; rel=&quot;stylesheet&quot; /&gt; 

&lt;script type=&quot;text/javascript&quot; src=&quot;jquery-1.4.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;jquery-ui-1.8rc3.custom.min.js&quot;&gt;&lt;/script&gt;
</pre>
<p>The HTML is straight forward and stripped down for the example:</p>
<pre class="brush: xml;">
&lt;form action=&quot;index.cfm&quot;  method=&quot;post&quot;&gt;
&lt;fieldset&gt;
&lt;legend&gt;jQuery UI Autocomplete Example - ColdFusion Backend&lt;/legend&gt;
&lt;p&gt;Start typing the name of a state or territory of the United States&lt;/p&gt;
&lt;p class=&quot;ui-widget&quot;&gt;&lt;label for=&quot;state&quot;&gt;State (abbreviation in separate field): &lt;/label&gt;
	&lt;input type=&quot;text&quot; id=&quot;state&quot;  name=&quot;state&quot; /&gt; &lt;input readonly=&quot;readonly&quot; type=&quot;text&quot; id=&quot;abbrev&quot; name=&quot;abbrev&quot; maxlength=&quot;2&quot; size=&quot;2&quot;/&gt;&lt;/p&gt;
    &lt;input type=&quot;hidden&quot; id=&quot;state_id&quot; name=&quot;state_id&quot; /&gt;
&lt;p class=&quot;ui-widget&quot;&gt;&lt;label for=&quot;state_abbrev&quot;&gt;State (replaced with abbreviation): &lt;/label&gt;
&lt;input type=&quot;text&quot; id=&quot;state_abbrev&quot; name=&quot;state_abbrev&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot; /&gt;&lt;/p&gt;
&lt;/fieldset&gt;
&lt;/form&gt;
</pre>
<p>As a bonus, we dump out the form values to see what we have right underneath the form itself:</p>
<pre class="brush: coldfusion;">
&lt;cfdump var=&quot;#form#&quot; label=&quot;Form Fields&quot; /&gt;
</pre>
<p>And the jQuery on the page is equally brief:</p>
<pre class="brush: jscript;">
$(function() {

            $('#abbrev').val(&quot;&quot;);

            $(&quot;#state&quot;).autocomplete({
                source: &quot;states.cfm&quot;,
                minLength: 2,
                select: function(event, ui) {
                    $('#state_id').val(ui.item.id);
                    $('#abbrev').val(ui.item.abbrev);
                }
            });

            $(&quot;#state_abbrev&quot;).autocomplete({
                source: &quot;states_abbrev.cfm&quot;,
                minLength: 2
            });
        });
</pre>
<p>Notice that there are two autocomplete functions on the page, one for each example in the demo. Each function calls a different ColdFusion file which return slightly different result sets.</p>
<p>Also, the minLength for autocomplete to return results is set to 2 to prevent too many rows from being returned.</p>
<p>Both ColdFusion pages return the data after a few steps:</p>
<ol>
<li>It queries the database</li>
<li>Loops the query, adding each row to a structure that is appended to an array</li>
<li>Outputs the array as JSON data</li>
</ol>
<p>The states.cfm file returns the id field, the state field as &#8216;label&#8217;, and the abbrev field. These values are placed in the appropriate text boxes by the autocomplete jQuery function. </p>
<pre class="brush: coldfusion;">
&lt;cfset returnArray = ArrayNew(1) /&gt;

&lt;cfquery name=&quot;qryStates&quot; dataSource=&quot;autocomplete&quot;&gt;
    Select * from states where state like '%#URL.term#%'
&lt;/cfquery&gt;

&lt;cfloop query=&quot;qryStates&quot;&gt;
    &lt;cfset statesStruct = StructNew() /&gt;
    &lt;cfset statesStruct[&quot;id&quot;] = id /&gt;
    &lt;cfset statesStruct[&quot;label&quot;] = state /&gt;
    &lt;cfset statesStruct[&quot;abbrev&quot;] = abbrev /&gt;

    &lt;cfset ArrayAppend(returnArray,statesStruct) /&gt;
&lt;/cfloop&gt;

&lt;cfoutput&gt;
#serializeJSON(returnArray)#
&lt;/cfoutput&gt;
</pre>
<p>Unfortunately, the ColdFusion function serializeJSON does not put query results in the format that javascript likes. That&#8217;s why we have to do the hokey-pokey with the structure and array.</p>
<p>The states_abbrev.cfm shows the basic functionality of the autocomplete function by just assigning results of the query to the &#8216;label&#8217; and &#8216;value&#8217; fields. Explanation on the &#8216;label&#8217; and &#8216;value&#8217; fields from the jQuery UI site:</p>
<p><em>&#8220;The local data can be a simple Array of Strings, or it contains Objects for each item in the array, with either a label or value property or both. The label property is displayed in the suggestion menu. The value will be inserted into the input element after the user selected something from the menu. If just one property is specified, it will be used for both, eg. if you provide only value-properties, the value will also be used as the label.&#8221;</em></p>
<pre class="brush: coldfusion;">
&lt;cfset returnArray = ArrayNew(1) /&gt;

&lt;cfquery name=&quot;qryStates&quot; dataSource=&quot;autocomplete&quot;&gt;
    Select * from state where state like '%#URL.term#%'
&lt;/cfquery&gt;

&lt;cfloop query=&quot;qryStates&quot;&gt;
    &lt;cfset statesStruct = StructNew() /&gt;
    &lt;cfset statesStruct[&quot;label&quot;] = state /&gt;
    &lt;cfset statesStruct[&quot;value&quot;] = abbrev /&gt;

    &lt;cfset ArrayAppend(returnArray,statesStruct) /&gt;
&lt;/cfloop&gt;

&lt;cfoutput&gt;
#serializeJSON(returnArray)#
&lt;/cfoutput&gt;
</pre>
<p>Usual recommended jQuery and CF reading:</p>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0596159773" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0321647491" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847195121" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=032151548X" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="http://cf-jensbits.com/demos/autocomplete/" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/autocomplete/']); return false;"><span>Demo</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>Related posts:<ol><li><a href='http://www.jensbits.com/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/' rel='bookmark' title='Permanent Link: Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples'>Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples</a></li>
<li><a href='http://www.jensbits.com/2010/04/14/jquery-ui-autocomplete-widget-with-asp-net/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with ASP.NET VB'>jQuery UI Autocomplete Widget with ASP.NET VB</a></li>
<li><a href='http://www.jensbits.com/2010/03/29/jquery-ui-autocomplete-widget-with-php-and-mysql/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with PHP and MySQL'>jQuery UI Autocomplete Widget with PHP and MySQL</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/03/18/jquery-ui-autocomplete-with-coldfusion/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Passed the ColdFusion 8 Certification Exam</title>
		<link>http://www.jensbits.com/2010/01/05/passed-the-coldfusion-8-certification-exam/</link>
		<comments>http://www.jensbits.com/2010/01/05/passed-the-coldfusion-8-certification-exam/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 19:10:40 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=529</guid>
		<description><![CDATA[Passed the ColdFusion 8 Certification Exam today. Scored a 95 and could not have done it without CF8 Exam Buster. I have heard all the debate on whether or not to take the CF exam and I think most arguments against taking it are rubbish. The real benefit of taking any exam is the fact [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>Passed the ColdFusion 8 Certification Exam today. Scored a 95 and could not have done it without <a href="http://www.centrasoft.com/products.cfm">CF8 Exam Buster</a>. </p>
<p><img   title="ColdFusion 8 Adobe Certified Expert - Advanced" alt="ColdFusion 8 Adobe Certified Expert - Advanced" src="/images/cfcert.gif" /></p>
<p>I have heard all the debate on whether or not to take the CF exam and I think most arguments against taking it are rubbish.</p>
<p>The real benefit of taking any exam is the fact that you get exposed to parts of the language that you never knew existed. Just studying for the exam helped me find tags, attributes, and functions I wouldn&#8217;t even have thought to look for. And, if you are a freelancer, it can only help to have this credential.</p>
<p>So, if you can pony up the $150 for the test and the $40 for Exam Buster, there is no reason why you shouldn&#8217;t take the exam. Just go through the Exam Buster tests until you consistently score in the 90&#8242;s and you are a lock to pass.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/01/05/passed-the-coldfusion-8-certification-exam/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>ColdFusion and Google Analytics: Getting Out What You Put In</title>
		<link>http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/</link>
		<comments>http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 03:43:27 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Google Analytics]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=510</guid>
		<description><![CDATA[The Hooking into Google Analytics post details how to connect to the Data Export API of Google Analytics (GA) and get a simple visitors count in return. Here we will expand greatly on that and create a cfc that will process just about any result from the API. This code requires at least ColdFusion 8.0.1. [...]


Related posts:<ol><li><a href='http://www.jensbits.com/2009/05/02/hooking-into-google-analytics-with-coldfusion/' rel='bookmark' title='Permanent Link: Hooking into Google Analytics with ColdFusion'>Hooking into Google Analytics with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2009/05/10/google-analytics-api-login-authentication-with-coldfusion/' rel='bookmark' title='Permanent Link: Google Analytics API Login Authentication with ColdFusion'>Google Analytics API Login Authentication with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2010/05/16/generating-signatures-in-coldfusion-with-rsa-sha1-for-secure-authsub-in-google-analytics/' rel='bookmark' title='Permanent Link: Generating Signatures in ColdFusion with RSA-SHA1 for Secure AuthSub in Google Analytics'>Generating Signatures in ColdFusion with RSA-SHA1 for Secure AuthSub in Google Analytics</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The <a href="/2009/05/02/hooking-into-google-analytics-with-coldfusion/">Hooking into Google Analytics</a> post details how to connect to the Data Export API of Google Analytics (GA) and get a simple visitors count in return. Here we will expand greatly on that and create a cfc that will process just about any result from the API. </p>
<blockquote><p>This code requires at least ColdFusion 8.0.1. Check your version before installing.</p></blockquote>
<p>An auth token is needed for requests to the API and two ways to do that are the <a href="http://code.google.com/intl/en/apis/analytics/docs/gdata/gdataAuthentication.html">AuthSub and ClentLogin methods</a>. The method used is up to the developer as once the auth token is retrieved and set into session, data calls to the API can be repeatedly made.</p>
<pre class="brush: coldfusion;">
&lt;cffunction name=&quot;googleLogin&quot; access=&quot;public&quot; hint=&quot;GA account authorization&quot;&gt;
        &lt;cfargument name=&quot;email&quot; type=&quot;string&quot; required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;password&quot; type=&quot;string&quot;required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;gaLoginUrl&quot; type=&quot;string&quot; required=&quot;no&quot; default=&quot;https://www.google.com/accounts/ClientLogin&quot;&gt;

        &lt;cfset var loginAuth = &quot;&quot; /&gt;

        &lt;cfhttp url=&quot;#arguments.gaLoginUrl#&quot; method=&quot;post&quot;&gt;
            &lt;cfhttpparam name=&quot;accountType&quot; type=&quot;url&quot; value=&quot;GOOGLE&quot;&gt;
            &lt;cfhttpparam name=&quot;Email&quot; type=&quot;url&quot; value=&quot;#arguments.email#&quot;&gt;
            &lt;cfhttpparam name=&quot;Passwd&quot; type=&quot;url&quot; value=&quot;#arguments.password#&quot;&gt;
            &lt;cfhttpparam name=&quot;service&quot; type=&quot;url&quot; value=&quot;analytics&quot;&gt;
            &lt;cfhttpparam name=&quot;source&quot; type=&quot;url&quot; value=&quot;my-analytics&quot;&gt;
        &lt;/cfhttp&gt;

        &lt;cfif NOT FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent)&gt;
            &lt;cfset loginAuth = &quot;Authorization Failed&quot; /&gt;
        &lt;cfelse&gt;
            &lt;cfset loginAuth = Mid(cfhttp.filecontent, FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent) + (Len(&quot;Auth=&quot;)), Len(cfhttp.filecontent)) /&gt;
        &lt;/cfif&gt;

         &lt;cflock scope=&quot;session&quot; type=&quot;exclusive&quot; timeout=&quot;5&quot;&gt;
                &lt;cfset session.ga_loginAuth = loginAuth /&gt;
         &lt;/cflock&gt;

    &lt;/cffunction&gt;
</pre>
<p>To retrieve the profile or data feed, a call is made to the API via a function.</p>
<pre class="brush: coldfusion;">
   &lt;cffunction name=&quot;callApi&quot; access=&quot;public&quot; returntype=&quot;array&quot; hint=&quot;GA data as array of structures&quot;&gt;
        &lt;cfargument name=&quot;gaUrl&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;
        &lt;cfargument name=&quot;authToken&quot; type=&quot;string&quot; required=&quot;no&quot; default=&quot;#session.ga_loginAuth#&quot; /&gt;

        &lt;cfset var authTokenHeader = 'GoogleLogin auth=' &amp; arguments.authToken /&gt;

        &lt;cfset var responseOutput = &quot;&quot; /&gt;

        &lt;cfhttp url=&quot;#arguments.gaUrl#&quot; method=&quot;get&quot;&gt;
            &lt;cfhttpparam name=&quot;Authorization&quot; type=&quot;header&quot; value=&quot;#authTokenHeader#&quot;&gt;
        &lt;/cfhttp&gt;

        &lt;cfset responseOutput = cfhttp.filecontent /&gt;
        &lt;!---remove dxp: prefix from nodes that have it and strip xmlns from feed element---&gt;
         &lt;cfset responseOutput = responseOutput.ReplaceAll(&quot;(&lt;/?)(\w+:)&quot;,&quot;$1&quot;) /&gt;
         &lt;cfset responseOutput = REReplaceNoCase(responseOutput,&quot;&lt;feed[^&gt;]*&gt;&quot;,&quot;&lt;feed&gt;&quot;) /&gt;
         &lt;!---entry nodes hold the data---&gt;
         &lt;cfset entryNodes = XmlSearch(responseOutput, '//entry/') /&gt;

         &lt;cfreturn entryNodes /&gt;
    &lt;/cffunction&gt;
</pre>
<p>Next, a list of the profiles (websites) that the user has access to are retrieved by requesting an account feed. If the user has only one profile associated with their credentials, the data is displayed immediately. If they have more than one, they are presented with a select box to select the profile they want data from.</p>
<pre class="brush: coldfusion;">
&lt;cfinvoke component=&quot;ga&quot; method=&quot;parseProfiles&quot; returnvariable=&quot;profilesArray&quot;&gt;&lt;/cfinvoke&gt;
</pre>
<pre class="brush: coldfusion;">
 &lt;cffunction name=&quot;parseProfiles&quot; access=&quot;public&quot; returntype=&quot;array&quot; hint=&quot;GA profiles as array of structures&quot;&gt;

	&lt;cfset var profileArray = ArrayNew(1) /&gt;
        &lt;cfset var entryStruct = StructNew() /&gt;

        &lt;cfset entryNodes = callApi(&quot;https://www.google.com/analytics/feeds/accounts/default&quot;) /&gt;

        &lt;cfloop array=&quot;#entryNodes#&quot; index=&quot;entry&quot;&gt;
            &lt;cfset entryStruct = StructNew() /&gt;

            &lt;cfset entryStruct.title = entry.title.XmlText /&gt;
            &lt;cfset entryStruct.tableId = entry.tableId.XmlText /&gt;

            &lt;cfset arrayAppend(profileArray,duplicate(entryStruct)) /&gt;
        &lt;/cfloop&gt;

        &lt;cfreturn profileArray /&gt;
    &lt;/cffunction&gt;
</pre>
<p>A default date range of one year is set initially. A dialog box that allows the user to change the date range is presented as an option. The date range is limited to a max date of yesterday because GA does not have full data for the current day. This causes the averages that are calculated on the return data to be skewed.</p>
<p>A data feed request url is sent to GA along with the auth token  a via cfhttp tag.</p>
<pre class="brush: coldfusion;">
&lt;cfset reqUrl = &quot;https://www.google.com/analytics/feeds/data?ids=&quot; &amp; session.tableId &amp; &quot;&amp;metrics=ga:newVisits,ga:pageviews,ga:visits,ga:visitors,ga:timeOnSite&amp;start-date=&quot; &amp; session.startdate &amp; &quot;&amp;end-date=&quot; &amp; session.enddate /&gt;
</pre>
<p>The XML response is then parsed out and returned as an array of structures.</p>
<pre class="brush: coldfusion;">
&lt;cffunction name=&quot;parseData&quot; access=&quot;public&quot; hint=&quot;GA data as array of structures set in session&quot;&gt;
        &lt;cfargument name=&quot;gaUrl&quot; type=&quot;string&quot; required=&quot;yes&quot; /&gt;
        &lt;cfargument name=&quot;arrayName&quot; type=&quot;string&quot;required=&quot;yes&quot; /&gt;

        &lt;cfset var dataArray = ArrayNew(1) /&gt;
        &lt;cfset var entryStruct = StructNew() /&gt;

         &lt;cfset entryNodes = callApi(arguments.gaUrl) /&gt;

        &lt;!---CF8 loop through the entries and put each data point in structure---&gt;
        &lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes)#&quot; index=&quot;num&quot;&gt;
		&lt;!---rest of the stats data from GA, first check if dimension exists---&gt;
		&lt;cfif StructKeyExists(entryNodes[num],&quot;dimension&quot;)&gt;
		&lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes[num].dimension)#&quot; index=&quot;i&quot;&gt;
		&lt;!---start after ga: to remove it---&gt;
		&lt;cfset &quot;entryStruct.#Mid(entryNodes[num].dimension[i].XmlAttributes[&quot;name&quot;],4,
Len(entryNodes[num].dimension[i].XmlAttributes[&quot;name&quot;]))#&quot; = entryNodes[num].dimension[i].XmlAttributes[&quot;value&quot;] /&gt;
		&lt;/cfloop&gt;
		&lt;/cfif&gt;

		&lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes[num].metric)#&quot; index=&quot;i&quot;&gt;
			&lt;cfset &quot;entryStruct.#Mid(entryNodes[num].metric[i].XmlAttributes[&quot;name&quot;],4,
Len(entryNodes[num].metric[i].XmlAttributes[&quot;name&quot;]))#&quot; = entryNodes[num].metric[i].XmlAttributes[&quot;value&quot;] /&gt;
		&lt;/cfloop&gt;

		&lt;cfset arrayAppend(dataArray,duplicate(entryStruct)) /&gt;

	&lt;/cfloop&gt;

         &lt;!---CF9 can use this simplier loop. If you have CF9, uncomment and delete loop above
            &lt;cfloop array=&quot;#entryNodes#&quot; index=&quot;entry&quot;&gt;
		&lt;cfif StructKeyExists(entry,&quot;dimension&quot;)&gt;
                	&lt;cfloop array=&quot;#entry.dimension#&quot; index=&quot;dimension&quot;&gt;
                 	&lt;cfset &quot;entryStruct.#Mid(dimension.XmlAttributes[&quot;name&quot;],4,
Len(dimension.XmlAttributes[&quot;name&quot;]))#&quot; = dimension.XmlAttributes[&quot;value&quot;] /&gt;
                 	&lt;/cfloop&gt;
                 &lt;/cfif&gt;

                 &lt;cfloop array=&quot;#entry.metric#&quot; index=&quot;metric&quot;&gt;
                 	&lt;cfset &quot;entryStruct.#Mid(metric.XmlAttributes[&quot;name&quot;],4,
Len(metric.XmlAttributes[&quot;name&quot;]))#&quot; = metric.XmlAttributes[&quot;value&quot;] /&gt;
                  &lt;/cfloop&gt;

                &lt;cfset arrayAppend(dataArray,duplicate(entryStruct)) /&gt;
           &lt;/cfloop&gt;---&gt;

        	&lt;cflock scope=&quot;session&quot; type=&quot;exclusive&quot; timeout=&quot;5&quot;&gt;
        		&lt;cfset &quot;session.#arrayName#&quot; = dataArray /&gt;
        	&lt;/cflock&gt;

    &lt;/cffunction&gt;
</pre>
<p>Once the data is in a form you can manipulate, graphs, tables, and charts of all kinds can be made.</p>
<p>ClientLogin, AuthSub, and Secure AuthSub authentication examples are included in the demo. <strong>ClientLogin recommended only for client apps.</strong> Google notice on using ClientLogin:</p>
<blockquote><p>
&#8220;Important: Do not use ClientLogin if you are writing an application that runs on<br />
your computer to make requests on behalf of 3rd party end users. Instead, use either<br />
AuthSub or OAuth, which protects end users&#8217; private data. Because ClientLogin stores<br />
the user login data, it should only be used in cases where that data is under the<br />
direct control of the user (e.g. their personal computer).&#8221;</p></blockquote>
<h2>Recommended Reading</h2>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470529393" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470130652" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470562315" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470531282" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="http://cf-jensbits.com/demos/ga/login.cfm" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/ga/login.cfm']); return false;"><span>Demo</span></a></p>
<p id="download"><a href="http://github.com/jensbits/Google-Analytics-Data-Export-API-with-ColdFusion"><span>Download files from github</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>Related posts:<ol><li><a href='http://www.jensbits.com/2009/05/02/hooking-into-google-analytics-with-coldfusion/' rel='bookmark' title='Permanent Link: Hooking into Google Analytics with ColdFusion'>Hooking into Google Analytics with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2009/05/10/google-analytics-api-login-authentication-with-coldfusion/' rel='bookmark' title='Permanent Link: Google Analytics API Login Authentication with ColdFusion'>Google Analytics API Login Authentication with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2010/05/16/generating-signatures-in-coldfusion-with-rsa-sha1-for-secure-authsub-in-google-analytics/' rel='bookmark' title='Permanent Link: Generating Signatures in ColdFusion with RSA-SHA1 for Secure AuthSub in Google Analytics'>Generating Signatures in ColdFusion with RSA-SHA1 for Secure AuthSub in Google Analytics</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>ColdFusion cfgrid Selected Row Disappearing / Blank in IE</title>
		<link>http://www.jensbits.com/2009/10/28/coldfusion-cfgrid-selected-row-disappearing-blank-in-ie/</link>
		<comments>http://www.jensbits.com/2009/10/28/coldfusion-cfgrid-selected-row-disappearing-blank-in-ie/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 13:45:06 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[IE]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=449</guid>
		<description><![CDATA[After selecting a row in cfgrid in Internet Explorer, the selected row goes blank or all white. The data is still there and the row is selected, you just can&#8217;t tell. The problem lies in a css file that ColdFusion uses for the cfgrid. According to some other posts on the web, there is some [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>After selecting a row in cfgrid in Internet Explorer, the selected row goes blank or all white. The data is still there and the row is selected, you just can&#8217;t tell.</p>
<p>The problem lies in a css file that ColdFusion uses for the cfgrid. According to <a href="http://blog.seguetech.com/?p=149">some other posts on the web</a>, there is some incorrectly commented out css rules. They are commented out with &#8216;//&#8217; rather than &#8216;/*&#8230;*/&#8217;. The file is ext-all.css and on my set up with IIS, I found it at C:\Inetpub\wwwroot\CFIDE\scripts\ajax\resources\ext\css\ext-all.css.</p>
<p>When the comments are correctly marked up, it got better (the text showed up) but the background color did not behave even though I specified the select background color in the cfgrid attributes with selectColor=&#8221;#FF3300&#8243;. BTW, the selectColor worked for FireFox, IE didn&#8217;t seem to care.</p>
<p>My solution (although imperfect) was to edit the ext-all.css by properly commenting out the bad comments and adding my own background color for the selected td. It&#8217;s imperfect because it overrides the selectColor in FireFox.</p>
<pre class="brush: css;">
.x-grid-row-selected td, .x-grid-locked .x-grid-row-selected td{
	background-color: #316ac5; /* added */
	/*color: white;*/
}

.x-grid-row-selected span, .x-grid-row-selected b, .x-grid-row-selected div, .x-grid-row-selected strong, .x-grid-row-selected i{
	color:white !important;
}

.x-grid-row-selected .x-grid-cell-text{
	/*color: white;*/
}

.x-grid-cell-selected{
	/*color: white;*/
}

.x-grid-cell-selected span{
	/*color: white !important;*/
}

.x-grid-cell-selected .x-grid-cell-text{
	/*color: white;*/
}
</pre>
<p>Hope this helps someone else and I hope Adobe fixes it.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/10/28/coldfusion-cfgrid-selected-row-disappearing-blank-in-ie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion</title>
		<link>http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/</link>
		<comments>http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 13:17:30 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[forms]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=441</guid>
		<description><![CDATA[This is the same as the previous jquery form submit post that used PHP just flavored with CF this time. Two jQuery functions that allow for the submission of form are the jQuery.ajax function and the jQuery.post function (there is also jQuery.get but that is not addressed here). More functionality, along with more complexity, is [...]


Related posts:<ol><li><a href='http://www.jensbits.com/2009/10/04/jquery-ajax-and-jquery-post-form-submit-examples-with-php/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with PHP'>jQuery.ajax and jQuery.post Form Submit Examples with PHP</a></li>
<li><a href='http://www.jensbits.com/2009/08/10/modal-confirmation-dialog-on-form-submit-javascript-jquery-ui-and-thickbox-varieties/' rel='bookmark' title='Permanent Link: Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties'>Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties</a></li>
<li><a href='http://www.jensbits.com/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/' rel='bookmark' title='Permanent Link: Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples'>Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<blockquote><p>This is the same as the previous <a href="/2009/10/04/jquery-ajax-and-jquery-post-form-submit-examples-with-php/">jquery form submit post that used PHP</a> just flavored with CF this time.</p></blockquote>
<p>Two jQuery functions that allow for the submission of form are the jQuery.ajax function and the jQuery.post function (there is also jQuery.get but that is not addressed here). </p>
<p>More functionality, along with more complexity, is offered with the .ajax function while the .post function, with its more simple functionality and implementation, will be all that is needed for simple form posts.</p>
<blockquote><p>It is <strong>highly recommended</strong> that you get a tool like <a href="http://getfirebug.com/">Firebug</a> to see the post response coming back from the page. It helps immensely.</p></blockquote>
<p>Here is an example of both in action doing the same thing: form submit with email validation.</p>
<h2>jQuery.ajax</h2>
<p> The form:</p>
<pre class="brush: xml;">
&lt;form id=&quot;JqAjaxForm&quot;&gt;
&lt;fieldset&gt;
&lt;legend&gt;jQuery.ajax Form Submit&lt;/legend&gt;
&lt;p&gt;&lt;label for=&quot;name_ajax&quot;&gt;Name:&lt;/label&gt;&lt;br /&gt;
&lt;input id=&quot;name_ajax&quot; type=&quot;text&quot; name=&quot;name_ajax&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for=&quot;email_ajax&quot;&gt;E-mail:&lt;/label&gt;&lt;br /&gt;
&lt;input id=&quot;email_ajax&quot; type=&quot;text&quot; name=&quot;email_ajax&quot;  /&gt;&lt;/p&gt;
&lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;&lt;/p&gt;
&lt;/fieldset&gt;
&lt;/form&gt;
&lt;div id=&quot;message_ajax&quot;&gt;&lt;/div&gt;
</pre>
<p>Pretty simple, nothing fancy. There is a form for each jQuery function, .ajax and .post. The only difference in the forms are the element names.</p>
<p>jQuery controls the submit for the forms. For the .ajax submission the jQuery is this:</p>
<pre class="brush: jscript;">
$(function(){
    $(&quot;#JqAjaxForm&quot;).submit(function(){
        dataString = $(&quot;#JqAjaxForm&quot;).serialize();

        $.ajax({
        type: &quot;POST&quot;,
        url: &quot;process_form.cfm&quot;,
        data: dataString,
        dataType: &quot;json&quot;,
        success: function(data) {

            if(data.email_check == &quot;invalid&quot;){
                $(&quot;#message_ajax&quot;).html(&quot;&lt;div class='errorMessage'&gt;Sorry &quot; + data.name + &quot;, &quot; + data.email + &quot; is NOT a valid e-mail address. Try again.&lt;/div&gt;&quot;);
            } else {
                $(&quot;#message_ajax&quot;).html(&quot;&lt;div class='successMessage'&gt;&quot; + data.email + &quot; is a valid e-mail address. Thank you, &quot; + data.name + &quot;.&lt;/div&gt;&quot;);
            }

        }

        });

        return false;            

    });
});
</pre>
<p>The .serialize function is used to put the form data in a format that can be processed by a page on the server. The .ajax function options include:</p>
<ul>
<li>type: &#8220;get&#8221; or &#8220;post&#8221;</li>
<li>url: the page to receive the form data</li>
<li>data: the form data itself</li>
<li>dataType: the data type the function should expect back from the server</li>
<li>success function: runs on a succesful post to the page</li>
</ul>
<p>More information on the options and further explanations of the options used here can be found on the<a href="http://docs.jquery.com/Ajax/jQuery.ajax"> jQuery.ajax documentation page</a>.</p>
<h2>jQuery.post</h2>
<p>As in the .ajax example, the form is simple, only the names have been changed:</p>
<pre class="brush: xml;">
&lt;form id=&quot;JqPostForm&quot;&gt;
&lt;fieldset&gt;
&lt;legend&gt;jQuery.post Form Submit&lt;/legend&gt;
&lt;p&gt;&lt;label for=&quot;name_post&quot;&gt;Name:&lt;/label&gt;&lt;br /&gt;
&lt;input id=&quot;name_post&quot; type=&quot;text&quot; name=&quot;name_post&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for=&quot;email_post&quot;&gt;E-mail:&lt;/label&gt;&lt;br /&gt;
&lt;input id=&quot;email_post&quot; type=&quot;text&quot; name=&quot;email_post&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;&lt;/p&gt;
&lt;/fieldset&gt;
&lt;/form&gt;
&lt;div id=&quot;message_post&quot;&gt;&lt;/div&gt;
</pre>
<p>And again, jQuery controls the submit for the forms. For the .post submission the jQuery is this:</p>
<pre class="brush: jscript;">
$(function(){
    $(&quot;#JqPostForm&quot;).submit(function(){
        $.post(&quot;process_form.cfm&quot;, $(&quot;#JqPostForm&quot;).serialize(),
        function(data){
            if(data.email_check == 'invalid'){

                    $(&quot;#message_post&quot;).html(&quot;&lt;div class='errorMessage'&gt;Sorry &quot; + data.name + &quot;, &quot; + data.email + &quot; is NOT a valid e-mail address. Try again.&lt;/div&gt;&quot;);
            } else {
                $(&quot;#message_post&quot;).html(&quot;&lt;div class='successMessage'&gt;&quot; + data.email + &quot; is a valid e-mail address. Thank you, &quot; + data.name + &quot;.&lt;/div&gt;&quot;);
                }
        }, &quot;json&quot;);

        return false;

    });
});
</pre>
<p>jQuery.post is a shorter, easier way to post the form data. The function arguments are:</p>
<ul>
<li>url of the form processing page</li>
<li>the form data</li>
<li>the callback function
<li>
<li>the data type of the return data</li>
</ul>
<p>More information can be found on the<a href="http://docs.jquery.com/Ajax/jQuery.post"> jQuery.post documentation page</a>.</p>
<h2>Processing the Form</h2>
<p>Both methods are processed by the same page. It processes the form data, process_form.cfm in this example, by checking to see if the e-mail submitted is valid. Much more than that could be done on the page if needed.</p>
<pre class="brush: coldfusion;">
&lt;cfset email_check = &quot;&quot; /&gt;
&lt;cfset return_json_string = &quot;&quot; /&gt;
&lt;cfset return_struct = StructNew() /&gt;

&lt;cfif (isDefined(&quot;form.email_ajax&quot;) AND isValid(&quot;email&quot;,form.email_ajax)) OR (isDefined(&quot;form.email_post&quot;) AND isValid(&quot;email&quot;,form.email_post))&gt;
   &lt;cfset email_check = &quot;valid&quot;/&gt;
&lt;cfelse&gt;
    &lt;cfset email_check = &quot;invalid&quot;/&gt;
&lt;/cfif&gt;

&lt;cfset StructInsert(return_struct, &quot;email_check&quot;, email_check) /&gt;

&lt;cfif isDefined(&quot;form.email_ajax&quot;)&gt;
	&lt;cfset StructInsert(return_struct, &quot;name&quot;, form.name_ajax) /&gt;
	&lt;cfset StructInsert(return_struct, &quot;email&quot;, form.email_ajax) /&gt;

	&lt;!---return_json_string is for pre-CF 8 only, delete if you have cf 8 or later---&gt;
	&lt;cfset return_json_string = '{&quot;email_check&quot;:&quot;#email_check#&quot;,&quot;name&quot;:&quot;' &amp; form.name_ajax &amp; '&quot;,&quot;email&quot;:&quot;' &amp; form.email_ajax &amp; '&quot;}' /&gt;

&lt;cfelse&gt;
	&lt;cfset StructInsert(return_struct, &quot;name&quot;, form.name_post) /&gt;
	&lt;cfset StructInsert(return_struct, &quot;email&quot;, form.email_post) /&gt;

	&lt;!---return_json_string is for pre-CF 8 only, delete if you have cf 8 or later---&gt;
	&lt;cfset return_json_string = '{&quot;email_check&quot;:&quot;#email_check#&quot;,&quot;name&quot;:&quot;' &amp; form.name_post &amp; '&quot;,&quot;email&quot;:&quot;' &amp; form.email_post &amp; '&quot;}' /&gt;

&lt;/cfif&gt;

&lt;!--- serializeJSON is CF 8 and above only, see below for pre-CF 8 ---&gt;
&lt;cfoutput&gt;#serializeJSON(return_struct)#&lt;/cfoutput&gt;

&lt;!--- Uncomment the cfoutput statement below and remove the cfoutput statement above if you don't have CF 8---&gt;
&lt;!--- &lt;cfoutput&gt;#return_json_string#&lt;/cfoutput&gt; ---&gt;
</pre>
<p>This code puts the results of the e-mail validation and the form data in a <a href="http://json.org/">JSON-formatted</a> string. It then will output the return data string which is picked up by the success function in the .ajax function or the function(data) function in the .post function on the original page. </p>
<p>I prefer working with JSON, but there are other options for the return data. Check the jQuery documentation for the types available to you.</p>
<p>The JSON response will look like this:</p>
<pre class="brush: jscript;">
{&quot;email_check&quot;:&quot;valid&quot;,&quot;name&quot;:&quot;Julia&quot;,&quot;email&quot;:&quot;julia@example.com&quot;}
</pre>
<p><span style="color: red;font-weight: bold;">NOTE: If you have ColdFusion 8 or better use the <a href="http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_s_03.html">serializeJSON function</a>. This function can return query results, arrays, dates, strings, and the like to JSON which is easily consumed and digested by javascript. Pre-CF 8 will require building the JSON string manually but with some loops and other creativity, it can be done.</span></p>
<p>The appropriate message based on the e-mail validation check is then displayed.</p>
<p>Pretty simple, pretty handy couple of jQuery functions. Once you see it in action, you get the idea.</p>
<p>Usual recommended jQuery and CF reading:</p>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0596159773" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0321647491" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847195121" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=032151548X" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="http://cf-jensbits.com/demos/jquery/submit/" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/jquery/submit/']); return false;"><span>Demo</span></a></p>
<p id="download"><a href="/media/code/jQAjaxPostCF.zip"><span>Download zip of all files</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>Related posts:<ol><li><a href='http://www.jensbits.com/2009/10/04/jquery-ajax-and-jquery-post-form-submit-examples-with-php/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with PHP'>jQuery.ajax and jQuery.post Form Submit Examples with PHP</a></li>
<li><a href='http://www.jensbits.com/2009/08/10/modal-confirmation-dialog-on-form-submit-javascript-jquery-ui-and-thickbox-varieties/' rel='bookmark' title='Permanent Link: Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties'>Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties</a></li>
<li><a href='http://www.jensbits.com/2010/05/29/using-jquery-autocomplete-to-populate-another-autocomplete-asp-net-coldfusion-and-php-examples/' rel='bookmark' title='Permanent Link: Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples'>Using jQuery Autocomplete to Populate Another Autocomplete &#8211; ASP.NET, ColdFusion, and PHP Examples</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>ColdFusion Example: Session Timeout Warning with jQuery/JS</title>
		<link>http://www.jensbits.com/2009/09/12/session-timeout-warning-with-coldfusion-and-jqueryjs/</link>
		<comments>http://www.jensbits.com/2009/09/12/session-timeout-warning-with-coldfusion-and-jqueryjs/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 18:57:58 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=412</guid>
		<description><![CDATA[You may also be interested in the post on refreshing session without reloading page with ColdFusion. Updated 11-Jan-2010: Improved ability to adjust timeouts and simplified code a bit. I wrote a post on session timeout warnings with PHP; here&#8217;s a version with ColdFusion. Some of the text is the same because the method and principles [...]


Related posts:<ol><li><a href='http://www.jensbits.com/2010/04/18/coldfusion-session-timeout-with-warning-and-session-refresh/' rel='bookmark' title='Permanent Link: ColdFusion Session Timeout with Warning and jQuery Session Refresh'>ColdFusion Session Timeout with Warning and jQuery Session Refresh</a></li>
<li><a href='http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion'>jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2010/03/18/jquery-ui-autocomplete-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with ColdFusion'>jQuery UI Autocomplete Widget with ColdFusion</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<blockquote><p>You may also be interested in the post on <a href="/2010/04/18/coldfusion-session-timeout-with-warning-and-session-refresh/">refreshing session without reloading page with ColdFusion</a>. Updated 11-Jan-2010: Improved ability to adjust timeouts and simplified code a bit.</p></blockquote>
<p>I wrote a <a href="/2009/09/07/session-timeout-warning-php-example-with-jqueryjs/">post on session timeout warnings with PHP</a>; here&#8217;s a version with ColdFusion. Some of the text is the same because the method and principles are the same for both languages.</p>
<p>Javascript is needed to keep track of the time the user has been sitting on the page. The server does not know how long they have been sitting there. It only knows whether or not a request comes in during a session or after the session has expired and acts accordingly at that time. Too late for a warning.</p>
<h3>Session Defined: Start to Finish</h3>
<p>A session is defined as when a user begins and ends using or visiting a web site. It can be unlimited in length or strictly defined by a timeout period. If the site requires a log in or accesses sensitive data, it should time out after a period of inactivity. They can end a session by logging out or closing the browser.</p>
<p>Inactivity means the user has done nothing, made no requests of the web server, during a specified time. Ajax requests usually do not count. </p>
<h3>Demo</h3>
<p>The session time left is determined by the server, and, if you want to poll the server with an Ajax request, go for it. Javascript is used to keep track of the time left in the session.</p>
<p>The demo uses a simple log in with session timing handled by jquery and javascript. When the session expiration approaches, the user is warned and given an opportunity to restart the session. If the session time limit is reached, the user is prompted to log in again. If they ignore that prompt, the page automatically redirects to the log in form. In the demo this sequence of events takes 40 seconds to complete and is broken down as follows:</p>
<ol>
<li><em>Session timeout:</em> 30 seconds</li>
<li><strong>Timeout warning:</strong> 20 seconds</li>
<li><strong>Session expired warning:</strong> 10 seconds</li>
<li><strong>Redirect to log in page: </strong>10 seconds</li>
</ol>
<h3>Interrupting the User</h3>
<p>The user&#8217;s attention can be diverted away from other open windows to the eminent session expiration by using a javascript alert in place of the jquery dialog box. Personal preference.</p>
<h3>Code Breakdown</h3>
<p>The application.cfc controls the session by creating non-persistent cookies for CFID and CFTOKEN so the session expires when the user&#8217;s browser closes. It also sets the session variable sessionStartTime. The sessionStartTime variable is used to illustrate the fact that the application.cfc function OnSessionStart only fires once. It does not fire every time a session is renewed or restarted.</p>
<pre class="brush: coldfusion;">
&lt;cfcomponent
    displayname=&quot;Application&quot;
    output=&quot;false&quot;
    hint=&quot;Handle the application.&quot;&gt;

    &lt;!--- Set up the application. ---&gt;
    &lt;cfset THIS.Name = &quot;sessiontest&quot; /&gt;
    &lt;cfset THIS.ApplicationTimeout = CreateTimeSpan(0,1,0,0) /&gt;
    &lt;!--- CreateTimeSpan(days, hours, minutes, seconds) ---&gt;
    &lt;cfset THIS.SessionTimeout = CreateTimeSpan(0,0,0,30) /&gt;
    &lt;cfset THIS.SessionManagement = true /&gt;
    &lt;cfset THIS.SetClientCookies = false /&gt;

    &lt;cffunction
        name=&quot;OnSessionStart&quot;
        access=&quot;public&quot;
        returntype=&quot;void&quot;
        output=&quot;false&quot;
        hint=&quot;Fires ONLY ONCE when session first created and not when session renewed/restarted.&quot;&gt;       

        &lt;!---set cfid/cftoken as non-persistent cookies so session ends on browser close ---&gt;
        &lt;cfif not IsDefined(&quot;Cookie.CFID&quot;)&gt;
            &lt;cflock scope=&quot;session&quot; type=&quot;readonly&quot; timeout=&quot;5&quot;&gt;
                &lt;cfcookie name=&quot;CFID&quot; value=&quot;#session.CFID#&quot;&gt;
                &lt;cfcookie name=&quot;CFTOKEN&quot; value=&quot;#session.CFTOKEN#&quot;&gt;
                 &lt;cfset session.SessionStartTime = Now() /&gt;
            &lt;/cflock&gt;
        &lt;/cfif&gt;

        &lt;cfreturn /&gt;
    &lt;/cffunction&gt;

&lt;/cfcomponent&gt;
</pre>
<p>The log in page checks for a query string variable called &#8216;expired&#8217; and, if present, deletes the session loggedin variable. This is there because the code is going to control the expiration of the session eliminating the need to compensate for browser latency. The actual session start time the time the page loads can differ by several seconds. To avoid having to add time to the session or any other fancy guesswork, when the allotted session time has expired according to the javascript timer on the page, they are done &#8211; session over.</p>
<p>If they are logged in, they get bumped to the index page. The rest is the logic that handles the log in form.</p>
<p>Note: I would not recommend handling a log in form this way. This is for demonstration only.</p>
<pre class="brush: coldfusion;">
&lt;cfif isDefined(&quot;url.expired&quot;) AND url.expired&gt;
    &lt;cfset StructDelete(session,&quot;loggedin&quot;) /&gt;
&lt;/cfif&gt;

&lt;cfif isDefined(&quot;form.username&quot;) AND isDefined(&quot;form.pw&quot;) AND form.username EQ &quot;session&quot; AND form.pw EQ &quot;test&quot;&gt;
    &lt;cfset session.loggedin = true /&gt;
&lt;/cfif&gt;

&lt;cfif StructKeyExists(session, &quot;loggedin&quot;) AND session.loggedin&gt;
    &lt;cflocation url=&quot;index.cfm&quot; addToken=&quot;no&quot; /&gt;
&lt;/cfif&gt;
</pre>
<p>Other than the log in form and a message for the user, that&#8217;s all there is to the log in page.</p>
<h3>Handling Session Timeout</h3>
<p>The index page handles the session timeout code. This could be a separate javascript included in every page. The first block simply determines if they are logged in. If they are not, send them to the login page. If they are, load the index page.</p>
<pre class="brush: coldfusion;">
&lt;!---if not logged in, send them to login page, else load the index page---&gt;
&lt;cfif NOT StructKeyExists(session, &quot;loggedin&quot;) OR NOT session.loggedin&gt;
    &lt;cflocation url=&quot;login.cfm&quot; addToken=&quot;no&quot; /&gt;
&lt;cfelse&gt;
 &lt;!---Load the page ---&gt;
&lt;/cfif&gt;
</pre>
<p>Now the time variables are set and the a javascript timer is set to check the session every 10 seconds.<br />
Javascript uses milliseconds so for clarity the time intervals multiply the number of seconds by 1,000. You could put 10000 in for 10 seconds but I think 10*1000 helps me determine that it is 10 seconds quite a bit faster. Do what is comfortable for you.</p>
<p>Also, a flag is set to determine if the warning dialog box has been opened and the countdown has begun.</p>
<pre class="brush: jscript;">
//event to check session time variable declaration
var checkSessionTimeEvent = 0;

$(document).ready(function() {
	//event to check session time left (times 1000 to convert seconds to milliseconds)
    checkSessionTimeEvent = setInterval(&quot;checkSessionTime()&quot;,10*1000);
});

//Your timing variables in number of seconds

//total length of session in seconds
var sessionLength = 30;
//time warning shown (10 = warning box shown 10 seconds before session starts)
var warning = 10;
//time redirect forced (10 = redirect forced 10 seconds after session ends)
var forceRedirect = 10; 

//time session started
var requestTime = new Date();

//session timeout length
var timeoutLength = sessionLength*1000;

//set time for first warning, ten seconds before session expires
var warningTime = timeoutLength - (warning*1000);

//force redirect to log in page length (session timeout plus 10 seconds)
var forceRedirectLength = timeoutLength + (forceRedirect*1000);

//set number of seconds to count down from for countdown ticker
var countdownTime = warning;

//warning dialog open; countdown underway
var warningStarted = false;
</pre>
<p>The checkSessionTime function is what gets fired off every 10 seconds by the timer. It does a time comparison and opens the dialog boxes that warn the user.</p>
<pre class="brush: jscript;">
function checkSessionTime()
{
	//get time now
	var timeNow = new Date(); 

	//event create countdown ticker variable declaration
	var countdownTickerEvent; 	

	//difference between time now and time session started variable declartion
	var timeDifference = 0;

	timeDifference = timeNow - requestTime;

    if (timeDifference &gt; warningTime &amp;&amp; warningStarted === false)
        {
            //call now for initial dialog box text (time left until session timeout)
            countdownTicker(); 

            //set as interval event to countdown seconds to session timeout
            countdownTickerEvent = setInterval(&quot;countdownTicker()&quot;, 1000);

            $('#dialogWarning').dialog('open');
            warningStarted = true;
        }
    else if (timeDifference &gt; timeoutLength)
    	{
    		//close warning dialog box
            if ($('#dialogWarning').dialog('isOpen')) $('#dialogWarning').dialog('close');

            $('#dialogExpired').dialog('open');

            //clear (stop) countdown ticker
            clearInterval(countdownTickerEvent);
        }

     if (timeDifference &gt; forceRedirectLength)
     	{
        	//clear (stop) checksession event
            clearInterval(checkSessionTimeEvent);

            //force relocation
            window.location=&quot;login.cfm?expired=true&quot;;
        }
}
</pre>
<p>The countdownTicker function provides a countdown inside the warning dialog box to prompt the user to act now. It uses a timer that fires every second for a 5,4,3,2,1 effect inside the dialog box.</p>
<pre class="brush: jscript;">
function countdownTicker()
{
	//put countdown time left in dialog box
	$(&quot;span#dialogText-warning&quot;).html(countdownTime);

	//decrement countdownTime
	countdownTime--;
}
</pre>
<p>And, the dialog boxes either allow the user to reload the page or, if they did nothing when the warning popped up, it logs them out by redirecting to the log in page with the expired variable in the query string. Also, thanks to scube&#8217;s debugging, it now redirects to the log in if they hit the close button on the dialog box rather than the Login button.</p>
<pre class="brush: jscript;">
$(function(){
                // jQuery UI Dialog
                $('#dialogWarning').dialog({
                    autoOpen: false,
                    width: 400,
                    modal: true,
                    resizable: false,
		    close: function() {
                            window.location=&quot;login.php?expired=true&quot;;
                     },
                    buttons: {
                        &quot;Restart Session&quot;: function() {
                            location.reload();
                        }
                    }
                });

                $('#dialogExpired').dialog({
                    autoOpen: false,
                    width: 400,
                    modal: true,
                    resizable: false,
                    buttons: {
                        &quot;Login&quot;: function() {
                            window.location=&quot;login.cfm?expired=true&quot;;
                        }
                    }
                });
});
</pre>
<p>The dialog box contents are at the bottom of the page but they could be just about anywhere in the body.</p>
<pre class="brush: xml;">
&lt;!--Dialog box contents--&gt;
&lt;div id=&quot;dialogExpired&quot; title=&quot;Session (Page) Expired!&quot;&gt;&lt;p&gt;&lt;span class=&quot;ui-icon ui-icon-alert&quot; style=&quot;float:left; margin:0 7px 0 0;&quot;&gt;&lt;/span&gt; Your session has expired!&lt;p id=&quot;dialogText-expired&quot;&gt;&lt;/p&gt;&lt;/div&gt;

&lt;div id=&quot;dialogWarning&quot; title=&quot;Session (Page) Expiring!&quot;&gt;&lt;p&gt;&lt;span class=&quot;ui-icon ui-icon-alert&quot; style=&quot;float:left; margin:0 7px 0 0;&quot;&gt;&lt;/span&gt; Your session will expire in &lt;span id=&quot;dialogText-warning&quot;&gt;&lt;/span&gt; seconds!&lt;/div&gt;
</pre>
<p>Remember, this is just one example. There are other ways to do this. Use this, improve this, or roll your own.</p>
<p>Usual recommended jQuery and CF reading:</p>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0596159773" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0321647491" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847195121" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=032151548X" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="http://cf-jensbits.com/demos/session/login.cfm" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/demos/session/login.cfm']); return false;"><span>Demo</span></a></p>
<p id="download"><a href="/media/code/session-expire-cf.zip"><span>Download</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
<!-- End PayPal Donations -->



<p>Related posts:<ol><li><a href='http://www.jensbits.com/2010/04/18/coldfusion-session-timeout-with-warning-and-session-refresh/' rel='bookmark' title='Permanent Link: ColdFusion Session Timeout with Warning and jQuery Session Refresh'>ColdFusion Session Timeout with Warning and jQuery Session Refresh</a></li>
<li><a href='http://www.jensbits.com/2009/10/23/jquery-ajax-and-jquery-post-form-submit-examples-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion'>jQuery.ajax and jQuery.post Form Submit Examples with ColdFusion</a></li>
<li><a href='http://www.jensbits.com/2010/03/18/jquery-ui-autocomplete-with-coldfusion/' rel='bookmark' title='Permanent Link: jQuery UI Autocomplete Widget with ColdFusion'>jQuery UI Autocomplete Widget with ColdFusion</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/09/12/session-timeout-warning-with-coldfusion-and-jqueryjs/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>
