jQuery + ColdFusion 8 = Erotic And Magnetic Poetry

Posted August 31, 2007 at 8:08 AM by Ben Nadel

Tags: ColdFusion, Javascript / DHTML

I just opened a ColdFusion 8 account at HostMySite.com and I'm already having fun playing around with all the new features of ColdFusion 8. Yesterday, I put up a demo that combines the unbelievable simplicity of jQuery with the image manipulation power of ColdFusion 8 to create a drag-and-drop magnetic poetry system; you know, like the kind you see on the refrigerator doors in college dorm rooms and young adult apartments. Using jQuery, the user can add images to the "Canvas". Then, using the a jQuery plugin (Interface), the user can drag and drop the magnetic pieces around on the Canvas. Once the positioning is done, the image data is submitted to the server where ColdFusion 8 will compile all the pieces into one PNG image that is streamed to the browser.


 
 
 

 
jQuery And ColdFusion 8 Erotic, Magnetic Poetry Graphic  
 
 
 

Lots of fun to be had. Try it out for your self here:

jQuery + ColdFusion 8 = Erotic And Magnetic Poetry Online Demo

The system was actually quite simple to build and consists of only two ColdFusion templates and some jQuery files. The hardest part of the system was building the images used for the actual magnetic pieces. One day, I might be able to build the magnetic images using ColdFusion 8, but I doubt the server has my web site font.

