in the following code, I want to assign a different label to the text field for each iteration.
<%= f.field_for :skills do |s| %>
<li>
<label>Skills</label>
<%= s.text_field :name %>
</li>
<% end %>
How can I do that?
Here is my controller code, where I create three different skill objects:
def edit
3.times{resource.skills.build}
render_with_scope :edit
end
You could do something like this:
<% counter = 0 %>
<%= f.fields_for :skills do |s| %>
<li>
<%= s.label :name, "Skill #{counter}" %>
<%= s.text_field :name %>
<% counter = counter + 1 %>
</li>
<% end %>
It is preferred to use s.label :name, since that will make sure when you click the label, the text-box will get the focus. But the value of the label can be overruled, as i did here.
I am not quite sure what else you could mean with changing the label for each item, so if you could make that clearer.
Hope this helps.
Just scope the label to s:
<%= f.field_for :skills do |s| %>
<li>
<%= s.label :name, 'Skills' %>
<%= s.text_field :name %>
</li>
<% end %>
I think that should do it.
Related
Let's say I have a cat model and a life model. And let's say a cat (#cat) has_many lives, and a cat accepts_nested_attributes for a life.
Now, if I wanted to update 7 lives (#lives) at once, using one form_for(#cat), how would that form look like? This is what I've tried, but in this form only the attributes for the last life are passed to the params hash:
<%= form_for(#cat) do |f| %>
<% #lives.each do |life| %>
<%= f.fields_for(life) do |l| %>
<%= l.input :date_of_birth, as: :date %>
<% end %>
<% end %>
<%= f.submit %>
<% end %>
You need to build the attributes in your controller
#cat = Cat.find(<criteria>)
#cat.lives.build
In your example, you have a loop inside a loop. Try this:
<%= form_for(#cat) do |f| %>
<%= f.fields_for(:lives) do |l| %>
<%= l.input :date_of_birth, as: :date %>
<% end %>
<%= f.submit %>
<% end %>
What I currently have is:
<%= f.label :attachment_uploader, 'Current Attachments:' %>
<%= f.fields_for :data_files do |attachment| %>
<% if !attachment.object.new_record? %>
<%= attachment.label :attachment_uploader, 'Delete: ' + attachment.object.attachment_uploader_url.split("/").last %>
<%= attachment.check_box :_destroy %>
<% end %>
<% end %>
However, if I don't have any attachments the label is still there. For the sake of aesthetics I'd like it to be hidden unless I have attachments.
I was thinking something akin to:
<%= f.fields_for :data_files do |attachment, index| %>
<% if index == 0 %>
<%= attachment.label :attachment_uploader, 'Current Attachments:' %>
<% end %>
#rest of code
<% end %>
But that doesn't work!
I've read about the f.options[:index] in another post, but I couldn't figure it out.
Add an unless empty? condition before fields_for. #object will be the object for which you created the form
<%= f.label :attachment_uploader, 'Current Attachments:' %>
<% unless #object.data_files.empty? %>
<%= f.fields_for :data_files do |attachment| %>
<% if !attachment.object.new_record? %>
<%= attachment.label :attachment_uploader, 'Delete: ' + attachment.object.attachment_uploader_url.split("/").last %>
<%= attachment.check_box :_destroy %>
<% end %>
<% end %>
<% end %>
I am trying tp print a non updateable value in my page.
So far it displays
<%= f.fields_for :ingredients do |builder| %>
<fieldset>
<%= builder.text_area :name %>
</fieldset>
<% end %>
which works and I need it to display a non updatable - plain text. So I tried to do
Option 1
<%= f.fields_for :ingredients do |builder| %>
<fieldset>
<%= builder.label :name, "Ingredients" %>
</fieldset>
<% end %>
But no success. this does work:
option 2
<% #recipe.ingredients.each do |ingredient| %>
<td><%= ingredient.name %></td>
<% end %>
What is the main difference between option 1 and 2 ? I prefer using option 1 with the <li> tag. what am I doing wrong?
Label is used to create a label for a field, and not meant to show its value. Option 2 is exactly how you would display the contents of the name field. Option 1 style of formatting is to show the literal 'Ingredients' instead of 'name'. Ususally, that would be followed by <%= builder.text_area :name %>.
Another possible inconsistency: #recipe.ingredients is an array, so there is no field called ingredients.name. As a test, try ingredients[0].name.
So in option 1, try:
<% ingredient = #recipe.ingredients[0] %>
<%= f.fields_for :ingredient do |builder| %>
<fieldset>
<%= builder.label :name, "Ingredients" %>
</fieldset>
<% end %>
If that printed the label 'Ingredients', then you could print the list of ingredients with:
<td>Ingredients:</td>
<% #recipe.ingredients.each do |ingredient| %>
<td><%= ingredient.name %></td>
<% end %>
In my Rails app I have a nested form_for in my show action. This form is the same as the one in the edit action, but it has different fields.
Category -> Task -> completed (boolean, check_box) is what I am trying to update, but it doesn't. Although, if I do Category -> Task -> name (string, text_field) it updates fine.
This does NOT work
<%= form_for check_list do |f| %>
<%= f.error_messages %>
<% count = 0 %>
<ol>
<%= f.fields_for :tasks do |task| %>
<li>
<%= task.label :completed, check_list.tasks[count].name %>
<%= task.check_box :completed %>
</li>
<% count += 1 %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
This works
<%= form_for check_list do |f| %>
<%= f.error_messages %>
<% count = 0 %>
<ol>
<%= f.fields_for :tasks do |task| %>
<li>
<%= task.label :name, check_list.tasks[count].name %>
<%= task.text_field :name %>
</li>
<% count += 1 %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
This is a partial, and check_list is a variable I'm passing
Edit:
Here is the source for my models:
class CheckList < ActiveRecord::Base
has_many :tasks, :dependent => :destroy
accepts_nested_attributes_for :tasks, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
# Validations
validates :name, :presence => true
end
class Task < ActiveRecord::Base
belongs_to :check_list
end
I'd suggest adding the name as a hidden field on the form, as Rails probably updates all the fields that are passed into the Action.
<%= form_for check_list do |f| %>
<%= f.error_messages %>
<% count = 0 %>
<ol>
<%= f.fields_for :tasks do |task| %>
<li>
<%= task.label :completed, check_list.tasks[count].name %>
<%= task.check_box :completed %>
<%= task.hidden_field :name %>
</li>
<% count += 1 %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
<% end %>
</ol>
<p><%= f.submit 'Update' %></p>
<% end %>
i would like to use an additional collection for a fields_for. this collection should hold all the possibilities to be used in fields_for.
Lets say I have a person with tasks that will happen regularly each week on the same day. In the person form, i should have an entry for each day, even if there are not yet any saved tasks. I tried:
<% form_for(#person) do |f| %>
...
<% f.fields_for :tasks, #weekdays do |task_fields| %>
<%= weekday.name %>:
<%= project_fields.text_field :name %>
<% end %>
<% end %>
now there should be for each weekday a text field to enter the name of the task of that day. for example weekday.name = "monday" and task.name = "drinking coffee", task.weekday_id = 1
You are not iterating through the week_days. You should do like this:
<% #weekdays.each_with_index do |weekday, i| %>
<% f.fields_for :tasks do |task_fields| %>
<%= weekday.name %>:
<%= task_fields.text_field :name %>
<%= task_fields.hidden_field :weekday_id, :value => (i + 1) %>
<% end %>
<% end %>
If you have a table 'weekdays', then hidden_field value should be weekday.id
Edit: July 30
I think I completely messed up this answer. Let me try to improve it.
<% f.fields_for :tasks, #weekdays do |task_fields| %>
<%= weekday = task_fields.object %>
<%= weekday.name %>:
<%= task_fields.text_field :name %>
<%= task_fields.hidden_field :weekday_id, :value => weekday.id %>
<% end %>