7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
  1. Code
  2. Web Development

Create an In-Place Editing System

Scroll to top
Read Time: 13 mins

Making users click through multiple pages just to edit a field is so 1999. In this tutorial, you'll learn how to create an in-place editing system as found on popular sites, such as Flickr.

A word from the Author

With all the buzz around Web 2.0, ease of use is now much more important than ever. Being able to edit some content without having to go to another page is something a lot of users really crave. A lot of big names are already using this pattern to great effect. If you've used Flickr, you've probably seen this in action.

I believe a demo is worth a thousand words. Hit the demo and try it out yourselves.

Today, we are going to look at how to implement this with, you guessed it right, our favorite JavaScript library, jQuery. Interested? Let's get started right away!

Design Goals

Before we start looking at how to implement the functionality, here are a few thoughts about the goals and the resulting decisions.

  • We need to let the user edit the content without leaving the page. This is a given.
  • This should either function as a whole or fail as a whole. When JS is disabled, we don't want to run into weird quirks.
  • The user should know the content is editable. A subtle blue background change should draw the user's attention to this.
  • When dealing with how to trigger the edit there are a few options. We can either let the user edit on a normal click or double click. I've chosen double click since random double clicks occur at a smaller rate than random clicks. Switching it is just a matter of changing the parameter in the bind event.
  • A way for the user to save or discard the edits.
  • Save or edit events can be triggered by 2 ways. Keyboard events or mouse events. I chose mouse events since keyboard events lack specificity.
  • With respect to mouse events, you could use either traditional buttons or usual links. I chose links for no particular reason.
  • The user should be able to resume editing even if he clicks outside of the input box or leaves the page and comes back.
  • Additionally, the user should be able to edit as many fields as possible simultaneously.

Now that we've mapped out our needs we can now move on to how we are going to do this.

Plan of Action

We'll now need to map out what needs to be done in a specific order.

Step 1: We'll need to add a class of editable to each elements which need this functionality.

Step 2: We'll next need to add hovers to each editable item to draw attention to the fact that that item's content is editable. We'll add and remove the hovers using JavaScript instead of CSS. This is mainly done for devices or browsers with JavaScript disabled. We don't want to send them wrong visual cues.

Step 3: When an editable item is double clicked, we need to swap out the contents and replace it with a text box with the old text in it.

Step 4a: When the user wants to save the edits, copy the input's value to the parent element and remove the input box.

Step 4b: Or when the user wants to discard the changes, replace the old content and remove the input box.

These are the basic steps in creating this functionality. Of course there are few other small things but I'll explain them as we go along.

Core Markup

The HTML markup of the demo page looks like so.

As you see, disregarding the boiler plate, we have two unordered lists. Each li element has a class of editable to denote that its content can be edited.

We've also included the jQuery library and our own script file.

CSS Styling

Nothing special here. Just a bunch of code for layout and styling purposes.

Take special note of the editHover and noPad classes. We'll be using them in a bit.

JavaScript Implementation

Now that we have a solid framework and some basic styling in place, we can start coding up the required functionality. Do note that we make extensive use of jQuery. Specifically we'll need at least version 1.3 or higher. Anything less and it won't work.

Adding Hovers


As noted earlier, we'll need to add a subtle blue background to editable objects to signify they are editable. We've already created the editHover class to take care of this.

This tiny snippet takes care of that for us. We use jQuery's hover method to add the editHover class when the element is hovered upon and remove it when it is not. We use this to refer to the specific element that is hovered over. If we had used .editable as the selector instead each and every element will get the class added to it. So we use this to target only the element we need.

Switching out the Elements

First up, we need to make sure our code is executed when the target element is double clicked. So we'll first hook up the handler for this event first.

We attach the replaceHTML function to the double click event relative to the editable element with that one liner. Now we can move on the switching out the elements.

Let's go over our code bit by tiny bit.

I define the functionality inside a separate named function instead of an anonymous function for a specific reason: I'll be using this function more than once. Next, we save the content of the element for future use using jQuery's html method and replacing all quotes since it messes up our output down the line.