The first ColdFusion 8 page displays the canvas and uses jQuery to manipulate the magnetic pieces:

  • <!--- Kill extra output. --->
  • <cfsilent>
  •  
  • <!--- Query for word images. --->
  • <cfdirectory
  • action="list"
  • directory="#ExpandPath( './words/' )#"
  • type="file"
  • listinfo="name"
  • sort="name ASC"
  • name="qWord"
  • />
  •  
  • <!---
  • Loop over words to get rid of file extensions.
  • We are going to be using these values to create the
  • word list and we don't need the file extensions
  • (we are going to assume they are all GIF images).
  • --->
  • <cfloop query="qWord">
  •  
  • <!--- Get the word from the file name. --->
  • <cfset qWord[ "name" ][ qWord.CurrentRow ] = ListFirst(
  • qWord.name,
  • "."
  • ) />
  •  
  • </cfloop>
  •  
  • </cfsilent>
  •  
  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>Magnetic Poetry With ColdFusion 8 And jQuery</title>
  •  
  • <style type="text/css">
  •  
  • body,
  • html {
  • background-color: #FFFFFF ;
  • font: 11px verdana ;
  • margin: 0px 0px 0px 0px ;
  • padding: 0px 0px 0px 0px ;
  • }
  •  
  • div#canvas {
  • border: 1px solid #999999 ;
  • height: 600px ;
  • left: 10px ;
  • overflow: hidden ;
  • position: absolute ;
  • top: 10px ;
  • width: 800px ;
  • }
  •  
  • div#wordlist {
  • border: 1px solid #999999 ;
  • height: 600px ;
  • left: 815px ;
  • overflow: auto ;
  • position: absolute ;
  • top: 10px ;
  • width: 200px ;
  • }
  •  
  • div#wordlist a {
  • background-color: #F0F0F0 ;
  • cursor: pointer ;
  • display: block ;
  • line-height: 20px ;
  • margin: 0px 0px 1px 0px ;
  • text-align: center ;
  • }
  •  
  • div#wordlist a:hover {
  • background-color: #FFFFFF ;
  • }
  •  
  • div.magnet {
  • position: absolute ;
  • z-index: 100 ;
  • }
  •  
  • div.magnet img {
  • display: block ;
  • position: relative ;
  • }
  •  
  • form {
  • height: 30px ;
  • left: 10px ;
  • margin: 0px 0px 0px 0px ;
  • position: absolute ;
  • top: 615px ;
  • width: 802px ;
  • }
  •  
  • button {
  • background-color: #FAFAFA ;
  • border: 1px solid #999999 ;
  • display: block ;
  • font-size: 18px ;
  • height: 30px ;
  • margin: 0px auto 0px auto ;
  • width: 800px ;
  • }
  •  
  • textarea {
  • display: none ;
  • }
  •  
  • </style>
  •  
  • <!-- Linked Files. -->
  • <script
  • type="text/javascript"
  • src="./jquery-1.1.4.pack.js">
  • </script>
  •  
  • <script
  • type="text/javascript"
  • src="./interface.drag-drop.js">
  • </script>
  •  
  • <script type="text/javascript">
  •  
  • // Define all the words that are available.
  • var arrWords = (
  • <cfoutput>
  • "#ValueList( qWord.name, "|" )#"
  • </cfoutput>
  • ).split( "|" );
  •  
  •  
  • // When a user clicks on the word link, this initiates
  • // the magnetic adding function (will not fully execute
  • // until the image has loaded).
  • function AddWord( jCanvas, jLink ){
  • var jMagnet = null;
  • var jImg = null;
  •  
  • // Create the magnet DIV.
  • jMagnet = $( "<div>" ).addClass( "magnet" );
  •  
  • // Set the image value.
  • jMagnet.attr( "image", jLink.text() );
  •  
  • // Create the image.
  • jImg = $( "<img>" );
  •  
  • // Set the load function for the img.
  • jImg.load(
  • function(){
  • var jImg = $( this );
  • var jDiv = $( this.parentNode );
  •  
  • // Set the position.
  • jDiv.css( "top", "30px" );
  • jDiv.css( "left", "30px" );
  •  
  • // Set the Div width height.
  • jDiv.width( jImg.width() );
  • jDiv.height( jImg.height() );
  •  
  • // Make the magnet draggable.
  • jDiv.Draggable(
  • {
  • <!--- containment: "parent", --->
  • zIndex: 1000,
  • ghosting: true,
  • opacity: 0.7
  • }
  • );
  • }
  • );
  •  
  • // Append the image to the div.
  • jMagnet.append( jImg );
  •  
  • // Set the image source.
  • jImg.attr(
  • "src",
  • ("words/" + jLink.text() + ".gif")
  • );
  •  
  • // Add the magnet to the canvas.
  • jCanvas.append( jMagnet );
  •  
  • // Return out.
  • return;
  • }
  •  
  •  
  • // This will store the image data into the form and then
  • // submit the form to the page that generates the image
  • // using ColdFusion 8 image functionality.
  • function GenerateImage( jForm, jCanvas ){
  • var jData = $( "textarea#data" );
  • var strData = "";
  • var jMagnet = jCanvas.find( "div.magnet" );
  •  
  • // Loop over the magnets to build the data
  • // string.
  • jMagnet.each(
  • function( intI ){
  • var jDiv = $( this );
  •  
  • // Append list data for image.
  • strData += (
  • jDiv.attr( "image" ) + ":" +
  • parseInt( jDiv.css( "top" ) ) + ":" +
  • parseInt( jDiv.css( "left" ) ) + ","
  • );
  • }
  • );
  •  
  • // Store the data value in the form.
  • jData.val( strData );
  •  
  • // Submit the form.
  • jForm.submit();
  • }
  •  
  •  
  • // This prepares the document once the body has
  • // finished loading and the DOM is ready for
  • // interaction.
  • $(
  • function(){
  • var jCanvas = $( "div#canvas" );
  • var jList = $( "div#wordlist" );
  • var jForm = $( "form" );
  • var jWord = null;
  •  
  • // Loop over all the words.
  • for (
  • var intWord = 0 ;
  • intWord < arrWords.length ;
  • intWord++
  • ){
  •  
  • // Create a link for the word.
  • jWord = $(
  • "<a>" +
  • arrWords[ intWord ] +
  • "</a>"
  • );
  •  
  • // Bind the onclick action.
  • jWord.click(
  • function(){
  • AddWord( jCanvas, $( this ) );
  • }
  • );
  •  
  • // Add the link to the word list.
  • jList.append( jWord );
  • }
  •  
  •  
  • // Set up the form so that we have control
  • // over the submission procress.
  • jForm.find( "button" ).click(
  • function(){
  • GenerateImage( jForm, jCanvas )
  • }
  • );
  • }
  •  
  • );
  •  
  • </script>
  • </head>
  • <body>
  •  
  • <!--- The magnetic canvas. --->
  • <div id="canvas"></div>
  •  
  • <!--- The list of words. --->
  • <div id="wordlist"></div>
  •  
  • <!--- Generate Image form. --->
  • <form action="generate.cfm" method="post" target="_blank">
  •  
  • <button type="button">
  • Generate Image Using ColdFusion 8 &raquo;
  • </button>
  •  
  • <!--- This will store the magnet positional data. --->
  • <textarea name="data" id="data">Blam</textarea>
  •  
  • </form>
  •  
  • </body>
  • </html>

The only ColdFusion 8 specific code on the main page is the fact that the ColdFusion CFDirectory tag is using the ListInfo and Type attributes to make sure that we get only the name values of files in the graphics directory. Other than that, jQuery is really what dominates this page. This works seamlessly on FireFox, but in IE, there is some weird ghosting issues on the drag-and-drop feature. Also, it took me a good amount of time to figure out that ghosting would NOT work if the DIV had an explicit "display: block" style (who knows why?!?).

