Rails in place editing plugin w/ selection

No Gravatar

As of Rails 2.0 the in_place_editor methods have been moved into a plugin. You can download this plugin here. For some items I needed to have a dropdown selection instead of a text field. To add this functionality, I added two methods to the plugin.

Here is the full contents of ‘in_place_macros_helper.rb’ http://pastie.caboo.se/169443

Replace the contents of this file:
“your_app/vendor/plugins/in_place_editing/lib/in_place_macros_helper.rb”

Controller Usage:
in_place_edit_for :object, :method

#example_controller.rb

class MyController < ApplicationController

in_place_edit_for :user, :theme_color

end

Inserting this in the top of you controller automatically creates a method that update the object and returns the updated value as text to the browser.

View Usage:
in_place_editor_select_field :object, ‘method‘, {tag_options},{:collection => “[array]“, scriptaculous_options}

#example_view.html.erb

<label for=”user_theme_color_1_in_place_editor”>Theme Color:</label>

<%= in_place_editor_select_field :user, ‘theme_color’, {},{:collection => “[[ 1 , 'Red' ], [ 2 , 'Green' ], [ 3 , 'Blue' ]]”} %>

<br />

UPDATE: Get the new code for the plugin from the pasties link above
*These methods require the prototype and scriptaculous libraries so be sure to include them in your views.

Tags: , , , , ,

