I have a span
element that I want to become editable upon double-click. (That is, the user can edit the text and it will save when s/he clicks outside.)
I found this nice jQuery plugin: "X-editable In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery" http://vitalets.github.com/x-editable/
I found many answers to be out of date on this topic, but adamb's was the easiest solution for me, thank you.
However, his solution was bugged to fire multiple times due to not removing the keypress event along with the element.
Here's the updated plugin using $.on()
instead of $.bind()
and with the keypress event handler being removed when the element is created again.
$.fn.extend({
editable: function() {
var that = this,
$edittextbox = $('<input type="text"></input>').css('min-width', that.width()),
submitChanges = function() {
that.html($edittextbox.val());
that.show();
that.trigger('editsubmit', [that.html()]);
$(document).off('click', submitChanges);
$edittextbox.detach();
},
tempVal;
$edittextbox.click(function(event) {
event.stopPropagation();
});
that.dblclick(function(e) {
tempVal = that.html();
$edittextbox.val(tempVal).insertBefore(that).off("keypress").on('keypress', function(e) {
if ($(this).val() !== '') {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) {
submitChanges();
}
}
});
that.hide();
$(document).one("click", submitChanges);
});
return that;
}
});
http://jsfiddle.net/Hbww2/142/
If you want a solution that works in ALL modern browsers, here's a nifty little jQuery plugin I made that emulates the functionality you described:
SIMPLY DROP THIS BLOCK INTO YOUR CODE-BASE:
//plugin to make any element text editable
//http://stackoverflow.com/a/13866517/2343
$.fn.extend({
editable: function() {
var that = this,
$edittextbox = $('<input type="text"></input>').css('min-width', that.width()),
submitChanges = function() {
that.html($edittextbox.val());
that.show();
that.trigger('editsubmit', [that.html()]);
$(document).unbind('click', submitChanges);
$edittextbox.detach();
},
tempVal;
$edittextbox.click(function(event) {
event.stopPropagation();
});
that.dblclick(function(e) {
tempVal = that.html();
$edittextbox.val(tempVal).insertBefore(that).bind('keypress', function(e) {
if ($(this).val() !== '') {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) {
submitChanges();
}
}
});
that.hide();
$(document).click(submitChanges);
});
return that;
}
});
Now you can make any element editable simply by calling .editable() on a jQuery selector object, like so:
$('#YOURELEMENT').editable();
To get the changes after the user submits them, bind to the "editsubmit" event, like so:
$('#YOURELEMENT').editable().bind('editsubmit', function(event, val) {});
//The val param is the content that's being submitted.
Here's a fiddle demo: http://jsfiddle.net/adamb/Hbww2/
Now tested, and does work (at least Firefox 8 and Chromium 14 on Ubuntu 11.04):
$('span').bind('dblclick',
function(){
$(this).attr('contentEditable',true);
});
JS Fiddle demo.
Edited in response to Randomblue's comment (below):
...how do I detect when the user clicks outside the span, so that I can set attr('contentEditable', false)
Just append the blur()
method:
$('span').bind('dblclick', function() {
$(this).attr('contentEditable', true);
}).blur(
function() {
$(this).attr('contentEditable', false);
});
JS Fiddle demo.
The above works: I've tested it in this jsfiddle: http://jsfiddle.net/nXXkw/
Also, to remove the editability when user clicks off of the element, include:
$('span').bind('blur',function(){
$(this).attr('contentEditable',false);
});