rails content_for rendering content twice - ruby-on-rails

I use fields_for as so:
<%= f.fields_for :task_comments, #task_category.task_comments do |task_comment_builder| %>
<%= render 'field', f: task_comment_builder %>
<% end %>
My fields partial contains the following:
<% content_for :dynamic_field do %>
<%= f.text_field :comment %>
<% end %>
<%= render 'shared/dynamic_field' %>
dynamic_field partial contains this:
<div class="field-border">
<%= yield :dynamic_field %>
</div>
What happens is if there are 3 task comments, instead of displaying the comment field once for each task_comment, it displays the comment field twice for each task_comment.
What might I be doing wrong?

Rather than using content_for, I decided to use render layout, which does the job:
<%= f.fields_for :task_comments, #task_category.task_comments do |task_comment_builder| %>
<%= dynamic_fields task_comment_builder do |f| %>
<%= render 'field', f:f %>
<% end %>
<% end %>
# application_helper.rb
def dynamic_fields(f, options = {}, &block)
options[:id] ||= "#{f.object.class.name.underscore}_#{f.object.object_id}"
render layout: "shared/dynamic_fields", locals: {f: f, options: options}, &block
end
# shared/_dynamic_fields.html.erb
<div class="field-border">
<%= link_to(raw('<i class="glyphicon glyphicon-remove"></i>'), '#', class: 'btn btn-danger remove-field', style: "float: right;") %>
<div style="clear: both; padding-top: 3px;">
<%= yield f %>
</div>
</div>

Related

How to change the content of rendered layout in rails?

Have to render the form that already exist in the project inside the page, but with a different title
app/views/welcome
<div class="form-wrapper>
<%= render 'form/form_variants/register_1', register: #register %>
</div>
-----------
app/views/form/form_variants/register_1
<%= form_for register.user, as: :user, url: register_path(service: params[:service]), method: :post %>
<%= content_tag :div, class: html_class('simpleFormHeading') do %>
<%= content_tag :h1, t('signup.title_register') %> #title that should be changed
<%= content_tag :p, raw(t('login.account_login.text', login_link: login_link)) %>
<% end %>
#a lot of inputs
<% end%>
Thanks in advance for your reply!
I would pass it as another variable to the partial
<div class="form-wrapper>
<%= render 'form/form_variants/register_1', register: #register, signup_title = 'whatever' %>
</div>
# app/views/form/form_variants/register_1
# optional: init signup_title to a default value depending on your needs
<% signup_title ||= t('signup.title_register') %>
<%= content_tag :h1, signup_title %>

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?
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.
I think you will have to pass index variable to your controller action as hidden_field and then display it on create.js.erb
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.hidden_field :index, value: index %>
<%= f.text_area :content, class: "form-control", id: "communication_content#{index}" %>
<%= f.submit("New Communication") %>
<% end %>
communications_controller
def create
#index = params[:communication][:index]
...
end
Communications/create.js.erb
$('#communication_pane<%= #index %>').prepend('<%= escape_javascript(render #communications) %>');

Rails 5: Nil error in the first argument of a form

