Paul Robertson's words, punctuated

Thoughts on development, user-centered design, code, etc. by Paul Robertson

Loading a cfform SWF into another SWF

I haven’t written about ColdFusion Flash Forms in a while (I’m a Flex user now that you no longer need a server to create the content). However, this morning I got an interesting question from “trifide” that I hadn’t considered before, so I’m making a brief return into cfform land:

There are many attempts to loading external swf into cfform. But what about the contrary? Do you know a way to embed cfform into a flash movie? i.e. call a cfform in a movieclip without getURL and external pop-up ..

I started writing a comment response, but naturally it was getting pretty long-winded so I decided it deserved its own posting.

When you use cfform in a coldfusion page, the server generates a SWF file, with its own URL. (I don’t know whether it actually writes it to the disk, or whether it just keeps it in it’s memory – but from the end-user perspective that doesn’t really matter.) More specifically, it generates a SWF, then sends the appropriate HTML to the browser including the URL of the SWF. From the browser’s perspective the SWF is a completely separate item at a different URL – the browser doesn’t know that the programmer wrote it all in a single document. You can see the generated SWF’s URL by looking at the HTML source code of the CFM page.

For example, consider the page at the following URL (an example accompanying an article by the folks at ASFusion):

http://www.asfusion.com/blog/examples/cfdj/

If you view the source, you’ll see that the page includes some JavaScript that is used to write the appropriate object and embed tags into the browser page. Right in the middle of that you’ll see this line (today at least; the file name may change in the future, as explained below):

document.write("   src='/blog/examples/cfdj/859792312.mxml.cfswf' ");

That’s the line of JavaScript that’s writing the SWF’s generated URL into the page. So we know that there is a URL that the web server will recognize and, when a computer requests that URL, the server will return the appropriate SWF.

You can try it out if you’d like – try requesting the SWF’s URL directly (i.e. http://www.asfusion.com/blog/examples/cfdj/859792312.mxml.cfswf) and you’ll see the same SWF, without the HTML page wrapper.

So, knowing the URL of the generated SWF, you can use it in the same way you’d use any SWF. As I mentioned, you can type the URL in the browser to request it directly, or you could alternatively load it into another SWF using MovieClip.loadMovie() or any other MovieClip loading technique (e.g. the Loader class in ActionScript 3.0).

Potential issues

There are, of course, a couple of gotchas that you’ll want to keep in mind.

  1. First of all, notice that the generated SWF’s URL is really just a number with a couple of file extensions. The reason for that is because this generated URL represents a single version of your cfform SWF. If you change the source code of the cfform in such a way that it needs to recompile the SWF, then the server will generate a new SWF with a new URL. So any time you change your cfform, the URL will change too (and, obviously, you’ll need to change the URL that’s called by the other SWF doing the loading). The reason the URL changes is to prevent the browser from using the cached (old) SWF – with a new URL, the browser loads a new SWF.

    An obvious workaround is to just make a copy of the generated SWF and put it at a permanent URL. Like I said, I’m not sure if ColdFusion actually writes the generated SWF to the server’s hard drive, or whether it just keeps it in memory. If it does write it to disk it should be easy to get a copy from the server. If not, you can just load the SWF directly in a browser and then choose “Save As…” (or whatever) from your browser to save a copy of the SWF locally. BUT, by using a single URL, you lose the automatic versioning that prevents the browser from caching the SWF. You can find one idea to work around that issue (i.e. to do your own SWF versioning) in my article ”Using URL Variables and FlashVars” (specifically the URL Variables part of the article).

  2. Second (and this is a big one): From my rudimentary tests, it looks like any queries in the CF page that the cfform uses are not available when you load the SWF separate from the CFM page. I’m not sure why – I’d have to look more at the generated MXML to try to figure it out – but my guess is that the SWF makes use of the URL of its container HTML page to figure out where to communicate to get its data (rather than having the CFM page’s URL hard-coded into the SWF). Depending on what you want to use the cfform for, that probably throws a big wrench into things.
  3. If you’re actually using the cfform for its intended purpose – that is, as a form to submit data – you’re going to have some issues with loading it into another SWF. When you submit a cf flash form, it navigates away from the current URL to the cfform tag’s “target” URL (essentially using LoadVars.send(), so clicking that button on a cfform SWF loaded into another SWF would navigate away from the container SWF as well.

Finally, I can’t help but mention that loading a cfform SWF into another SWF may be a case of over-complicating something that can be done better in other ways. The obvious alternative is to just use Flex directly to create the form SWF, then loading the Flex SWF into the other SWF. Naturally, that means you’ll need to learn Flex…but if you’ve used cf flash forms then you’re already well on your way into that territory – just write out the generated mxml and take a look at what it consists of; then change a few things in the cfform and see how that changes the generated mxml…and so on. Don’t get me wrong – I’m sure there are legitimate reasons for using cfform rather than Flex in this situation, and I obviously can’t predict all the use cases. But over the long run I think you’ll find it’s a lot easier, without any of the issues or side effects, to use Flex.

Comments