Filling date gaps in a report Filling date gaps in a report Filling date gaps in a report
I needed a way to push a bunch of blank dates into a query for a cfchart to ensure I didn't have any gaps in my date coverage. This article did the trick...

Read more...

AjaxOnLoad and cfhtmlhead AjaxOnLoad and cfhtmlhead AjaxOnLoad and cfhtmlhead

I had an odd issue today where I was using AjaxOnLoad to run a javascript, and I was getting an error that the function was not defined. The function and the ColdFusion.Event.registerOnLoad even were both getting added to the page. I could create an anchor tag on the page with an onclick and it would run the code fine, so I was perplexed as to why it was telling me that the function wasn't defined. See if you can spot the problem.

<cfset AjaxOnLoad("myFunction") />

<cfsavecontent variable="headContent">
<script type="text/javascript">
var myFunction = function(){
   alert('yo der');
}
</script>
</cfsavecontent>

<cfhtmlhead text="#headContent#" />

Turns out that CF is simply adding content to the head of the document as you call the CF code. This means that with the above code snippet, the registerOnLoad script was getting called before the other function in the code. Changing my CF to this fixed the issue:

<cfsavecontent variable="headContent">
<script type="text/javascript">
var myFunction = function(){
   alert('yo der');
}
</script>
</cfsavecontent>

<cfhtmlhead text="#headContent#" />

<cfset AjaxOnLoad("myFunction") />

I'm not used to thinking that hard about where I stick my cfhtmlhead tags. Guess I better pay closer attention next time.

onMissingMethod Issue Cleared Up onMissingMethod Issue Cleared Up onMissingMethod Issue Cleared Up

At LandsofAmerica I've been making extensive use of the onMissingMethod() functionality of CF8 to provide implicit getters and setters. This has worked fantastically well, and I'm never going back to explicitly declaring these unless I have to :). But one problem I've had was with using my implicit getters and setters inside my objects. It just didn't work...

My onMissingMethod() functionality is wrapped up in a base decorator object that all of my base objects extend. It looks like this:

<cfcomponent displayname="Base Decorator" hint="This object provides default methods for all base objects. All base objects should extend BaseDecorator" output="false">

   <cfset variables.instance = StructNew() />

   <cffunction name="init" access="public" returntype="any" output="false">

      <!--- Loop through the arguments and run a setter for each one supplied --->
      <cfloop collection="#Arguments#" item="property">
         <cfif property NEQ "id">
            <cfset set(property, Arguments[property]) />
         </cfif>
      </cfloop>

      <cfreturn this />
   </cffunction>

   <!--- Don't allow the setID method to be called from the outside --->
   <cffunction name="setID" access="private" returntype="void" output="false">
      <cfargument name="ID" type="numeric" required="true" />
      <cfset variables.instance.ID = Trim(Arguments.ID) />
   </cffunction>
   <cffunction name="getID" access="public" returntype="numeric" output="false">
      <cfreturn variables.instance.ID />
   </cffunction>

   <cffunction name="get" access="private" output="false" returnType="any">
      <cfargument name="property" type="string" required="false" default="" />
      <cfargument name="defaultValue" type="any" required="false" default="" />
      <cfset var retVal = "" />
      <cfif Arguments.Property NEQ "">
         <cfif NOT StructKeyExists(variables.instance, Arguments.Property)>
            <cfset set(Arguments.property, Arguments.defaultValue) />
         </cfif>
         <cfset retVal = variables.instance[arguments.property]>
      <cfelse>
         <cfset retVal = variables.instance />
      </cfif>

      <cfif IsSimpleValue(retVal)>
         <cfreturn Trim(retVal) />
      <cfelse>
         <cfreturn retVal />
      </cfif>
   </cffunction>

   <cffunction name="set" access="private" output="false" returnType="void">
    <cfargument name="property" type="string" required="true">
    <cfargument name="value" type="any" required="true">
    <cfset variables.instance[arguments.property] = arguments.value />
   </cffunction>

   <cffunction name="onMissingMethod" output="false">
      <cfargument name="missingMethodName" type="string">
      <cfargument name="missingMethodArguments" type="struct">

      <cfset var property = "">
      <cfset var value = "">

      <cfif findNoCase("get",arguments.missingMethodName) is 1>
         <cfset property = replaceNoCase(arguments.missingMethodName,"get","")>
         <cfif NOT StructIsEmpty(Arguments.missingMethodArguments)>
            <cfset value = arguments.missingMethodArguments[listFirst(structKeyList(arguments.missingMethodArguments))]>

         </cfif>
         <cfreturn get(property, value) />

      <cfelseif findNoCase("set",arguments.missingMethodName) is 1>
         <cfset property = replaceNoCase(arguments.missingMethodName,"set","")>
         <!--- assume only arg is value --->
         <cfset value = arguments.missingMethodArguments[listFirst(structKeyList(arguments.missingMethodArguments))]>
         <cfset set(property,value)>

      </cfif>

   </cffunction>
</cfcomponent>

So within my objects, if I called getSomeValue(), I would get an error that method didn't exist (duh, that's why I have onMissingMethod()). For the life of me I couldn't figure out a way around it, so I just started calling get("SomeValue") while I was inside an object. This was workable, though not necessarily ideal. It means that if I refactor a particular method to make it explicit (by creating a getSomeValue method), then I would need to go through my object and replace all of the get("somevalue") calls with getSomeValue().

Well Ben Nadel just made a post on his blog, Comprehensive ColdFusion Component OnMissingMethod() Testing that solves the problem... When calling an objects internal methods, if you always THIS scope them, then onMissingMethod will fire like it's supposed to.

Thanks Ben, now I have to go through and do all of those find/replaces ;-)

We Made a Baby!!! We Made a Baby!!! We Made a Baby!!!
Aren't you jealous?

Read more...

I Love MXUnit I Love MXUnit I Love MXUnit

I just thought you should know that...

MXUnitPass.png

Get your own dose of lovin' at MXUnit.org.

Powered by Mango Blog.