jQuery Edit In Place (JEIP)
History
A few years back I wrote a Javascript library for editing content in place, that was based on Prototype. It was modeled after the Flickr UI/approach. Nothing amazing, but it worked well enough.
Fast forward a few years and the momentum in the Javascript library field has moved decidedly to jQuery. I’ve been meaning to write a port of the edit in place code to use jQuery, and now I finally have. To help confusion with the original code I’m calling it jQuery Edit In Place, or JEIP for short.
Downloads
Current Version: 0.1.2 (Change Log)
Download: jeip.js
Demo
I’ve put together a very basic demo. Everything is done with templates and CSS classes, so if you don’t like the default look of the demo there are lots of methods for changing it.
Examples
Here’s the most basic example, it enables in line editing for the page element that has an id of content.
$( "#content" ).eip( "save.php" );
After editing is complete and the user clicks on the save button the script sends the url, form_type, element id, original value and new value data via HTTP post to save.php. The returned data is expected to be in JSON object, with the following values: is_error, error_text and html. The is_error field is a boolean, and error_text is used to provide information about the error condition. The html is a string that is used to replace the contents of the edited element.
If you’ve got a larger chunk of text to edit you’ll want to use a textarea form:
$( "#content" ).eip( "save.php", {
form_type: "textarea"
} );
And for those cases where you just need to provide options, there’s an easy way to do a select form:
$( "#content" ).eip( "save.php", {
form_type: "select",
select_options: {
blue : "Blue",
green : "Green",
red : "Red",
black : "Black",
brown : "Brown",
white : "White"
}
} );
For select forms two additional bits of data are passed to the save URL: the original option text and the new option text.
The eip function will also work on multiple elments, so if you select a class it will make all of the elements with that class editable:
$( ".edit-class" ).eip( "save.php" );
The Save XHR and Response
When the edit form is saved JEIP uses the jQuery AJAX function to send data to the save URL. It send the following fields via HTTP POST:
- url – (string) URL that the edit form was on.
- form_type – (string) The type of edit form that was used (text, textarea, select)
- id – (string) The id of the DOM element that was edited.
- orig_value – (string) The original value of the DOM element that was edited.
- new_value – (string) The new value of the DOM element that was edited.
- data – (object) Optional additional data that was passed along via the original eip call.
For select form edits two additional fields are sent:
- orig_option_text – (string) The original option display text.
- new_option_text – (string) The new option display text.
The response to the XHR needs to be a JSON object with three values:
- is_error – (bool) When true indicates that there was some sort of error when the save URL processed the XHR. Under normal conditions this should be set to false.
- error_text – (string) When is_error is true, this string is used to provide a plain text descriptive of what the error was.
- html – (string) This string is used to replace the old value of the edited DOM element.
Options
There are a number of options that can be provided as part of the second parameter in the eip function. The defaults should fit for most, but if you want to tweak things I’ve tried to provide lots knobs.
- save_on_enter – (bool) When true the save event is triggered when the enter key is pressed. Doesn’t apply for textarea edits.
- cancel_on_esc – (bool) When true the cancel event is triggered when the escape key is pressed.
- focus_edit – (bool) When true give the edit field focus when the edit form is shown.
- select_text – (bool) When true select the text in the edit field.
- edit_event – (string – event) What type of event (usually click or dblclick) to trigger the edit mode.
- select_options – (object) Key/value pairs for the option fields in a select form. The key will be used as the option value and the value from the option will be used as the display option text.
- data – (object) Additional data that will be passed in the XHR to the save URL.
- form_type – (string) What type of edit form to use: text, textarea and select. The default is text.
- size – (int) Value to use for the size attribute on the edit field. By default this is calculated at run time.
- max_size – (int) Maximum value to allow when calculating the size value.
- rows – (int) Value to use for the rows attribute in textarea edit forms. By default this is calculated at run time.
- max_rows – (int) Maximum value to allow when calculating the rows value.
- cols – (int) Value to use for the cols attribute in the textarea edit forms.
- savebutton_text – (string) Text to use on the save button.
- savebutton_class – (string – CSS class) CSS class to use on the save button. The default value is jeip-savebutton.
- cancelbutton_text – (string) Text to use the on the cancel button.
- cancelbutton_class – (string – CSS class) CSS class to use on the cancel button. The default value is jeip-cancelbutton.
- mouseover_class – (string – CSS class) CSS class to apply when the mouse enters an element that is editable. The default value is jeip-mouseover.
- editor_class – (string – CSS class) CSS class to apply to the edit form wrapper. The default value is jeip-editor.
- editfield_class – (string – CSS class) CSS class used on the edit field element. The default value is jeip-editfield.
- saving_text – (string) Text shown while the XHR is waiting for a response. The default value is ‘Saving …’.
- saving_class – (string – CSS class) CSS class used on the saving_text string. The default value is jeip-saving.
- saving – (string – template) Template string used to show the saving_text string.
- start_form – (string – template) Template string used to start the edit form.
- form_buttons – (string – template) Template string used to show the form buttons.
- stop_form – (string – template) Template string used to end the edit form.
- text_form – (string – template) Template string used to show the text edit forms.
- textarea_form – (string – template) Template string used to show the textarea edit forms.
- start_select_form – (string – template) Template string used to start a select edit form.
- select_option_form – (string – template) Template string used to show options elements in select edit forms.
- stop_select_form – (string – template) Template string used to edit a select edit form.
- after_save – (function) Function that is called after the XHR completes. By default it just flashes the element a few times.
- on_error – (function) Function that is called when the save URL returns an error (by setting is_error to true in the return JSON object). By default it calls the alert() function to show the error_text returned from the XHR.

