One of the nice features in Rails is the in_place_editor_field view helper which wraps script.aculo.us's Ajax.InPlaceEditor and displays your model attributes in a nice ajaxy editor. However a major problem with it is that when the attribute is blank the editor effectively disappears and you are not able to set a value for it through the browser.
This seemed like a common problem but I wasn't able to find a nice solution to it after 20 minutes of googling. There were some kludgy fixes that required poor interface design on the web page, adding special handling code to my models [shudder], or else hacking the script.aculo.us code. What I wanted was for blank values to be replaced with a series of blank spaces (which would then give the user something to click on). It took a bit of poking around in the rails source, but I was able to pull it off by over-riding some of the default behavior. Here it is.
file RAILS_ROOT/lib/extensions.rb:
class Extensions
ActionView::Helpers::JavaScriptMacrosHelper.class_eval do
def in_place_editor_field(object, method, tag_options = {}, in_place_editor_options = {})
tag = ::ActionView::Helpers::InstanceTag.new(object, method, self)
tag.nil_content_replacement = in_place_editor_options[:nil_content_replacement] || 'Unknown'
tag_options = {:tag => "span", :id => "#{object}_#{method}_#{tag.object.id}_in_place_editor", :class => "in_place_editor_field"}.merge!(tag_options)
in_place_editor_options[:url] = in_place_editor_options[:url] || url_for({ :action => "set_#{object}_#{method}", :id => tag.object.id })
tag.to_content_tag(tag_options.delete(:tag), tag_options) +
in_place_editor(tag_options[:id], in_place_editor_options)
end
end
ActionView::Helpers::InstanceTag.class_eval do
attr_writer :nil_content_replacement
def value
unless object.nil?
v = object.send(@method_name)
if @nil_content_replacement.nil?
return v
else
(v.nil? || v.to_s.strip=='') ? @nil_content_replacement : v
end
end
end
end
end
And put this line at the end of RAILS_ROOT/config/environment.rb:
require 'extensions'









It works perfectly. You should submit this to the dev team!
Posted by: Matteo Vaccari | 2006.09.11 at 04:55 AM
This solution worked well, sans one issue. When using in_place_edit_for any field whose value was cleared by the edit would no longer be editable. So, I cracked open the code and made use of the (unused) options parameter to pass in a value to be used when the update results in an empty value. The new parameter is :empty_text. Here's the code:
ActionController::Macros::InPlaceEditing::ClassMethods.class_eval do
def in_place_edit_for(object, attribute, options = {})
define_method("set_#{object}_#{attribute}") do
@item = object.to_s.camelize.constantize.find(params[:id])
@item.update_attribute(attribute, params[:value])
display_value = params[:value].empty? && options[:empty_text] ? options[:empty_text] : @item.send(attribute)
render :text => display_value
end
end
end
Posted by: jfoxny | 2006.10.26 at 11:12 AM
I am also trying to do this in_place_edit and have also found that after it is blanked and updated the field becomes unclickable. I tried jfoxny code but couldn't get it to work. jfoxny can you post an example of it being used... or where you placed this snippet also inside extensions.rb?
Julian (not a noob, but not an expert either)
Posted by: Julian Guppy | 2006.11.29 at 03:42 PM
Hey Julian, I am sure you figured this out, but for others, like myself, who did not "get" what to do with jfoxny's addition right off the bat, all you need to do is add the :empty_text parameter to the in_place_edit_for call in your controller...
class UsersController '...'
end
His snippet also lives within the extension class. I hope this helps... only a month late :)
Posted by: rjb | 2006.12.28 at 05:57 PM
this code no longer works with rails 1.2.2...does anyone have a patch?
Posted by: deezzer | 2007.02.25 at 11:20 PM
For 1.2.2
ActionView::Helpers::InstanceTag.class_eval do
attr_writer :nil_content_replacement
def value(object)
unless object.nil?
v = object.send(@method_name)
if @nil_content_replacement.nil?
return v
else
(v.nil? || v.to_s.strip=='') ? @nil_content_replacement : v
end
end
end
end
Posted by: Cussen | 2007.02.26 at 08:34 PM
Does not work for me, i get following error:
wrong number of arguments (1 for 0)
Extracted source (around line #87):
...
87:
...
#{RAILS_ROOT}/lib/extensions.rb:16:in `in_place_editor_field'
in extensions.rb i have at this line:
tag.to_content_tag(tag_options.delete(:tag), tag_options) +
Same if I change this line to:
tag.to_content_tag(tag_options.delete(:tag), tag_options) + in_place_editor(tag_options[:id], in_place_editor_options)
or
tag.to_content_tag(tag_options.delete(:tag), tag_options)
What could be the problem?
Posted by: mkezys | 2007.03.08 at 04:33 PM
mkezys: I had the same problem. Turns out the implementation of value() in the post is incorrect. It should be
def value(object)
not
def value
Cussen's comment above has it defined correctly. That's why you get the "wrong number of args" error
Posted by: joe | 2008.02.27 at 01:30 PM
Nothing suggested in this thread worked for me (Rails 2.0.2) but after much hair-pulling, I had an AHA! moment. I put a bit of CSS at the top of my template:
.in_place_editor_field:after {
content: url(/images/edit_entry_12.png)
}
Basically, CSS dynamically inserts the a small image into the , giving you something to click on when the is otherwise empty. You can also use "content:'some text'" instead of an image, but that looks ugly.
Posted by: doppler | 2008.04.22 at 02:12 PM