Topic: Ajax form with in_place_editor_fields

I have a simple Ajax form working in my application.  It simply provides a 2 field Ajax form (Expense description + Expense amount) with a submit button, and two partials (one for the form, and another for the rendered list).  When the submit button is clicked, the item description and amount are rendered as two columns in a single row above the form, with a yellow highlight for the last entered item.

I am now trying to modify the code to add in-place-editing to each of the rendered rows, but keep running into problems.  I am a Ruby and Rails newbie, so I don't know if what I am trying to do is supportable in Rails 1.2.3.  I have searched here and elsewhere and have not found a post addressing this subject, so I am posting it in hopes of finding out if this is doable, and perhaps some pointers on how to accomplish it.

Here is the current working code:

View (in app/views/users/show.rhtml):

<div id="monthy_expenses">
    <h3>Monthly Expenses</h3>
    <table id="expenses">
        <tr><th>Description</th><th class="amount">Amount</th></tr>
        <%= render :partial => 'expenses/expense', :collection => @user.expenses %>
    </table>
</div>   

<div id="new_expense_form_for_user">
    <%= render :partial => 'expenses/new' %>
</div>


Partial #1 ("_expense.rhtml", for listing expenses):
<tr id="expense-<%= expense.id %>">
    <td><%=h expense.description %></td>
    <td class="amount"><%=h number_with_precision(expense.amount, 2) %></td>
</tr>

Partial #2 ("_new.rhtml", for rendering data entry form):
<div id="new-expense">
    <h3>Add a recurring monthly expense</h3>
    <% form_remote_for    :expense,
                        Expense.new,
                        :url => hash_for_expenses_url(    :user => @user,
                                                        :action => 'new'
                                                        ),
                        :html => { :id => 'expense-form' } do |f| %>
        <label for="expense_description">Description:</label><br />
        <%= f.text_field 'description', :size => 60 %><br />
       
        <label for="expense_amount">Amount:</label><br />
        <%= f.text_field 'amount', :size => 10 %><br /><br />
       
        <%= submit_tag 'Add Expense' %>
    <% end %>
</div>

RJS template ("new.rjs")
page.insert_html :bottom, 'expenses', :partial => 'expense'
page.visual_effect :highlight, "expense-#{@expense.id}"
page.form.reset 'expense-form'

The above works well and produces output like this:

Monthly Expenses

Description    Amount   
Rent                    2500.00     <---- I would like to make these edit_in_place
utilities              550.00     <---- I would like to make these edit_in_place
Test                      100.00     <---- I would like to make these edit_in_place
Test                     100.00      <---- I would like to make these edit_in_place
test xx           1000.00      <---- I would like to make these edit_in_place

Add a recurring monthly expense

Description:  XXXXXX
Amount:       XXXXXX

[Add Expense]


I modified the code as follows to incorporate in-place-editing, but it doesn't work:

In Controller:

# Setup in-place-editing for expense fields
in_place_edit_for   :expense, :description
in_place_edit_for   :expense, :amount

In Partial ("_expense.rhtml"):
<tr id="expense-<%= expense.id %>">
    <td><%=h in_place_editor_field :expense, :description, {}  %></td>
    <td class="amount"><%=h in_place_editor_field :expense, :amount, {}  %></td>
</tr>

I am getting the following error on line 2 of the _expense.rhtml partial

RuntimeError in Users#show

Showing app/views/expenses/_expense.rhtml where line #9 raised:

Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Extracted source (around line #9):

6:  -->
7:
8:     <tr id="expense-<%= expense.id %>">
9:         <td><%= in_place_editor_field :expense, :description %></td>
10:         <td class="amount"><%=h in_place_editor_field :expense, :amount, {}  %></td>
11:     </tr>
Trace of template inclusion: /app/views/users/show.rhtml

I am baffled by the 'nil' error as the partial is called from the show.rhtml view with a collection:

<%= render :partial => 'expenses/expense', :collection => @user.expenses %>

This works just fine in the non-edit-in-place version, so I can't see why it is now resolving to 'nil'.  I tried a number of variations but all resolved to the nil error.  Any thoughts ?

Last edited by Dondi (2007-05-04 15:03:07)

Re: Ajax form with in_place_editor_fields

IIRC in_place_edit_for is expecting an @var class variable.  since you're in a partial and the class variable gets passed through as the name of the partial, it breaks.

try this

<% @expense = expense #for in place editor -%>
<tr id="expense-<%= expense.id %>">
  <td><%=h in_place_editor_field :expense, :description, {}  %></td>
  <td class="amount"><%=h in_place_editor_field :expense, :amount, {}  %></td>
</tr>

there may be better alternatives, but this has worked for me in the past.

Re: Ajax form with in_place_editor_fields

Thanks smoothoperatah!  That did the trick.

Re: Ajax form with in_place_editor_fields

Perfect ... that worked for me too.