jQuery Photo Tagger Plugin For Flickr-Style Photo Tagging

Posted February 4, 2010 at 10:21 AM

Tags: ColdFusion, Javascript / DHTML

A few days ago, I programmed a little proof-of-concept for Flickr-style photo tagging using jQuery. I did it as an exploration in mouse-based event binding; but, it was a lot of fun and I wanted to see if I could take it a step further. So, yesterday and this morning, I packaged the jQuery code up into a jQuery plugin (phototagger.jquery.js), build a light-weight ColdFusion persistence layer (drop-and-run, no database required), and turned it into an official project: jQuery Photo Tagger.

 
 
 
 
 
 
jQuery Photo Tagger Plugin Video Demo. 
 
 
 

Watch the online video here.

Try the online demo here (NOTE: Hold CTRL key when clicking mouse to create hotspot).

View the official project page here.

There's way too much code to show here - the jQuery plugin comes in at about 1,000 lines of code. As such, you can either check out the project page or try the online demo for yourself. For now, I'm just going to show you the HTML that actually sets up and invokes the Photo Tagger jQuery plugin:

  • <!DOCTYPE HTML>
  • <html>
  • <head>
  • <title>Flickr-Style Photo Tagging With jQuery And ColdFusion</title>
  • <style type="text/css">
  •  
  • div.photo-container {
  • float: left ;
  • margin-right: 10px ;
  • }
  •  
  • </style>
  • <script type="text/javascript" src="./jquery-1.4.1.js"></script>
  • <script type="text/javascript" src="./phototagger.jquery.js"></script>
  • <script type="text/javascript">
  •  
  • // When the DOM is ready, initialize the scripts.
  • jQuery(function( $ ){
  •  
  • // Set up the photo tagger.
  • $( "div.photo-container" ).photoTagger({
  •  
  • // The API urls.
  • loadURL: "./load_tags.cfm",
  • saveURL: "./save_Tag.cfm",
  • deleteURL: "./delete_tag.cfm",
  •  
  • // This will allow us to clean the response from
  • // a ColdFusion server.
  • cleanAJAXResponse: function( apiAction, response ){
  • // Check to see if this it the load.
  • if (apiAction == "load"){
  •  
  • // Loop over response array.
  • $.each(
  • response,
  • function( index, tagData ){
  • // Translate the ColdFusion keys
  • // to lowercase. This will create
  • // dupliate keys, but it doesn't
  • // matter for our use-case.
  • $.each(
  • tagData,
  • function( key, value ){
  • tagData[ key.toLowerCase() ] = value;
  • }
  • );
  •  
  • }
  • );
  •  
  • }
  •  
  • // Return cleaned response.
  • return( response );
  • }
  • });
  •  
  • });
  •  
  • </script>
  • </head>
  • <body>
  •  
  • <h1>
  • Flickr-Style Photo Tagging With jQuery And ColdFusion
  • </h1>
  •  
  • <div class="photo-container">
  • <img id="photo1" src="./sexy.jpg" width="520" height="347" />
  • </div>
  •  
  • <div class="photo-container">
  • <img id="photo2" src="./sexy2.jpg" width="520" height="347" />
  • </div>
  •  
  • </body>
  • </html>

I tried to build the jQuery plugin with as much flexibility as I could. There are a large number of default settings that can be overridden globally or on an as-needed basis (as done in the code above). Because the photo tagging life-cycle requires persistence, you do have to provide it with load, save, and delete URLs.

This is probably the most complicated piece of jQuery that I have ever created; as such, writing this was a lot of trial an error. The approach uses a combination of standard jQuery plugin architecture and object oriented programming (OOP). The plugin defines a private controller class and then instantiates a new instance of that controller class to be used for every photo-tagging element on the page. This felt really good to do, but I have not idea how this falls in terms of jQuery plugin best practices.

Right now, it's a bit buggy in IE. IE doesn't seem to like mouse over events on clear background. IE also seems to hate moving the mouse while the CTRL key is pressed. I'll have to do some digging to see if there are ways around this, or if I simply have to find a different approach. At least now that this is an official project, it gives me a place to post my updates in a meaningful manner.

If anyone has any suggestions about this or things that they would like added / changed, please let me know.




Reader Comments

Feb 4, 2010 at 10:45 AM // reply »
4 Comments

It be nice if it was written somewhere you create a tag by holding CTRL and left-click dragging. Didn't figure it out until I read your explanation about IE not liking CTRL + mouse drag. :)

This is largely preference, but in things like tags or tooltips, I like being able to select the text given. Allowing that would open up the possibility to provide links in the tag.

Regardless, very cool project. Thanks for sharing!


Feb 4, 2010 at 10:48 AM // reply »
17 Comments

Very cool!


