Anar
Anar

Reputation: 925

Rails 3 - Got "Undefined local variable or method `f' " when use ajax to execute remote javascript

I have a question on this: I have a partial named _return_item.html.erb, so I want to render it repeatedly and dynamically.

<%= f.fields_for :return_items, return_item do |item_form| %>
  some_field_input_for_return_item
<%end%>

The index.html.erb is like this:

<%= form_for(@return_request) do |f| %>
  <div id="contact">
    <!-- some_field_input_for_request_contact_info -->
  </div>
  <div id="itemlist">
    <!-- This part is working-->

    <% @return_request.return_items.each do |item| %>
      <%= render :partial => "return_items/return_items", :locals => {:f => f, :return_item => item}%>
      <!-- I_want_to_append_the_partial_here -->
    <%end%>

  </div>
  <%= button_tag("Add New Item", :class=>"addItem" )%>
<%end%>

<script>
  $(document).ready( function () {
    $( '.addItem' ).click(function () {
      $.ajax({
        url: "return_requests/request_new_item",
        data: {
               item_num: ($( '#itemlist' ).children().length)
              },
        dataType: "script"
      })
      return false;
    });
  });
</script>

The request_new_item controller is like this:

def request_new_item
  @return_item = ReturnItem.new 
end

and here is request_new_item.js.erb :

 $("#itemlist").append('<%= j render :partial => "return_items/return_items", :locals => {:f => f, :return_item => item } %>');

When I press the button addItem, I expect to generate a new partial, but actually, this doesn't work. The console provide an error:

 ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x007f5a302232b0>:0x007f5a380afea8>)

UPDATE: I forgot to post the model: return_request.rb:

class ReturnRequest < ActiveRecord::Base
    has_many :return_items, :class_name=>'ReturnItem', :foreign_key=>'RMA_Nmb', :primary_key=>'RMA_Nmb'
    accepts_nested_attributes_for :return_items
end

return_item.rb:

class ReturnItem < ActiveRecord::Base
  belongs_to :return_request, :class_name=>"ReturnRequest"
end

So, could anybody explain me how this happen, and how can I fix this? Thanks

Upvotes: 0

Views: 2088

Answers (2)

Anar
Anar

Reputation: 925

So I have solved this question,using some other way, as @Yanhao said. The reason it reports undefined local variable or method f because I put the javascript snippet outside the form_for block. It is certain that I can not locate f and item. I followed @Yanhao's suggestion and use append which is provide by jquery to implement the dynamical effect: First, I put the <script> tag inside the form_for so it can locate the f and for the variable item. I just use the following code:

$(document).ready( function () {
    $( '.addItem' ).click(function () {

       $("#accordion").append('<%= j render :partial => "return_items/return_items", :locals => {:f => f, :return_item => @return_request.return_items.build }%>');

      return false;
    });
  });

this code is work perfect to me. Thanks again for the help.

Upvotes: 0

Yanhao
Yanhao

Reputation: 5294

In index.html.erb, the variable f is passed into the block, but in request_new_item.js.erb, where can f come? It is really undefined in that erb.

I think the browser doesn't have to request that piece of HTML from server. Instead, it can just duplicate the existing partial and append it. To make it easy to duplicate, you can wrap the partial in _return_item.html.erb with a DIV. You may need to adjust some names of fields in the partial before appending it.

The gem called "nested_form" could be a choice too.

Upvotes: 1

Related Questions