ruby-on-railsajaxruby-on-rails-5partial-viewsrenderpartial

Rails - How to access index value in partial


I am trying to use the built-in rails ajax to append an item to a list after a user fills out a form - However, I cannot target the div tag to append the new entry to: ActionView::Template::Error (undefined local variable or method 'index'

Clients/Index:

<% @clients.each_with_index do |client, index| %> 
  <div id="communication_pane<%= index %>">
    <%= render client.communications.order(created_at: :desc) %>
  </div>

  <%= form_for([@clientlist, client, client.communications.build], remote: true) do |f| %>
  <%= f.text_area :content, class: "form-control", id: "communication_content#{index}" %>
  <%= f.submit("New Communication") %>
<% end %>

Communications/create.js.erb:

$('#communication_pane<%= index %>').prepend('<%= escape_javascript(render @communications) %>');

How can you access the index value from Clients/Index?


Solution

  • In your create.js.erb, there is an undefined variable index at $('#communication_pane<%= index %>')
    Because there is no way the server knows about where you clicked on the client so that you have to explicitly tell the server about it. Here is an idea:

    <!-- app/views/clients/index.html.erb -->
    <% @clients.each_with_index do |client, index| %> 
      <div id="communication_pane<%= index %>">
        <%= render client.communications.order(created_at: :desc) %>
      </div>
    
      <%= form_for([@clientlist, client, client.communications.build], remote: true) do |f| %>
        <%= f.text_area :content, class: "form-control", id: "communication_content#{index}" %>
        <!-- Letting server know the index of current form by adding a param -->
        <%= hidden_field_tag :client_index, index %>
        <%= f.submit("New Communication") %>
      <% end %>
    <% end %>
    

    Then at your js.erb file, use params[:client_index] instead of index

    # app/views/communications/create.js.erb
    $('#communication_pane<%= params[:client_index] %>')
      .prepend('<%= escape_javascript(render @communications) %>');
    

    Hope this help.