Feb 4, 2010 at 10:50 AM // reply »
8,777 Comments

@Mike,

Ahh, nice catch. I have added a note next to the demo link. I am not sure what you mean about selecting the text given? Can you explain that more?

@Adam,

Thanks my man :)


Feb 4, 2010 at 11:07 AM // reply »
4 Comments

@Ben,

Sure thing. For example, say you have a photo in which someone's using a specific workout product, and you tag the photo so people know what they're using. Now another user comes by, checks out the photo, and sees the tag. If they want to do a search to find out more about that product, they have to mouse over the tag and write down the name, whereas if they could just select the text, it'd be a lot easier.

It's a really lame example, but hopefully it illustrates the point. :)

Also, any plans to allow HTML into the tags? Maybe an option to enable/disable HTML, along with a list of accepted elements? You could tag a photo with a link to somewhere (product, photo credit, person's profile, etc) that, with selecting text possible, would allow a user to explore the subject further.

Hope these suggestions don't detract from what's already a very cool plugin.


Feb 4, 2010 at 11:09 AM // reply »
1 Comments

Just awesome!


Feb 4, 2010 at 11:18 AM // reply »
17 Comments

For what it's worth, Flickr uses a button on the page to turn on tag creation, and allows simple html elements to be included, like links and strong/em tags.


Feb 4, 2010 at 12:13 PM // reply »
3 Comments

Ben.. you rock! I was actually JUST working on something very similar for our advertising clients to highlight image points they want to specify in the images..this will prove to be a step beyond my attempt.. thank you so very much dude.


Feb 4, 2010 at 12:17 PM // reply »
3 Comments

Great plugin but for Mac users the ctrl key triggers the right-click contextual menu which gets in the way a little. You may need to add the ability for Mac users to use the cmd key instead?


Feb 4, 2010 at 12:46 PM // reply »
1 Comments

It doesn't work in IE, besides that it rocks.


Feb 4, 2010 at 2:31 PM // reply »
8,777 Comments

@Mike,

I think the option to allow for HTML is a good idea; as well is the idea to have a list of "allowed" HTML tags. Very cool.

@Adam,

Hmm. Maybe I need a way to have the creation turned of tag hotspots on / off. Not sure what kind of event would / should trigger that.

@Billy,

Cool man - let me know if you see room for more stuff in this. I have some updates to do to make this more IE-friendly.

@Dave,

If I end up going with a on/off mechanism for the hotspot creation, then this won't be an issue. IE seems to not like the CTRL+mouse-move anyway.

@Stefano,

It sort of works in IE, but not well. As it currently stands, only the border of the box triggers the message. It is definitely junky, though. I'm coming up with ways to improve it.


Feb 6, 2010 at 2:52 PM // reply »
2 Comments

Very cool work Ben. I checked it the other day but I'm on a Mac so it wasn't working quite right as Dave commented. I pulled the code to see what I could do, but then I came back today and see you added the on/off feature.. I like that option, good fix. Worked well in Safari, Chrome, FF, Opera. Can't wait to see what's next..


Feb 6, 2010 at 4:42 PM // reply »
8,777 Comments

@Brian,

Awesome - but just to be clear, are you saying that the newest updates are working for you on the Mac? Or, are you seeing any current bugs?


Feb 6, 2010 at 5:12 PM // reply »
2 Comments

Yes, its working now on my mac now that I don't have to control click to tag because you added the enable/disable. Hope that helps!


Feb 6, 2010 at 5:17 PM // reply »
8,777 Comments

@Brian,

Beautiful :) Thanks for letting me know. If you can think of anything I should add, please let me know.


Feb 8, 2010 at 6:37 AM // reply »
3 Comments

This is cool, but when I try to run it locally I manage to tag the photo but I write the tag I get a pop up window saying "there was a problem with the API"
Will this problem be gone if I will uplod it to the internet?


Feb 8, 2010 at 7:21 AM // reply »
1 Comments

Hi,
thats pretty nice, but I prefer jQuery Annotation Plugin. There's also an ajax PHP version: http://stas.nerd.ro/index.php/read/568


Feb 8, 2010 at 7:54 AM // reply »
8,777 Comments

@Omer,

If you are not running ColdFusion on your local computer, yes, you will get an API error (when the plugin tries to communicate with the server to save the tags).

@Stas,

That looks pretty good, thanks.


Feb 8, 2010 at 9:03 AM // reply »
1 Comments

I found a better Plugin here:
http://jquery-notes.rydygel.de/samples.php


Feb 8, 2010 at 9:07 AM // reply »
8,777 Comments

@Brian,

Dang, that's pretty slick. I can't read what it says, but the plugin looks badass.


Feb 9, 2010 at 12:57 PM // reply »
1 Comments

muchas gracias, me será de gran utilidad.

