Simple ColdFusion 8 PDF Inspector

Hi folks,

I'm working on a project where I programmatically fill in government PDF forms. In today's case -- Lien Applications.

Well, the first thing I've got to know about the PDF file is:

  1. Is it really an interactive form? (if it's not I'll have to try and add form fields by hand with Adobe Acrobat Pro)
  2. If it's already an interactive form, then what's the structure of that form, and what are the names of the form fields?

The client I'm doing this for has stores in nine different states, so that's nine different versions of basically the same form -- but every state is a little different. At first I wrote a really quick and very specific CF program to give me this information. But now that I'm on my second and third form I decided that I'd rather spend a few minutes building a tool which would accept a path to my PDF and upon clicking a button give me the information I needed.

So that's what I did. And here's the code. Improvements could probably be made, and if you like, you're completely welcome to do so. But what's here works perfectly for my purposes.

[More]

jQuery + AjaxCFC Tutorial Part 1: Erratum 1

In part one of this tutorial series I noted the mechanism by which I enable/disable log4javascript using the CF variable 'JSIncludeList' along with a boolean 'ShowLog4JS'.

<CFSet ShowLog4JS = false>
<CFSet JSIncludeList = "">
<CFIf ShowLog4JS>
    <CFSet JSIncludeList = ListAppend(JSIncludeList, "log4j")>
</CFIf>

I also made mention of the following helper functions:

$.AjaxCFCHelper.setDebug(false);
$.AjaxCFCHelper.setBlockUI(true);
$.AjaxCFCHelper.setUseDefaultErrorHandler(true);
$.AjaxCFCHelper.setSerialization('json'); // json, wddx

I have to admit that I'd not used any of these functions before, but I wanted to at least make everyone aware of their existance. Well, I used the first one on the above list today while helping a friend to debug some code. It turns out that

$.AjaxCFCHelper.setDebug(true);

turns on log4javascript! So, basically I reinvented the wheel, and Rob already had us covered with a mechanism to turn on and off log4javascript.

If I learn anything new between now and when I finally get part two of this tutorial written (probably this weekend), I'll be sure to post another quick errata.

Cheers!

ColdFusion Tip: Using ListFind To Save Time

Here's something cool that you can do with ListFind() or ListFindNoCase() that could save you loads of typing. It's something I've been doing for years in ColdFusion. And who knows -- maybe everyone else has been too! But I'll just put it out there for your consumption. :o)

Have you ever written a piece of code that looks like this?

<CFIf ThisReportType EQ "OrdersPlaced"
    OR ThisReportType EQ "DailyNeeds"
    OR ThisReportType EQ "TravelExpenses"
    OR ThisReportType EQ "SpendRecap"
    OR ThisReportType EQ "FillRate"
    OR ThisReportType EQ "FillRateException"
    OR ThisReportType EQ "ShiftsFilled"
    OR ThisReportType EQ "OrderPlacementMethod"
    OR ThisReportType EQ "ResponseTime">

    <!--- then do something that pertains to all these different report types --->
</CFIf>

Yuck. That's a lot of typing (to me). If you're anything like me, I typically have a bunch of lists in my code. In this case I'm almost sure to have a list of report types called something clever like "ReportTypeList". Well, lets say that you've got twenty or thirty reports in your application, and just the above mentioned subset need some special code added.

Why not use ListFind() or ListFindNoCase()? Like this:

...
<CFSet ReportSubTypeList = "OrdersPlaced,DailyNeeds,TravelExpenses,SpendRecap,FillRate,
FillRateException,ShiftsFilled,OrderPlacementMethod,ResponseTime"
>

<CFIf ListFindNoCase(ReportSubTypeList, ThisReportType)>
    <!--- then do something that pertains to the given report type --->
</CFIf>
...

I like to use ListFindNoCase() just so I don't have to worry about case when performing an operation like this.

I have not run any tests to see how the different methods perform, but I imagine that they're not much different from each other. It just saved me a lot of repetitive typing.

Now, I stole that first snippet of code from a friend of mine, and in looking at the rest of the code I found that he had that same opening if statement repeated two or three times on the page!

Ick!

Yes. He probably did use cut and paste, but what happens when he has another report come along that needs the same special code? He's got to go add "OR ThisReportType EQ..." in perhaps several spots. I've only got to add a single word to a single list (probably somewhere at the top of my code), and I'm done! Finished! Movin' on to the next programming task for the day. My change took two seconds, and it affected the entire program, while his change probably took him three to five minutes and with all that typing (or cutting and pasting) he could have made several typos, and introduced a new bug to track down.

Also, I just find this little trick more elegant somehow.:o)

I'd also like to add that because both the ListFind() and ListFindNoCase() functions are available in the CFJS library, you can now employ this same little time-saving trick in your JavaScript too. :o)

Well, there's another neat little trick that you may want to tuck into your toolkit. ;o)

Cheers!

ColdFusion Loop Break

Here's a simple idea that my friend Steven Van Gemert came up with a couple of years ago. It's a neat little trick, and maybe some folks will find it useful.

Have you ever gotten yourself into an infinite loop? C'mon... we've all done it once or twice on accident, haven't we? Or maybe you've got a particularly long running loop that you'd like to be able to break out of. I'm not referring to a break tag where you'd have to come up with some condition under which to break.

Well, here's the trick Steven came up with that allows you to do just that. He called it 'thread control' for lack of a better name, though I think 'loop control' or 'loop break' would be a better name for it. Here's what you do: create an empty file (with one space in it) and save it as LoopControl.cfm (or whatever you want to call it). Then somewhere in your loop (top, bottom, middle-ish: it's up to you) do a <cfinclude template="/path/to/loopcontrol.cfm">

<cfloop condition="true">
    <cfset a = a + 1>
    <!--- oh no... an infinite loop! --->
    <cfinclude template="/Path/To/LoopControl.cfm">
</cfloop>

Now when you want to break out of that loop simply insert a <cfabort>, or <cfbreak> tag (along with any other code you want to run before exiting the loop) into your LoopControl.cfm file. Then when CF goes to include the file the next time, your new code gets inserted at that point and the loop is broken.

Neat, huh?

So why create an empty file with a space in it? Well, if you're working with CF5, an error gets thrown if you try to include a zero byte file. However, if you're using any of the MX versions of ColdFusion, then you're okay to include an empty file, as that behavior was changed when MX came around. Or you could write all the code you want to have in your LoopControl.cfm and slap comments around it.

<!---
    <cfinclude Template="/Include/OnRequestEnd.cfm">
    <cfabort>
--->

Then to break the loop, remove the comments and save the file. The next time CF includes the file, the new code will be executed, and the loop will be broken.

So that's a little trick that may come in handy someday. We use it when testing large maintenance programs that we may want to interrupt in the middle of processing.

Just tuck it away in your toolbox for later. :o)

BlogCFC was created by Raymond Camden. This blog is running version 5.9.4.001. Contact Blog Owner