I'm quite new with rails so excuse my ignorance.
I have an homepage with a view of astronomic observations and I want to put in the same page the view of the outings that the observatory organize.
Since I can't append two views in the same page I tryed to pass the second view as a partial but I get an error
First argument in form cannot contain nil or be empty
So I though it was a problem of variables and tryed to pass the local variable of the partial but nothing changed.
So how do I pass a variable of #outing to the partial outings/_index.html.erb which will be visualized in the view of observative_sessions
I defined #outing=Outing.new in outings_controller which is the controller for the view outings
In app > views > observative_sessions I have the index.html.erb with
<div class="panel panel-default" id = "observative_sessions">
...
</div>
<%= render 'outings/index', :outings => #outing %>
In app > views > outings I put an _index.html.erb
<%= render 'outings/new_modal' %>
<div class="panel panel-default">
...
<tbody>
<% #outings.each do |outing| %>
...
<% end %>
</tbody>
The _new_modal.html.erb calls the _form.html.erb
<%= render 'outings/form' %>
And then the form
<%= bootstrap_form_for #outing do |f| %>
<%= f.date_field :day, label: 'Giorno:' %>
<%= f.text_field :location, label: 'Luogo:' %>
<%= f.time_field :time, label: 'Ora:' %>
<%= f.submit 'Aggiorna' %>
<% end %>
I get the error in the first line of the form with #outing.
If I put the view in a page alone everything work but not with the partial.
So what did I do wrong?
Thank you in advance for all the help.
In app > views > observative_sessions I have the index.html.erb with
<div class="panel panel-default" id = "observative_sessions">
...
</div>
<%= render partial: 'outings/index', locals: {outing: #outing} %>
In app > views > outings I put an _index.html.erb
<%= render partial: 'outings/new_modal',locals: {outing: outing} %>
<div class="panel panel-default">
...
<tbody>
<% #outings.each do |outing| %>
...
<% end %>
</tbody>
The _new_modal.html.erb calls the _form.html.erb
<%= render partial: 'outings/form', locals: {outing: outing} %>
Then in your form use the local outing variable:
<%= bootstrap_form_for outing do |f| %>
<%= f.date_field :day, label: 'Giorno:' %>
<%= f.text_field :location, label: 'Luogo:' %>
<%= f.time_field :time, label: 'Ora:' %>
<%= f.submit 'Aggiorna' %>
<% end %>
You need to pass #outing variable to all forms those are using #outing variable.
Change the line of rendering _new_modal.html.erb partial like this
<%= render 'outings/new_modal', outing: outings %>
Then change the line of rendering _form.html.erb like this
<%= render 'outings/form', outing: outing %>
And finally change the actual form like this
<%= bootstrap_form_for outing do |f| %>
<%= f.date_field :day, label: 'Giorno:' %>
<%= f.text_field :location, label: 'Luogo:' %>
<%= f.time_field :time, label: 'Ora:' %>
<%= f.submit 'Aggiorna' %>
<% end %>

(Ruby on Rails) Trying To Edit A Post Using Partials But Having Problems

I'm making a bloglike application. I want to make it so that blog posts are editable if clicked.
This is my partial that displays all the posts of a user and makes them clickable
<% if #feed_items.any? %>
<% #feed_items.in_groups_of(3, false).each do |feeds| %>
<div class="row">
<% feeds.each do |feed| %>
<div class="col-md-4">
<ol class="posts">
<%= link_to edit_post_path(feed) do %>
<%= render feed %>
<% end %>
</ol>
</div>
<% end %>
</div>
<% end %>
<% end %>
This is the Edit view that it redirects to when a post is clicked:
<% if logged_in? %>
<div class="row">
<%= render 'shared/post_form' %>
</div>
<% end %>
And this is the '_post_form' partial which is the layout for an editable post:
<%= form_for(#post) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new post..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
When I click a post to edit it it does redirect however it gives me the error: "First argument in form cannot contain nil or be empty"
Any suggestions on how to resolve this?
In your controller's edit method you have to set #post like,
def edit
#post = Post.find(params[:id])
end

How to hide the form elements if the field is empty in ruby on rails?

I am using OpenStruct form for in my view like the following,
<%= form_for(OpenStruct.new(params[:f]), as: :f, url: product_types_path, method: :get, remote: true, html: {class: 'type'}) do |f| %>
<div class="field">
<%= f.label :product_type_id %>
<%= foreign_key(f, :product_type_id, Asset::Product::Type) %>
</div>
<% end %>
I want to hide the other form elements if product_type_id is nil or blank or empty?
I tried this,
<% unless product_type_id.blank? %>
<div class="field">
<%= render 'form' %>
</div>
<% else %>
<p>Select Product Type</p>
<% end %>
So if I got it right what you want to do is not to render the form if what you received with the param product_type_id is blank.
Is it possible for you to instatiate the variable in the controller instead of defining it directly in the form builder?
For instance in your controller:
def index
#product_type = OpenStruct.new(params[:f])
end
and in your view:
<% unless #product_type.product_type_id.blank? %>
<div class="field">
<%= render 'form', product_type: #product_type %>
</div>
<% else %>
<p>Select Product Type</p>
<% end %>
and finally your partial:
<%= form_for(product_type), as: :f, url: product_types_path, method: :get, remote: true, html: {class: 'type'}) do |f| %>
<div class="field">
<%= f.label :product_type_id %>
<%= foreign_key(f, :product_type_id, Asset::Product::Type) %>
</div>
<% end %>

Resources