Pass params between forms in the same view RoR

I have two forms in the same view a form_tag and form_for . The first ( form_tag ) use it to make a live search of a node ( parent node ) . The second ( form_for ) use it to create a node ( child node ) . To be clearer , each node has a variable ( parent_id ) pointing to another node ( the parent node ) .

My problem is that when I create the child node (with form_for ) do not know how to assign the value parent_id , because I do not know how to pass the value from one form to another

new.html.erb

<%= form_tag ({controller: "nodes", action: "search"}), :id => "users_search" do %>
  <%= text_field_tag :search, params[:search], :autocomplete => 'off' %>
  <div id='users'>
    <%= render 'users' %>
  </div>
<% end %>

<%=form_for @node do |f| %>
  <%= f.hidden_field :parent_id, :value => @nodo_padre %>
  <%= f.hidden_field :user_id, :value => current_user.id  %>
  <%= f.hidden_field :ocuped, :value => true %>
  <%= f.text_field :custom_node_name %>
  <%= f.check_box :terms_of_service,{}, true,false %>
  <%= f.submit "Pagar", class: "button postfix" %>
<% end %>

_users.html.erb

<% if not @parent.nil? %>
  <% @parent.each do |u| %>
    <%= u.user.email %>
    <%= hidden_field_tag @nodo_padre , u.id %> ...... i think...
<% end %>

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"nz7hu0sBrv49b2AY/Rw0C6NAK8dNo4ra7YkM5VAL0q+0D9yFsa5/pO3bOOuuXxx+K04MP5dZHNOJzanDToYOmw==",
 "node"=>{"parent_id"=>"",
 "user_id"=>"4",
 "ocuped"=>"true",
 "custom_node_name"=>"Mi primera red",
 "terms_of_service"=>"true"},
 "commit"=>"Pagar"}

nodes_controller.rb

def new
@node = Node.new   
end

def search
@node = Node.new  
@parent = Node.search(params[:search]).where(:ocuped => true)

if not @users.nil?
  if @users.count == 1
    @node_incomplete = @users.nodes.where(" sons < ? AND ocuped = ?",2,true).first
  else
    @node_incomplete = @users.first.nodes.where(" sons < ? AND ocuped = ?",2,true).first
  end
  @son_of_incompleted_node = @node_incomplete.children
end

respond_to do |format|
  format.html
  format.js { render }
end
end

def create
@node = Node.new(node_params)
@node.parent_id = @parent.id
respond_to do |format|
  if @node.save
    format.html { redirect_to @node, notice: 'Node was successfully created.' }
    format.json { render :show, status: :created, location: @node }
  else
    format.html { render :new }
    format.json { render json: @node.errors, status: :unprocessable_entity }
  end
end
end

Upvotes: 3

Views: 446

Answers (1)

Pascal
Pascal

Reputation: 8646

It does not matter how you build your forms (form_for, form_tag, simple_form_for...). This will all result in a <form> in the rendered html template. Those forms they "live" on the client side (browser). If you submit a form, then only the form elements (elements like <input>, <textarea>, <select>) are submited to the server.

It's not valid to nest <form> tags, that is you must not have a <form> tag inside another <form> tag. It is valid though to have multiple <form> tags on single page.

When you want to share information between <form> elements, then you can use Javascript to "transfer" the value from one <form> to another.

Say you want to know the parent node id when the second form is submitted:

  • register a change listener on the parent node id element in the first form
  • on change, read the value, write it to a hidden field on the second form

Assuming you use jQuery: you might find this useful: https://api.jquery.com/change/

Or you can set the parent node id to the hidden field when it's selected in the live search.

In any case: unless it is present in the <form> it won't be submitted to the server. So the solution is to use a hidden field.

Upvotes: 1

Related Questions