I have a table in view:
#view
<%= form_tag save_table_path do %>
<table>
<% #channel_name_body.values.max_by(&:size).size.times do |i| %>
<tr class="border">
<% #channel_name_body.values.map { |a| a[i] }.each do |value| %>
<td contenteditable class="border light_green"><%= value %></td>
<% end %>
</tr>
<% end %>
</table>
<%= submit_tag "save",:class => "btn btn-primary offset4" %>
<% end %>
I don't know what to do next to pass value of all cell in table to controller such as:
#controller
def save_table
#table=params[:table] #or #row1=params[:row1]... or #col1=params[:col1]....
end
Edit: I found way to solve this problem, it must use js.
I don't want to use js, what about if I change to <%= text_field_tag :cell, value %> how can I get value of all cell in table ?
I think you're getting confused with how to handle data in Rails (or any backend system)
HTML
HTML is a markup language; which means if you give it certain code, it will put various elements onto the page. The <table> tag is one of those elements, and has no bearing on the controller-side functionality of your app
Controller Params
HTML form params are directly related to the form (nothing else)
In Rails, you get the params hash ordered like this:
params[:form_name][:input_name]
Your Code
From what you've shown, it seems you have several parts missing
Firstly, you need input elements (to populate the params). Currently, you have:
<td contenteditable class="border light_green"><%= value %></td>
This does not create any params, as it's not an input element. It's just a value that's been outputted on the screen. What you'd need is something like:
<td contenteditable class="border light_green"><%= text_field_tag :cell, :value => value %></td>
By adding these inputs, you will give Rails the ability to populate the params hash with their values, which you can then access from your controller like this:
def save
#table = params[:form_name][:cell][0]
end
Hope this helps?
Try this:
<%= text_field_tag "table[cell#{index}]", value %>
On form submit it will give you values like params[:table][:cell1], params[:table][:cell2] and so on...
Hope this helps..
Related
I am currently creating a nested form using cocoon. I have a table that takes in information for everyone in a household. the form dynamically creates a new line when the user clicks on add new member. The problem that I am having is that when the form is submitted, only the last line of the table is passed through.
I have tried many different things including changing the attributes of the members and also trying to isolate just the household members so I can see what is happening. I have tried giving them unique id's, but that didn't work. It might be something to do with the rails sever or just some bad code that I can't see.
Here is where I am nesting the form
<tbody class="members">
<%= f.fields_for :household_members do |ff|%>
<%= render 'household_member_fields', :f => ff %>
<%end%>
</tbody>
</table>
<%= link_to_add_association 'Add household member', f, :household_members, data: {association_insertion_node: '.members',
association_insertion_method: :append} %>
This is the beginning of the households_member_fields:
<tr class= "nested-fields">
<% f.hidden_field :id%>
<td><% f.label(:name)%>
<%= text_field(:household_members, :name) %></td>
<td><% f.label(:birthdate)%>
<%= date_field(:household_members, :birthdate) %></td>
<td><% f.label(:ssn)%>
This is my controller
def create
addresses = params[:addresses].permit([:county]).to_h
contact_info = params[:contact_info].permit(params[:contact_info].keys).to_h
household = params[:household_type].permit([:house_type]).to_h
household_members = member_params
#workflow = CreatesUser.new(address_info: addresses,
contact: contact_info, household: household)
#workflow.create
redirect_to users_path
end
private
def member_params
params.require(:user).permit(household_members_attributes: [:id, :name, :birthdate, :ssn, :gender, :hispanic, :race, :or_tribe, :education, :_destroy])
end
When I currently submit two or more household members I only ever get one of them like this:
"household_members"=>{"name"=>"Fake2", "birthdate"=>"2019-07-21", "ssn"=>"fake2", "gender"=>"Female", "hispanic"=>"0", "race"=>"Alaska Native", "or_tribe"=>"0", "education"=>"Some college"}, "disablility_assistances"=>{"disabled"=>"0", "homebound"=>"0", "snap"=>"0", "ohp"=>"0", "med_insurance"=>"fake2"}, "veteran_statuses"=>{"veteran"=>"0"}
I am expecting to get multiple of these. If you have any incite into what I am doing wrong I would greatly appreciate it!
Thanks,
Aala95
After looking at what my code is returning a little more it looks like the nested form is being submitted but only with an ID and delete:
"user"=>{"household_members_attributes"=>{"0"=>{"_destroy"=>"false"}, "1"=>{"_destroy"=>"false"}}}
You have to fix your nested items partial: remove the scoped name --now it will be double scoped, this explains why some attributes are in household_members (your scope and blocked by the strong parameters definition) and some in household_members_attributes (the expected scope). Also there is no need to add the hidden field :id (that will be automatically handled by the index in the array).
So write your partial as follows:
<tr class= "nested-fields">
<td><% f.label(:name)%>
<%= text_field(:name) %></td>
<td><% f.label(:birthdate)%>
<%= date_field(:birthdate) %></td>
<td><% f.label(:ssn)%>
Hi in my apps I have a scaffold, were users can select different type of paper and add a paper weight for each type. Then I calculate the running total of paper_weight for each user in the ApplicationController.
I want to be more specific and show the users the average weight of each paper_type they are using. I´m a bit lost since I ´m rather new to rails, can anyone here help me??
thanks in advance
below are my views.
in paper/new.html.erb
<div class="control-group">
<%= f.label :paper_type, class: 'control-label' %><br>
<div class="controls">
<%= f.select(:paper_type, options_for_select([['Skrifstofupappír', 'Skrifstofupappír'], ['Dagblaðapappír', 'Dagblaðapappír'], ['Glans_&_tímaritapappír', 'Glans_&_tímaritapappír'], ['Annað', 'Annað']])) %>
</div>
</div>
<div class="control-group">
<%= f.label :paper_weight, class: 'control-label' %><br>
<div class="controls">
<%= f.number_field :paper_weight %>
</div>
</div>
in ApplicationController.rb
#paper_weight_per_capita = current_user.papers.sum(:paper_weight) / (current_user.profile.staff)
First a tweak.
In your Paper class is where you want to put the array of acceptable values for the paper type. That way you can validate input from perhaps more than just this form in the future. It also allows you to test that code plus putting an array right in the view like that is just not the best practice.
class Paper
PAPER_TYPES = ['Skrifstofupappír', 'Dagblaðapappír', 'Glans_&_tímaritapappír', 'Annað']
...
Then in your view, change to this.
<%= f.select(:paper_type, options_for_select(Paper::PAPER_TYPES)) %>
That doesn't answer your question, just a tweak to make your code cleaner and testable.
Then in your User model
def average_paper_types
self.papers.group(:paper_type).sum(:paper_weight)
end
And in your partial:
<table>
<thead>
<tr>
<% current_user.average_paper_types.each do |pair| %>
<th><%= pair[0] %></th>
<% end %>
</tr>
</thead>
<tbody>
<tr>
<% current_user.average_paper_types.each do |pair| %>
<td><%= pair[1] %></td>
<% end %>
</tr>
</tbody>
</table>
Not positive I understand correctly, but I think what you're trying to do (based on comments) is display the averages of each individual paper type on the index page.
As you're iterating through the different types of paper that belong to the user, you could call a method that performs that calculation. Inside that method you might do something like this:
def paper_weight_by_type(user_id, paper_type)
u = User.find(user_id)
weight_by_type = Paper.where(user_id: user_id, paper_type: paper_type).pluck(:paper_weight)
# then return this
weight_by_type.inject(:+)
end
this is a crude version. This could be an instance method on either user or paper in which case you wouldn't need both arguments. (ie current_user.paper_weight_by_type(paper_type) ...could also make it a class method and just pass both arguments by adding self. in front of def) Also several ways you could probably cut down on the number of queries being run...but this would get the job done. You'd want to call it from the paper loop on the index page however you ended up doing it. I would get it working one way and then improve it from there. Hope this helps.
I have a text field "tf_Designation" in a view page, see below:
<% form_for(:search) do |f| %>
<table>
<tr>
<td align="center">
<%= f.text_field :tf_Designation,placeholder: "Designation" %>
</td>
</tr>
</table>
<% end %>
I want to get text field value into a controllers page and I am doing like below:
def search
#blah=params[:search][:tf_Designation]
if !params[:search][:tf_Designation].blank?
#Designation = params[:search][:tf_Designation]
render '/index'
end
end
And I do not have search model. But it gave me error at this line #blah=params[:search][:tf_Designation]. The error is below:
undefined method `[]' for nil:NilClass
Kindly suggest me where I make mistake, waiting for your reply. Thanks
It's most likely an issue with how Rails processes form_for - we've only ever used instance variables with it (which can be populated by a resource):
form_for
Form helpers are designed to make working with resources much easier
compared to using vanilla HTML.
Typically, a form designed to create or update a resource reflects the
identity of the resource in several ways
(i) the url that the form is
sent to (the form element's action attribute) should result in a
request being routed to the appropriate controller action (with the
appropriate :id parameter in the case of an existing resource)
(ii)
input fields should be named in such a way that in the controller
their values appear in the appropriate places within the params hash,
(iii) for an existing record, when the form is initially
displayed, input fields corresponding to attributes of the resource
should show the current values of those attributes.
form_tag
I would highly recommend switching to form_tag, as this deals with perishable data:
#app/views/elements/_search.html.erb
<%= form_tag "/search" do %>
<%= text_field_tag :tf_Designation, nil, placeholder: "Designation" %>
<%= submit_tag "Search" %>
<% end %>
#app/controllers/your_controller.rb
def search
#designation = params[:tf_Designation]
unless #designation.blank?
render '/index'
end
end
I have the following loop
<% #sub_categories.dropdown_heads.each do |label| %>
<label for="login"><%= label.head_name %></label>
<%= select_tag "post[dynam][#{label.head_name}]", options_for_select(generate_option(label)) %>
<% end %>
Here is my helper function used for generating dropdown
def generate_option opt
opt.dropdown_lists.inject([]) do |memo, cat|
memo << [cat.list_name, cat.list_name]
end
end
The above piece of code will generate the following result(check the screen shot).
In my database table I have the column called content which holds similar datas
{"Style":"convertible","Year":"2010","Color":"green"}
Since the above code is from edit form, I need to show the selected values in select dropdown How can i parse the json data and show the chosen value any suggestion please.
Edit 1
I changed the line to
<%= select_tag "post[dynam][#{label.head_name}]", options_for_select(generate_option(label)), selected: get_value_for(label.head_name, #post) %>
It is not showing error but it is not filtering just displaying normally
My helper
def get_value_for(head_name, post)
content_hash = JSON.parse post.content
content_hash[head_name]
end
Have another helper to get the value for the label.
<% #sub_categories.dropdown_heads.each do |label| %>
<label for="login"><%= label.head_name %></label>
<%= select_tag "post[dynam][#{label.head_name}]", options_for_select(generate_option(label), get_value_for(label.head_name, #post)) %>
<% end %>
def get_value_for(head_name, post)
content_hash = ActiveSupport::JSON.decode(post.content)
content_hash[head_name]
end
I am assuming that you are setting #post in your controller and Post model is the one you are editing and it has the field content
Also this code is not tested. It should anyways give you the idea
In reference to this
I've created a question in a webform like this:
<div class="form_row">
<label for="features[]">Features:</label>
<% [ 'scenarios', 'role_profiles', 'private_messages', 'polls' ].each do |feature| %>
<br><%= check_box_tag 'features[]', feature,
(params[:features] || {}).include?(feature) %>
<% end %>
</div>
So if scenarios and private_messages gets checked and I print out params[:features] I will get:
scenariosprivate_messages
I was wondering how would I be able to obtain scenarios and private_messages separately from params. Is the mapping params[:features] = "scenariosprivate_messages" or is it really params[features] = ["scenarios", "private_messages"] ? If it's the latter how can I loop through them?
I write in my view:
<%= params[:features].each {|param|
param.capitalize
} %>
and I still just get scenariosprivate_messages printed.
Try this instead:
<% params[:features].each do |param| %>
<%= param.capitalize %>
<% end %>
The problem with your original solution is that you're printing out the result of the block, which is the array itself, rather than printing out each element of the array.
You shouldn't be using params in your views. You're best off assigning params[:features] to an instance variable in your controller and then iterating over that in your view.
But to answer your question, you're putting the equals sign for output in the wrong place. You want to output each element of the array individually instead of outputting the result of the loop.
You must use humanize:
<% params[:features].each do |param| %>
<%= param.humanize %>
<% end %>
According to this blog post you should be able to access them individually as params[:features]['scenarios'] etc. Looping should just work like with all other arrays -- eg
params[:features].each { |param|
# do something with param
}