Add section to form by rendering a partial when li

2019-06-23 17:57发布

问题:

UPDATE 3:

For anyone who reads this, this is why it wasn't working as expected in update 2 below: Passing a local variable to a partial that is rendered after the view has already loaded

If anyone knows how to solve that issue, let me know please.

UPDATE 2:

I updated the javascript with the quotation marks and it partially works...in the sense that the javascript is now functional and it will cause a string of text to appear on the page when I click the link as long as I have the partial only contain a string of text. However, when the partial includes the form fields code, something goes wrong.

If I just paste the following render code directly into the form in the new.html.erb view, it produces a new form section properly.

 <%= render "add_round", f: f %>

However, when I try to include similar code in comps_helper.rb and then reference it from the link_to, it does not work:

In comps_helper.rb:

def addRound(f)
   render "add_round", f: f 
end

In new.html.erb:

 <%= link_to "render it!", addRoundLink_path, remote: true %>
 <div id="some_id"></div>

And I changed addRoundLink.js.erb to:

$("#some_id").html("<%=j addRound(f) %>");  #Is this the correct change to have made here?

Clicking the link_to link does nothing in that case.

Any thoughts?

UPDATED CODE:

Thanks for the reply. I've made the following changes and it still does not appear to be working. The link appears at the bottom of the form but when clicked does not change anything. What am I missing?

routes.rb:

resources :comps
match '/new_competition', :to => "comps#new" 
get "/addRoundLink" => "comps#addRoundLink", :as => :addRoundLink   

Note: I included the other 2 lines related to "comps" just in case those would cause an issue.

comps_controller.rb:

def addRoundLink
  respond_to do |format|
    format.js
  end   
end

comps_helper.rb:

def addRound
  render "add_round"
end   

addRoundLink.js.erb:

$("#some_id").html(<%=j addRound %>);

comps/new.html.erb:

<%= link_to "render it!", addRoundLink_path, remote: true %>
<div id="some_id"></div>

Thanks.

ORIGINAL QUESTION

First off, I'm new to rails. I've read and tried many solutions to similar questions but nothing has worked so far.

I created a form with rails form_for and fields_for. The form creates a new competition (comp). The competition has many rounds. The top half of the form (the form_for section) accepts the details about the competition as inputs and the bottom half of the form accepts details about each round (the fields_for section). The form works perfectly in this basic format.

I took all the code that is in the fields_for section and put it into a partial. My plan was to then create a "add new round" link to the bottom of the form that would simply display the partial above the link each time the link is pressed. This would add a new section to the form for a new round and allow the user to input as many rounds as they'd like. This is the part that I am struggling to make work.

I added this code to my comps_helper:

def addNewRound
   render "add_round"
end

This renders the file /views/comps/_add_round.html.erb.

My question is: how do I get this to render in the form when a link is clicked. As far as I can get with the research I have done is:

<%= link_to "Add new round", { }, :remote => true %>

I don't exactly know what is supposed to go in the {} that will execute the addNewRound method. And I don't know what, if anything, I need to add to my comps_controller file.

Thanks so much for the help.

回答1:

You have to create an action in your controller

app/controllers/some_controller.rb

def hello
  respond_to do |format|
    format.js
  end
end

and define a route to this action.

routes.rb

get "/hello" => "some#hello", :as => :hello

then create a link to this action like that:

<%= link_to "render it!", hello_path, remote: true %>
<div id="some_id"></div>

When you click this link it will find its way to your action and respond with js(javascript) because we told action to respond with only js.

At the end render the partial to anywhere you want in your view(*in this example to the some_id div*)

app/views/some/hello.js.erb

$("#some_id").html("<%=j addNewRound %>");

WARNING: Creating dynamic forms is a pain. You will face a lot of problems (like setting different ids for new form elements etc...). I highly recommend you to use ryan bates nested_form gem