Related posts

  • Your post is very timely. I grabbed your code and am using it in one of my projects that I had punted on in_place_editing on. The formatting is a little honked in your code snippets, though. Here is my understanding of the cleaned up code:
    http://pastie.caboo.se/169298

    I get the select to show when I click on the value, but when I save it I get the RJS error where it prints the JS text to the screen.

    Did I miss something that still needs to be reformatted in the code?

    Thanks
  • What does your controller and view code look like, and what are you trying to get as a response. The default response is the current value of the method that is inserted back into the field that was edited.
  • OK. I got it. Here's the deal. In addition to this extension to the in_place_edit, I am also using a custom_in_place_editing (http://www.pluitsolutions.com/2007/03/20/custom...) s.t. the validation error messages appear in an alert.

    I also had textboxes with the in place edit barfing the RJS at me, so I was thinking that somewhere through the layers of additional customization something was off.

    Yes and No. I was leaving something out from the in_place_edit that is kind of important for "edge rails" -- this originally came out with a 1.x version of rails. The :script => true bit is important. Doh!

    The other thing that was amiss is that this does not seem to work with the custom_in_place_editing, but it doesn't need to. The validations (at least in MY model) are irrelevant because you can only select one of the choices. There is no need for them to be unique, so there are no additional validations. So for that one field I have just the in_place_edit for in the controller. I issue that after I loop through the content fields to issue the in_place_edit_with_validation_for.

    I have enough hooks in this now that I may just post my own blog entry on how I have mine all tied together.

    Thanks again for the extension to the in_place_edit.
  • gth
    Hello! In spite of the including the full content of ‘in_place_macros_helper.rb’ I still get the error about invalid authenticity token. Does somebody know what may be the reason?
  • I have updated this page. Please get the new code for the plugin from the pasties link at the top. I was having issue with wordpress garbling large blocks of code. But I know the code from the pastie works.
  • Martin
    Hi Do you have an example site showing this working for a select box?
  • Andrew P
    I'm using this for a bulk edit form, with associations, and i've had to make the following change at like 20.
    replace
    @item.update_attribute(attribute, params[:value])
    with
    begin
    @item.update_attribute(attribute, params[:value])
    rescue
    @item.update_attribute("#{attribute}_id", params[:value])
    end

    then call the in place edit with the association type ('type' rather than 'type_id')

    Also, from your assoc model, you can add the following


    def self.model_for_inplace_select
    "[" + Model.find(:all).collect{ |t| "[#{t.id},'#{t.name}']" }.join(',') + "]"
    end

    which you can then call to generate the select options.

    Thanks for the extension!
  • Andrew P
    Sorry, to clarify my last comment, you need to make the change on line 20 of the in_place_editing.rb file (found in the lib directory of the plugin)

    If anyone has a faster/more efficient way to find out if the attribute is a relationship, please do tell.
  • Martin
    Is it possible to use this on a select where you can add a new item
  • It's just a wrapper for the scriptaculous in place collection editor, which I don't believe will let you add options. If you are looking for an alternative with more features, I suggest trying the dojo inline editor. See my dojo_helper plugin for more information.
  • Reach
    I had some trouble using this with a collection local in a partial. There's no way to get an instance to the internal InstanceTag, and InstanceTag.object tries to find an object by using instance_variable_get(). What I wanted was to use the selector for each item in a collection, rendered in a partial. But the partial loop variable is a local, not an instance variable, so the InstanceTag ends up with a nil object.

    The only workaround I found was to tweak the code to let me pass an instance to in_place_editor_select_field explicitly. Is there a better way?

    (Also, it's useful to have in_place_collection_editor forward the :value option, which it doesn't currently.)

    Overall though, this saved me some time. Thanks for putting it together.
  • Cynthia
    I think I am missing a couple of things here. First, any change you could update your example to take the collection from a variable? I am trying to use your InPlaceCollectionEditor to update a foreign key. It works pretty well if my collection is a string litteral in the view file. But when I try to create a variable to hold that data, I can't get the quoting right to have it interpreted as an array of arrays in JavaScript.

    This works:
    "[[1, 'People'], [2, 'Animals']]"} %>

    This is the closest I come:
    @categories} %>

    but @categories gets flattened into 1People2Animals if I use the bare @categories. If I try quoting it in any way, I just end up with the litteral @categories.

    My other problem is I can't figure out how to display "Animals" but pass 2. Is there a way to do this? I have tried altering the code in in_place_editor_select_field but no luck. I am wondering if instead, I need to create a custom in_place_edit_for method for foreign key fields - since that is where the display value for the clickable field is created.
  • Cynthia:
    From what I understand, this is something like what you would want to do:

    #item_controller

    #This would provide you with @categories = [[1, "People"],[2, "Animals"]]
    @categories = Category.find(:all, :select => "id, name").map {|c| [c.id, c.name] }

    #item_view
    < %= in_place_editor_select_field :item, ‘category’, {},{:collection => @categories.inspect } %>

    Hope This helps
  • Cynthia
    Sorry that some of my previous comment disappeared - I should have thought to escape my html-ish tags.

    @categories.inspect worked perfectly. Thanks!

    About my second issue - the id being displayed rather than the name - is that how your code behaves? From my reading of the source code, the value displayed before the drop down appears is controlled by in_place_edit_for (in in_place_editing.rb) Did you have to make any changes in that function to display "Red" rather than 1 - and yet still have the select form pass 1 to the set_user_theme_color method? If I am reading that method correctly, I would have to create different setter methods depending on whether my collection for the select options is an array or an array of arrays (that is, is just values or key,value pairs). Is that true?
  • Cynthia:
    The array is a set of value key pairs i.e. [[value, "key"], [value, "key"]]
    I could be wrong about the order, if the value is getting displayed then swap the position of values and keys, then the key should get displayed and the value will get submitted.
  • Cynthia
    I guess my question was unclear. I am not having any trouble with the select options - nor with the actual editing. Thanks so much for publishing your code - it works perfectly.

    What I am struggling with is that my select is for editing a foreign key field. So rather than displaying the value from the database (e.g. 2), I want to display the name of the other object represented by the id 2. If I were really clever, I might be able to extend in_place_edit_for to deal with both a case where I want to display the value OR the case where I want to show an attribute from the associated model. But I concluded it was easier to create a separate method to deal with updates representing foreign keys. I have things sort of working - except I have not found the correct place to edit to get the initial display value I want. But once I have edited, the code here returns the name of the foreign object rather than the foreign key: http://pastie.org/253838

    Note that that code also contains edits I use to have in_place_edits respect validates. And additions so that there can be a default value if the field is initially empty. This still isn't completely done - the initial value still shows up as the id. But I'll update my pastie when I figure that out.
  • Cynthia,
    I believe I understand what your problem is now. Unfortunately, I am in the middle of moving and don't have the time to patch the plugin. If your up to it, I suggest modifying the in_place_edit_field by adding a value parameter, so that you can override the default value. Eventually I plan to setup a github fork to make things a little smoother. But until then, good luck.
  • Les
    Did anyone get this part of the plugin working?

    The entry I'm displaying the in_place_editor_select_field on, has a related gallery, which is stored as gallery_id in the entry table.

    I'm passing in the entry and gallery id, as per the instructions, but it's only showing the id, and not the name of the related gallery:

    in_place_editor_select_field :entry, 'gallery_id', {},{:collection => @galleries_collection.inspect}

    If anyone has a fix for this I'd be very appreciative!
  • Les
    Hi Cynthia

    I don't know if you're still working with this, but for anyone else, I worked out how to pass the related item in as a string and display it properly.

    Use your awesome pastie code, then apply the following: http://pastie.org/364828 and you should be good to go.

    Unfortunately it doesn't pre-select the current item in the dropdown, but what the heck, it's a minor UI thing that most users won't notice.
  • Ferit
    Thanks for the extension!
  • Nathan Feger
    I have switched to this particular plugin as I need validation associated with my in place editing. However, I found a problem, whereby I am sometimes getting multiple errors returned from my model.

    I modified in_place_editing.rb::in_place_edit_for method's failure case to this:
    errors = ' ' + @item.errors.on(attribute)
    if @item.errors.on(attribute).respond_to?(:join)
    errors = @item.errors.on(attribute).join("\n")
    end

    display_value = attribute.to_s.humanize + ' ' + errors || 'Oooops!'

    I also plan to jigger the response to allow the resultant text to be displayed somewhere other than the existing span, however, I have not figured that out yet.
blog comments powered by Disqus