saludos,
Felipe...


Feb 27, 2010 at 7:30 PM // reply »
1 Comments

Hi Ben,

Your plugin is really neat and videos really help to understand how it's implemented, many thanks. Are you releasing the code under any sort of licence? I have a project where I need to give the admin users a way to tag objects in photos and your code would be a great help.

Thanks again,

Jonathan


Mar 22, 2010 at 8:31 PM // reply »
8,777 Comments

@Jonathan,

Glad you like the videos. I typically release code as-is. If you like it, have at it. Of course, referrals back to this site always make me feel warm and fuzzy inside :)


Mar 28, 2010 at 10:41 AM // reply »
1 Comments

Hi Ben. I love the plugin. However, I have been using it with Jquery UI Dialog, which I use to display images, and fire it up on the click event that show the dialog.

If you fire up the first image, it works, but when you click on subsequent images, the plugins is not fired up at all.

I know this because the _GET request is sent the first time you click on an image, but not on the others. You have to reload the page for it to work again, but it will still work on only one image.

Just to let you know about this issue. Thanks for the plugin! Great work!


Apr 21, 2010 at 10:10 AM // reply »
8,777 Comments

@Ivan,

Yeah, I guess if you are loading the images dynamically, you'd have to apply/re-apply the plugin to each one.


May 1, 2010 at 10:42 AM // reply »
3 Comments

Hi Ben
I am trying to rum it on my server without much success, see here http://pixelme.info/amblog/tagger/
I used the files from the 2010_02_05 pack.

Where did I go wrong?


May 3, 2010 at 9:50 AM // reply »
8,777 Comments

@Omer,

It looks like that page needs a login; perhaps that's the problem? Is it possible the AJAX features are getting hit with a 401 Unauthorized response.


May 3, 2010 at 11:31 AM // reply »
3 Comments

Hej Ben
I tried to upload it to this address: http://pixelme.info/tagger
But then I get a different problem. What is missing there?


Aug 12, 2010 at 5:07 PM // reply »
1 Comments

Ben -

Thanks for your work on this, and sharing it with us. I am integrating it into a client site and am noticing that I can't get the AJAX to 'POST' even though I set it as the default saveMethod. Everytime I save it's doing a GET with the params in the URL.

Any ideas?


Aug 14, 2010 at 11:32 AM // reply »
8,777 Comments

@Noah,

Hmm, that's odd. I just took a look at the code and it should be referring to the default options.



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:

Formatting: <strong>bold</strong> <em>italic<em>







  • Help Wanted - Find Your Next ColdFusion Job
Recent Blog Comments
Sep 3, 2010 at 5:48 AM
Scope Behavior When Using CFThread Inside Of ColdFusion Components
Thanks Ben, Excellent article and very precise explanation. Cheers Philip A question on invoking asynchronous save or some task and returning response back to the calling page. Using cfThread is ... read »
Sep 3, 2010 at 3:04 AM
Long Polling Experiment With jQuery And ColdFusion
@Ben, Thank you for your answer. If you are interested in - I solved the problem. It was, as you said, a buffer issue. Now when I'm getting a new request, the first thing I do is I'm sending some fa ... read »
Sep 3, 2010 at 1:29 AM
Using jQuery's SlideUp() and SlideDown() Methods With Bottom-Positioned Elements
Hey Ben, Thanks for clearing this up! Also, is there a way for the container to be open when you first load the page, so that when u click on the link it will slideUp? ... read »
Sep 3, 2010 at 12:29 AM
Bidirectional Data Exchange With ColdFusion's CFThread Tag
Thanks for posting this example, Ben. I plan to put something like this to use. I want to spawn up a thread to insert several records (possibly 1000s) into a database incrementing a counter upon ea ... read »
Sep 2, 2010 at 11:23 PM
Experimenting With HTML5's Cache Manifest For Offline Web Applications
Hi Ben, having checked all articles on Html5's appCache, is there a solution to just update newer files, using the manifest file? I am looking into using application cache to actually have an offline ... read »
Sep 2, 2010 at 3:11 PM
Long Polling Experiment With jQuery And ColdFusion
@Alex, It looks like some of the browsers implement some sort of buffering on the data request. I was definitely finding different behavior across browsers. I want to come back and figure this code ... read »
Sep 2, 2010 at 3:09 PM
Creating Base64-Encoded Data URLs For Images In ColdFusion
@Randall, At the very least, I think Chrome won't be able to close windows unless it opens them up, right? I am not sure. ... read »
Sep 2, 2010 at 2:17 PM
ColdFusion NumberFormat() Exploration
Ben - I have same question as Jim and I think maybe you misread it? I want numbers with non-zero decimal places to display the decimal, but those that have no decimal to display w/o the decimal poin ... read »