Once you are done dragging your images around, clicking on the "Generate Image Using ColdFusion 8" button will grab the image data (including positions on the canvas) using jQuery, store it in the Form, and then submit it to another ColdFusion template, generate.cfm. This ColdFusion page then reads in all the images into ColdFusion 8 image objects and pastes them onto a blank canvas. Once all the images are done, I am then just writing the image to the browser.

  • <!--- Kill extra output. --->
  • <cfsilent>
  •  
  • <!--- Param form data. --->
  • <cfparam
  • name="FORM.data"
  • type="string"
  • default=""
  • />
  •  
  •  
  • <!--- Create a new canvas. --->
  • <cfset imgCanvas = ImageNew(
  • "",
  • 800,
  • 600,
  • "rgb",
  • "FFFFFF"
  • ) />
  •  
  •  
  • <!---
  • Loop over the form data as a comma
  • delimited list of magnets data-lists.
  • --->
  • <cfloop
  • index="lstMagnetData"
  • list="#FORM.data#"
  • delimiters=",">
  •  
  • <!--- Get the parts of the magnet data. --->
  • <cfset arrParts = ListToArray( lstMagnetData, ":" ) />
  •  
  • <!--- Make sure that we have three parts. --->
  • <cfif (ArrayLen( arrParts ) EQ 3)>
  •  
  • <!--- Read in the word image. --->
  • <cfimage
  • action="read"
  • source="./words/#arrParts[ 1 ]#.gif"
  • name="imgWord"
  • />
  •  
  • <!---
  • Paste the word image into the canvas using the
  • passed in top/left coordinates.
  • --->
  • <cfset ImagePaste(
  • imgCanvas,
  • imgWord,
  • arrParts[ 3 ],
  • arrParts[ 2 ]
  • ) />
  •  
  • </cfif>
  •  
  • </cfloop>
  •  
  •  
  • <!---
  • ASSERT: At this point, we have pasted in all the
  • magnetic words onto the canvas.
  • --->
  •  
  • </cfsilent>
  •  
  •  
  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>jQuery And ColdFusion 8 - Magnetic Poetry</title>
  •  
  • <style type="text/css">
  •  
  • body {
  • background-color: #F0F0F0 ;
  • }
  •  
  • img {
  • border: 1px solid #666666 ;
  • display: block ;
  • margin: 30px auto 0px auto ;
  • }
  •  
  • </style>
  • </head>
  • <body>
  •  
  • <!--- Write the image to the browser. --->
  • <cfimage
  • action="writetobrowser"
  • source="#imgCanvas#"
  • format="png"
  • />
  •  
  • </body>
  • </html>

This whole thing was really easy to put together. I can already see how amazingly powerful all the new features of ColdFusion 8 are going to be. A few months ago, I would have never been able to do something like this. If I even attempted it, I would have had to build a Flash movie or something that somehow exported to an image. It would have been a pain in the butt. Now, with ColdFusion 8, doing this sort of image manipulation took a white-space-heavy 100 lines of code.

ColdFusion 8 is mad sexy!



Reader Comments

IRz
Aug 31, 2007 at 9:31 AM // reply »
5 Comments

cfyeahbaby, next cforalsex. and soon cfvirtualwomen. go cf8 go.


Aug 31, 2007 at 9:41 AM // reply »
95 Comments

Man, you just got too much time on your hands, he he. Neat example though.


Aug 31, 2007 at 9:48 AM // reply »
211 Comments

Move over Ben Forta, CF8 has a new 'pimp' in town. ;P Anyway, I concur... you have too much time on your hands. :)


Aug 31, 2007 at 9:56 AM // reply »
11,238 Comments

Hey, better in front of a computer than out in a gang, right?


Aug 31, 2007 at 10:21 AM // reply »
92 Comments

Ben...

You should be able to upload your own font and specify that to be used. Great example but...sometimes your mother and I worry about you.

:)


Aug 31, 2007 at 10:28 AM // reply »
11,238 Comments

@Andy,

I don't have that kind of access to the server :( But regardless, I should try to work some kind of magic with whatever font they have, just so I can get the algorithm down.

And don't worry about me - I don't plan to even use a computer this weekend :)


Aug 31, 2007 at 10:47 AM // reply »
92 Comments

You can't even upload a font? With Image.cfc, you simply upload a font to any directory for which you have permissions, then pass in the path to the font. Couldn't be easier.


Aug 31, 2007 at 11:14 AM // reply »
11,238 Comments

@Andy,

I think the font needs to be the system folder? To be honest, I am not sure how exactly the fonts are read in for ColdFusion. If it has anything to do with the install of system files or CF Admin, I don't have access to that stuff.


Aug 31, 2007 at 12:53 PM // reply »
17 Comments

how do you delete a word once you put it up there? heaven forbid you should make a mistake in your composition, but still...


Aug 31, 2007 at 1:00 PM // reply »
11,238 Comments

@Michael,

Good question. I just drag it off the canvas. It is still "there", but it just won't show. I was trying to figure out how to do that. I might add a Key Capture feature (for delete) or maybe make a "Hot Area" for drag and drop delete (ie. Drop over bottom right corner to delete).