Now that our content is safely stored for later use, we can switch out the elements. First we empty out the li element by sending in an empty string to the html method. Next, we insert some standard HTML for an input box. We add some classes to it for styling purposes. More importantly, we set its value attribute to the original text contained by the element stored in oldText. We also add a couple of links to take care of saving and discarding the edits. We've also added classes to them so they can be targeted easily and for styling.

As always, we use this to target the element which triggered the event.

Keeping the Edits

Edited TextEdited TextEdited Text

First up, let me introduce jQuery's live method. You probably haven't seen this much before so I'll give a quick introduction.

You can't hook up handlers to events triggered by elements which are not even present in the DOM when the page and the JavaScript was loaded. If you use normal event binding functions, it'll fail due to the above mentioned reason. The live method takes care of that.

It binds handlers to events irrespective of when the element was created. For more about this, you can go through the official docs.

Lets look into our code now. We first bind the code contained within our anonymous function to the click event. Inside the function we first save the text contained in the input box. This can be a little tricky since the input box doesn't have an ID. So we first look for the form element which happens to be its sibling and then traverse through to find the input element. We then copy its value after replacing all the quotes it may contain.

Next, we obtain the links parent element, the li element and replace its HTML content with the text we copied in the previous step.

This block could have easily been created as a one liner but I chose to split it to 2 lines in the interest of readability.

Discarding the Edits

This is just as simple as it looks. Since the user doesn't want to keep any of the edits. We just replace the HTML content of parent element with the original text we had copied earlier to the oldText variable.

With this the core of our work is done. We just need to do a couple of edits to make sure things don't break when the user does unexpected things.

Binding and Unbinding

If you've tested out our code at this point you'll probably end up with this functionality breaking bug: When a user double clicks in the resulting input box it is now filled with the HTML content of the editing system. Try it yourself. With each double click, the value of the input box reflects by adding another bunch of text to it. This issue will probably be a lot worse if you've chosen click as the trigger event.

To rectify this, we need to unbind the event handler for that specific element alone and rebind them as soon as the user clicks either save or discard. Let's implement that now.

Our previous blocks of code now need to be edited out to so:

We unhook the handler for the element which triggered the event. The rest of the elements with the editable class still have their handlers intact and will respond to events.

Next we attach those handlers back in spite of whether the user chooses to edit them or not. If we don't re-attach these, the fields can be edited only once. The second time they are double clicked, the handlers are no longer attached to the events. We rectify this by hooking the handlers back to the events.

A Few Tweaks

This last bit of code is purely to spruce up the appearance of our effect. If you've noticed, the li has a bit of padding in place to make the text within look better. But when the text is stripped out and replaced by a text box we result looks ugly and breaks the effect. We want the text box to take up exactly the same space the original text took. With this in mind, we add a noPad class to the element when it has been double clicked and removed again when the user saves or discards the edit.

We unhook the handler for the element which triggered the event. The rest of the elements with the editable class still have their handlers intact and will respond to events.

The Complete Code

Here is how the complete code looks like:

Not bad. Fifty odd lines to add some spiffy new functionality.

Taking it One Step Further: The Backend

In the interest of not making it too long, I've stuck to creating the client side functionality alone. If you want to implement this functionality within your own projects, its implicitly assumed that you'd need a back-end system in place to save these changes and more importantly, you'd need an AJAX request for making this call asynchronously.

Adding this functionality should be a cinch but do make a note of this. The code above was created just to illustrate this pattern and not for production use. So I've abstained from adding additional IDs attributes to elements and name attributes to text boxes. In your production code, do add all of them so the text box's name attribute can be set meaningfully and in such a way the back end can recognize which piece of data needs to be updated.

To add an AJAX request, our save handler would have to be updated to so:

Remember, for the back-end to make any sense of what you are sending to it, you need some additional data along with the updated text so the app knows which data to edit. You could easily send in more than one piece of data to the script if you need to.


And there you have it; how to add a user friendly functionality to your projects. Hopefully you've found this tutorial interesting and this has been useful to you. Feel free to reuse this code elsewhere in your projects and chime in here if you are running into difficulties.

Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.