Wonderful! I’d love to take a look at an example save.php, as well – this is exactly what I’ve been looking for!!!
Sure, the save.php file is pretty basic: http://josephscott.org/projects/code/javascript/jeip/example/save.phps
How can I add an onBlur function that cancel the form??
P.S.: Sorry for my bad english
Don’t worry, already done it adding inside “_editMode” funcion:
$( “#edit-” + self.id ).blur( function( e ) {
_cancelEdit( self );
} );
P.S.: I almost forgot to congratulate you for the script… it’s just great.
Hmmm, perhaps I should make than an option. I would probably default that feature to being disabled though, I think many would find having their edit field disappear because they clicked somewhere else more frustrating than helpful.
Great plug-in! I was actually just looking for something like this a couple of weeks ago, but the only solution I could find was quite specialized and wouldn’t fit my needs. I’m glad I did another quick search today and came across your work :)
Just as an aside, I was wondering if there is an easy way to trigger an edit from an event tied to another element. For example, have a button beside the editable field that says ‘Edit’ and have it trigger the edit when clicked.
Thanks again for contributing your work!
There’s nothing currently to trigger editing one element by clicking on another. I may add something like that in a future version.
Thanks for the quick response!
Hi!
Seems like a wonderful jQuery plugin…
I’ll try to implement it in my project :)
just one question – is it possible to implement it without the AJAX save feature?
I only want to use it to change text fields, and handle the save myself submitting the whole page
Thanks for your work!
There’s no way to do that currently. Honestly this plugin would probably be total overkill for that kind of use.
Great plugin! But, I’ve written a local application, that doesn’t care anything about send data to a server, but only saving on the local machine. Can this plugin be adapted to this scenario?
How does your app save data locally? I’d imagine if there’s a Javascript interface to where you are storing data (like Google Gears) then you could adapt the code to send updates there instead.
Thanks for the useful script. I’m trying to implement it in a WordPress blog so that I can make post and page edits on-the-fly. Seems like everything is working though it doesn’t save. Instead, it says “Saving…” then the text vanishes. I assume it’s the JSON.php which I fetched from the PEAR site. Could you make JSON.php example available for a look over?
Thanks!!
The JSON.php file from PEAR is used to encode the returning data in JSON. The file that accepts the XHR in the examples is save.php. Here’s a link to that:
http://josephscott.org/projects/code/javascript/jeip/example/save.phps
[...] plugin that does exactly as the title says. You can edit content in place and save it as well. JEIP is now in version 0.1.2, you can download it from its official website (you can find information about how to save data through XHR) and view a demo as well. Spread [...]
Is it possible to handle the case that the editable div is empty? For now, I could not edit at all.
Thanks.
I don’t think the current version deals with the empty element situation, I’ll see about support for that.
I want to use your inline routine to edit a label under a thumbnail from a set of thumbnails on a horizontal filmstrip, update the page to show the new entry, then send that new entry to a database to update for later viewing. I do not have access to run .PHP on the system I am with. I can use C# and JavaScript. Does your routine offer the ability to run a function instead of running the SAVE.PHP file?
It just sends the data to a URL, so you can use any server side language, PHP just happens to be the one I used. The response needs to be JSON encoded, which isn’t specific to a particular language either. I suspect most languages have a library for encoding/decoding data in JSON.
Thanks for your great work on this plug-in. Was wondering, how can I specify a string which will be displayed for the empty string? Something like “Click Here to Edit”.
There’s not currently a way to do empty strings, I need to fix that in a future version.
just a quick question I’m hoping you can help me out with…I have everything set up as seen on this site…everything seems to be working except that the data doesn’t get switched…it just stays on the “saving…” part and only if I refresh does it show the new data in its place…not sure if its the JSON file that isn’t properly functioning or if there is something else I’m missing…do I need PEAR running to use the JSON file?
I love the plugin…just hoping I can get it to work…
First thing I’d do is debug on the server side and make sure that your script is getting the data correctly. If that then look at the response you script is sending back and make sure that it looks correct.
k…well I got it figured…
Thank you soooo much for this awesome plugin…
I can’t understand when I try this on my own server, when I click save, the icon gif displays, but it never disappears and saves the text that I just typed! Help?
Sorry for lack of explanation…I mean to say… the data does not save.
Two things to look at when debugging this, first make sure that your script is getting the request and the correct data. If that’s working then make sure that your script is returning the correct data, JSON encoded, etc.
Hi, How would i make use of this if I had multiple divs that needed this, yet only calling it once, ie…
data
data
data
I would think i would have jeip call from the class and use the id to reference the div. Is this functionality in place now?
These are created using jquery and are inserted on the fly and are coming from the database on page load.
Thanks,
-TOM
The last comment diddn’t show my full message
ie…
div id=”div_1″
div id=”div_2″
div id=”div_3″
There’s already an example on this page that shows how to do this, using a class:
$( “.edit-class” ).eip( “save.php” );
How could I pass additional data to eip from within the editing div. Lets say I have a extra attribute like this
div extra=”home” I need to pass something like this so that only a section in the database where page = home is updated.
Thanks
To send additional data when the save event happens take a look at the ‘data’ option. This doesn’t gather up attributes from the element, but it does allow you send what arbitrary data as part of the save XHR.
I’m trying to use the ‘data’ option, but I’m having trouble getting it to respond. I’m putting the values into data in key/value pairs:
data: {key : 'value'}and I’m trying to read it in my php with:
$var = $_POST['key'];Is this not the structure I should use?
Go back and take a look at the documentation on this page, under the section indicating what fields are sent in the XHR. The ‘data’ field is called ‘data’ in the POST.
Ok, I think I’ve solved my problem. I ended up using this jquery-json plugin, which I then modified my lines to look like this:
data: $.toJSON({key1:"value1", key2:"value2"})and
$data = json_decode(stripslashes($_POST['data']));This places it into a PHP object of $data->key1. If you do the following line it will place it into an array of $data['key1']:
$data = json_decode(stripslashes($_POST['data']), true);Wanted to thank you for an EXCELLENT plug-in. It came highly recommended, and has not disappointed.
I’m trying to implement some client side validation prior to transmitting the new value, and potentially triggering an alert box if it fails.
Is this something that has been addressed or considered?
Strike my last comment, the is_error option in the JSON results already create an alert.
What more could someone ask for? Thanks again.
Using the is_error works, just note that it it’s client side at that point since the data has already been transmitted.
Would it be possible to show how to add custom input types? I am looking to attach the jquery datepicker to a text field containing a date value. In other words, when the text field is clicked on, the jquery date picker will show to select a date which will then fill the text field.
I hadn’t really thought about it that way, but you could probably do that by overriding the default form templates. Take a look at the ‘text_form’ variable, it’s the template that’s used when editing a simple string. You can override it when calling .eip() on your element and provide the datapicker hooks inside the form.
Let me know how that works out, would make an interesting example for others who want to do something similar.
I was able to add a new datepick_form to the jeip.js, and hooked it in from a separate js file.
I am now struggling to bind the datepicker jquery function to the text field created by jeip.js.
For example, i may have a field (id=’field_A’) and when jeip is called, it replaces it with id=’edit-field_A’. Since the new field is not created until that point, what do you recommend I do to bind the datepicker function to that new field after its creation by jeip.js?
This is day 2 for me playing with jquery, so I apologize for the questions and if I am not being clear.
My guess is you’ll need a way to re-bind the datepicker code to the id/class of the form field because it’s added dynamically to the page later on. The other possibility is that the datepicker code needs to watch for new fragments being added to the page to see if it needs to bind events to them. Don’t know if there’s anything other that supports that right now.
What the mostly likely leaves us with is having to adding something to JEIP that can optionally call user defined functions after each editing event.
I managed to get a date picker field working and figured I would pass on the info if you wished to add it. Plus it might prove useful for others looking to dynamically add/bind functions to jeip.
In this example I used jquery datepicker and livequery to get it working as intended.
In my javascript that is called as part of the document.ready loading I used live query to bind to a new class. Example:
$(”.jeip-datefield”)
.livequery(function(){
$( this ).datepicker({ showOn: ‘both’ });
});
In my javascript that binds jeip to my fields I wish to edit, I forced it to use a new form_type. Example:
$( “#datefield” ).eip( “save.php”, {
form_type: “datepick”
});
In jeip.js I changed the following:
1. Added a new class:
editdate_class : “jeip-datefield”,
2. Added a new form template:
datepick_form : ‘ ‘
3. Added a new form field:
if( opt.form_type == ‘datepick’ ) {
form += _template( opt.datepick_form, {
id : self.id,
editdate_class : opt.editdate_class,
value : value
} );
} // date form
And I think that is it.
I use jquery ajax to query a database and return a form through php. On the success of the ajax response, I call a function that binds eip to the new fields returned from php. The livequery allows me to then trigger the datepicker in the newly inserted fields.
Hope this helps and wasn’t too confusing.
Evan
Yep, livequery was what I was thinking of. At some point I’ll try out the datepicker + jeip with your changes and see where this needs to go.
Hello Joseph
Have you implemented this functionality in latest update?
If yes,where can I find that.
I need the same functionality.
Thanks
Ashish
Thanks for all the great information. We use JQuery and PHP on the custom web pages for our customers.
Excellent script!
I’m a jQuery newbie but loving it already!
I needed to restrict text field length to X characters, and obvious way to do it is to burn it into code
text_form : ‘ ‘,
How can I make maxlenght=”250″ a setting?
Also, there is a class “missing” in
form_buttons : ‘…
I added
and with
.jeip_buttons {
position: relative;
float: left;
margin: -50px 0px 0px 0px;
}
placed buttons above text input.
If you just want to include the maxlength=’250′ into the form then I’d suggest including a new form template with the .eip() call.
Ahh, you want to move just the form buttons around with CSS. Sounds reasonable.
Awesome implementation! :-)
Could there be a way to unbind/suspend ‘eip’ from a selector?
It would be nice to enable and disable ‘edit in place’ depending on what else is happening on the page.
Clicking to edit is USUALLY intended, but if I’m moving blocks around a page it interferes. I’d like to have a button that would toggle between the sortable and edit in place functionality. Sortable can be bound and unbound. This looks close…
I’ll look into it some more…
I don’t think there’s anything that will directly support that. Might be an interesting feature to have though.
Get looking script, I am just trying to get around it (This is my first look into javascript really!) This would be perfect for what I need however is it possible to use this if you have variable text items on a page? For example (my data is retrieved dynamically) My PHP displays a list of names of people (which need to be editable) Obviously this list is ever changing. You mentioned above that you could use a .edit-class but then when it comes to updating the data of the MySQL table (your save.php) how would you be able to make sure you update the right table and row as wouldn’t it just pass the value of the first class? Sorry if that doesn’t make sense, I am kind of banging my head together
You need to make sure that there was a unique ID for each element that you are making editable. You could do this by having your PHP script generate a unique ID attribute value for instance.
Chocula: I agree with Joseph. To expand upon his point, on the server side, I would put the table and row id (or a suitable mapping), into the class or id.
Examples:
class=”edit-class students” id=”1234″
It would take some fancy javascript to retrieve the info and pass it back to the server, but it’s entirely possible.
class=”edit-class” id=”students_1234″
using .split(’_') on the id, you’ll be able to retrieve both students (table) AND 1234 (id). You should be able to do something similar on the server side, which would probably be better.
Yep, that would work because the element ID is always part of the data sent with the save request.
Great Script- thanks heaps
How can I have a simple link to activate the edit, for example:
TEXT TO EDITClick here to Edit
I want to edit the text inside the span “text-edit” from the link “link2Edit”. Thanks.
I’ve implemented the alternative edit-in-place plugin called ‘Jeditable’ (http://www.appelsiini.net/projects/jeditable) but because it lacks some basic features (like hover effect) I decided to drop it and look around for a similar plugin. Now I’ve bumped into JEIP and I wonder what the advantages are over Jeditable. Joseph, did you look into that plugin? If so, what are your findings?
I didn’t look at other jQuery edit in place plugins, I just wanted to make a jQuery version of the original Protoype.js based code that I wrote.
Do the save and cancel button HAVE to be under the text box, or can then come after the textbox (like in your drop down box example)
You can move them around any way you want. The raw HTML is in a template option, you could also tweak it with the CSS as well.
What I’m trying to do is click a button (say, an edit button) and all the fields a certain class become editable and automatically go to their editable state.. so, in other words, I have a table, I want to click Edit on the side of a row and all the columns in that row become editable immediately (not once you mouseover the individual text in that column and click it). Is this possible?
Certainly possible, though there’s no specific code to do that in one action in jeip.
Exactly what I want to do. I have several elements I’d like to make editable by clicking one button. Then, I’d like to have one Save/Cancel button for all. I would also like the option to bypass submitting to server, and use my own form “save” button to submit all at once when I’m done editing several objects. Anyone know of anything that does this?
There’s nothing in the code that directly supports this. I suspect you could use jeip as the core of this and build on top of it to make this type of thing possible.
I would love to be able to do that. Now I just have to learn javascript ;-).
Hey, this is an amazing script and I thank you for it greatly.
There’s just one thing that I can’t quite get to work, and that is viewing the edited content right away.
The way I have it working, is I put some logic into the save.php to update a mysql database. And it works.
However, I need to manually refresh the page after editing to view the changes made.
I believe a similar problem was posted above on December 5th. The edited area just remains stuck on “Saving…” until I manually refresh. And if I keep clicking save, it creates a string of “Saving…Saving…Saving…” and cancel just shows the initial value as well, even though it actually has been changed in my database.
I’m pretty new to this stuff, so please bare with me :P
Thanks,
Alex
Double check to make sure that your script is returning the properly formatted JSON response. I suspect that if the Saving… never goes away then the reply for the XHR either didn’t happen or it didn’t get back what it expected to.
Thanks for the reply Joseph.
After some toiling about and learning more about XHRs I wondered how to put the value I needed into the JSON response. I then re-read the instructions at the top of this page and realized that I needed to put the response into the html = “” at the bottom of save.php. I replaced the “” with $new_value and it works perfectly now :) (though there is a bit of a delay that I wonder if I can shorten…but that might be server lag.)
Oh, and just looking through JEIP.js I stumbled across something on line 67 that might be a typo. In the class for the start_select_form it is: editfield_clas which might need that second s. :)
Again, huge thanks :)
Alex
You’re right, definitely a typo there. I’ll fix that and make sure it gets into the next version. Guess I’ll need to make a next version one of these days then :-)
Hi Joseph,
This is very useful stuff.
I just wanted to know if its possible to validate my component before ajax request is sent to the server. I mean to say i want to check on the client side if the the text is empty or not and prevent from sending data to the server if the text is empty.
There’s nothing in there that specifically supports that at this point.
IS THERE NO SUPPORT FOR EMPTY STRING (like click here to edit) ?? Very Bad…
Yeah, I need to update it, specially since the original Prototype version had it.
Hi Joseph!
Thanks for this awesome plugin! I’m currently considering using it to allow a user to update particular sections of a single page by wrapping certain content in editable divs which change to textboxes on click, which I assume jeip will do.
I’m wondering: If I have more than one of these editable areas on the page, is there a way I can disable all of the other areas while the current one is clicked so that a user can only edit one at a time, and then re-enable all of them again on a submit of the current area?
Much thanks, sir!
There’s not a ‘disable’ option in the current code. That would be an interesting addition though.
Nice job. Looks great. I managed to get it happening only to find it won’t work with my repeating regions. About the third time I’ve found this problem.
So I have a php loop that brings a value in for multiple records in the database and I want to be able to edit each one of these using this. It seems only the first field will be editable. Anyone have any thoughts why?
Thanks
Do you have an example page the demonstrates the problem?
Joseph,
Thanks for the reply. Here is the example of your script deployed on a repeating region. The first item in the list works. Editing that is. I haven’t linked to the back end yet. Do you think it’s possible to have it function in lists?
http://reconarcade.com.au/testing/jqueryedittest.php
Just call jeip on a class that is shared among all of the fields you want to edit. IDs are unique to just one element on a page.
I’m such a noob sometimes. Thanks. Great work.
I thought I would pass on where I am at with it.
The class call works fine except for one thing. There is an issue at least in firefox when you press on another item in the list after choosing one to edit. They start to disspear.
http://www.reconarcade.com.au/testing/jqueryedittest.php
Being such a noob, I wouldn’t hesitate to guess how to turn off that.
I think you’ve got something else odd on that page then. There’s no problem doing multiple edits on the demo page: http://josephscott.org/projects/code/javascript/jeip/example/
Hello there!
this is a great plugin… i was wondering where do i get JSON.php?
Current versions of PHP ( > 5.2.0 ) come with json encoded/decode functions. If you don’t have those available then JSON.php is available from PEAR: http://pear.php.net/package/Services_JSON.