ck
Sep 3, 2007 at 4:53 AM // reply »
1 Comments

For fonts you can copy them on the server at any place and if you have access to administrator, you can add them through font management.

The fonts that you add are considered as user fonts and should get preference over system fonts.The only difference I think is that they will not be a part of any fall back algo.


Sep 4, 2007 at 7:24 AM // reply »
11,238 Comments

@CK,

When you say:

copy them on the server at any place

.. What do you mean? Copy them where? Do you mean I can reference the fonts from any folder?


Sep 20, 2007 at 4:52 AM // reply »
1 Comments

By the way, ecstacy is spelt "ecstasy"


Sep 20, 2007 at 7:14 AM // reply »
11,238 Comments

Yeah, spelling is certainly not my strong point :) Thanks for pointing that out.


Jan 9, 2008 at 3:47 AM // reply »
4 Comments

Althought,i can not understand some parts of the article,thanks for sharing.


abi
Apr 23, 2008 at 2:27 PM // reply »
2 Comments

Where to download the interface jquery files needed for this to work?


Apr 23, 2008 at 2:48 PM // reply »
11,238 Comments

@Abi,

Try http://www.jquery.com.


abi
Apr 23, 2008 at 3:16 PM // reply »
2 Comments

I was able to download jquery-1.2.3.min.js from there but this example seems to be using two different js files. (jquery-1.1.4.pack.js, interface.drag-drop.js) & i couldn't find any downloadable links for these two?


Apr 23, 2008 at 3:25 PM // reply »
11,238 Comments

@Abi,

You can just grab the ones from my demo if you want:

http://www.cf8testing.com/demo/magnetic_poetry/jquery-1.1.4.pack.js

http://www.cf8testing.com/demo/magnetic_poetry/interface.drag-drop.js

Enjoy.


Jul 2, 2008 at 3:38 PM // reply »
1 Comments

Do you have a solution for the ghosting issue in IE? As you say, in FF it works great, but for some reason IE seems to be afraid of ghosts... ;)


Jul 2, 2008 at 3:39 PM // reply »
11,238 Comments

@Dave,

I have not found a solution for this.


Jan 2, 2009 at 12:00 AM // reply »
1 Comments

This is nice, have you re-written it for the latest version of jquery?

Adrian


Jun 18, 2009 at 9:19 PM // reply »
1 Comments

I tried watching the live demo, but looks like is not working...do you have another site where we could see this?
Thanks
Carlo


Jun 19, 2009 at 7:02 PM // reply »
11,238 Comments

@Carlo,

Sorry, the CF8 beta account closed a long time ago. You can now see it here:

http://www.bennadel.com/resources/cf8testing/demo/magnetic_poetry/


Mar 16, 2010 at 8:54 AM // reply »
1 Comments

ive demo, but looks like is not working...do you have another site where we could see this?


Mar 17, 2010 at 9:59 AM // reply »
11,238 Comments

@yatakta,

All the CF8 testing stuff has been moved here:

http://www.bennadel.com/resources/cf8testing/


Jun 4, 2010 at 9:40 AM // reply »
13 Comments

Ben,

Can I save the coordinates of each poetry item on the drop event as I drop it on on the canvas or as I generate the image? I am trying t make each item or word clickable once the locations are saved.

Thanks
Kevin


Jun 7, 2010 at 9:20 PM // reply »
11,238 Comments

@Kevin,

Yeah, you should be able to. The drag-drop utility, I think, has a stop-event that you can add an event listener to when the piece is stopped. At that point, you can check the position of it.


Jun 7, 2010 at 9:59 PM // reply »
13 Comments

I am already on it... If I can get this to work I will like I hope, I will show you what I did with your code.

Thanks for sharing your code.


Jun 7, 2010 at 10:02 PM // reply »
11,238 Comments

@Kevin,

Oh very cool. Keep us updated.


Dec 6, 2011 at 12:43 PM // reply »
8 Comments

@Ben,

Is there not a way to make this save using Canvas / Javascript alone?

I understand the point was to save to CF8...
But I believe you can export to a PNG BASE64 URI using Javascript and save yourself the server processing?

I'm trying to figure out how to do that...
Any idea?

Sincerely,
Josh


Sam
Dec 12, 2011 at 8:47 AM // reply »
1 Comments

Great article. Recently, I have also experimented with magnetic words on the web. Took the word "Happy New Year" and translated into 64 languages. People can drag the words around to rearrange it along with others in real-time. This is at http://iwander.org.

Sam



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 19, 2013 at 2:31 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
It's funny really just how well that image describes the way I would imagine most people that go with angular for some project is. I have had a similar roller-coaster ride with it as well, but not qu ... read »
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools