On Blur Save with JRails In Place Editing
I’ve been working on a Rails app recently where I used the excellent jrails_in_place_editing plugin to create a large number of in-place editing textfields. I used this in lieu of the Rails plugin because I removed Prototype completely from my app. I’m prone to do this because jQuery is so clearly better than Prototype. Please, Rails Core, replace this? I usually do this using the JRails plugin because it has all the built-in helpers written for jQuery — beautiful!
In any case, the jrails_in_place_editing plugin is quite wonderful, but limited in terms of the number of features it actually implements. The jQuery plugin it is based on has a load of more configurable features. I added in a few back for my needs, but there’s one basic functionality I was surprised to find missing: on-blur saving. Brandy suggested I needed this in my project, and I have to say she was very right — it makes editing a lot of fields so much easier for power users.
Doing this is very simple. All you need to do is add the following to /public/javascripts/jquery.inplace.js:
//ON BLUR SAVE functionality
original_element.children("form").children(".inplace_field").blur(function(){
//put the original background color in
original_element.css("background", settings.bg_out);
var new_html = jQuery(this).parent().children(0).val();
//set saving message
if(settings.saving_image != ""){
var saving_message = '<img src="' + settings.saving_image + '" alt="Saving..." />';
} else {
var saving_message = settings.saving_text;
}
//place the saving text/image in the original element
original_element.html(saving_message);
if(settings.params != ""){
settings.params = "&" + settings.params;
}
if(settings.callback) {
html = settings.callback(original_element.attr("id"), new_html, original_html, settings.params);
editing = false;
click_count = 0;
if (html) {
// put the newly updated info into the original element
original_element.html(html || new_html);
} else {
// failure; put original back
alert("Failed to save value: " + new_html);
original_element.html(original_html);
}
} else if (settings.value_required && new_html == "") {
editing = false;
click_count = 0;
original_element.html(original_html);
alert("Error: You must enter a value to save this field");
} else {
jQuery.ajax({
url: settings.url,
type: "POST",
data: settings.update_value + '=' + new_html + '&' + settings.element_id + '=' +
original_element.attr("id") + settings.params +
'&' + settings.original_html + '=' + original_html,
dataType: "html",
complete: function(request){
editing = false;
click_count = 0;
},
success: function(html){
// if the text returned by the server is empty,
// put a marker as text in the original element
var new_text = html || settings.default_text;
// put the newly updated info into the original element
original_element.html(new_text);
if (settings.success) settings.success(html, original_element);
},
error: function(request) {
original_element.html(original_html);
if (settings.error) settings.error(request, original_element);
}
});
}
return false;
});
Of course, if you use cacheing you’ll want to delete all.js and let Rails re-cache with the reflected changes. This code worked like a dream for me — hope it helps you too!