Pass selected value to Rails controller - ruby-on-rails

I've got a method named 'statement' in a balances controller (balances_controller.rb) that returns information from a specific date (#latestDate) to a view (statement.html.rb)
#latestDate = the most recent date in the 'date' column in the 'balances' table
In the view, I've also got a dropdown list of all the dates and when a date is selected, I'd like to be able to update the information so that in effect, the statement method is called again but the #latestDate is set to the selected value from the dropdown list.
How can I do this?
UPDATE:
I've modified my code with brito's suggestions. When I press the Search button, the form passes the following params:
?utf8=✓&date_id=30%2F12%2F2015&commit=Search
However, if I select a date and click Search, the #latestDate gets set and the h1 tag gets displayed correctly, but the rest of the data doesn't get returned.
CODE:
balances_controller.rb
....
def statement
#dates = Balance.select("distinct(date)").order('date desc')
#Updated
if (params[:date_id].blank?)
#latestDate = Balance.order('date desc').first.date
else
#latestDate = params[:date_id]
end
#summaryBalances = Balance.joins(:account).order('accounts.credit').where('date = :abc', {abc: #latestDate})
end
....
balances/statement.html.rb
....
<h1>Statement at <%= #latestDate %></h1>
#UPDATED
<%= form_tag("/statement", method: "get") do %>
<%= select_tag "date_id", options_for_select( #dates.collect {|d| [ d.date, d.date ] }) %>
<%= submit_tag("Search") %>
<% end %>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Account</th>
<th>Balance</th>
<th colspan="1"></th>
</tr>
</thead>
<tbody>
<% #summaryBalances.each do |balance| %>
<tr>
<td><%= balance.account.name %></td>
<td class='account-balance'><%= number_to_currency(balance.balance, unit: "£") %></td>
<td><%= link_to 'Edit', edit_balance_path(balance) %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
....

A "dropdown" is a kind of input (HTML <select>).
<input>s and <select>s must be within a <form> HTML element.
Using pure HTML
Whatever is in the <form> will be accessible in the params hash. So if you have a dropdown list, it should be within a <form> like this:
<form accept-charset="UTF-8" action="/yourroute" method="get">
<select name="car">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
</form>
In the example above, the selected value (e.g. "volvo") will be available in the controller within params["car"]. Note that you would still have to define /yourroute.
Using Rails' helper methods
Of course, Rails helps you generate forms and inputs. You can use Rails' form helpers for that. For example, the following generates a search form ("Search" label, text box for input and a button) that sends a GET to the /search route:
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
EDIT
To check and set #latestDate = balance[date_id] if the balance[date_id] was selected:
#latestDate ||= params[:balance[date_id]] unless params[:balance].blank?

Related

How do I use check_box in a table form so that I can access the table attributes in an array?

I have a table inside of a form, with the following code:
<tbody>
<% #appointments.each do |appointment| %>
<td class="collapsing">
<div class="ui fitted slider checkbox">
<%= f.check_box appointment.id %><label></label>
</div>
</td>
<td><%= appointment.name %></td>
<% end %>
</tbody>
So a checkbox is generated, but if I'm selecting multiple checkboxes, I get
Parameters: {"utf8"=>"✓", "authenticity_token"=>"qCo02PG1F2wrSK4sxCQiQLzuhG4vZypgd9p5LzP9Sp7uZQFHs8tTTitLR++VXVK3f68P0qih+iQBlZt9anG01Q==", "cleaner"=>{"4"=>"1", "5"=>"0", "2"=>"0", "3"=>"0", "6"=>"0"}, "commit"=>"Request", "cleaner_id"=>"1"}
So to access the appointments, I would do parameters["cleaner"] and get <ActionController::Parameters {"4"=>"1", "5"=>"1", "2"=>"0", "3"=>"0", "6"=>"0"} permitted: false>
What I am looking to do is get an array instead of a hash.
The Hash class provides a keys method, which will return the keys of a hash as an array.
So parameters["cleaner"].keys is what you are (probably) looking for.
I guess you need to use some customization on the check boxes, something like:
<% #appointments.each do |appointment| %>
<td class="collapsing">
<div class="ui fitted slider checkbox">
<%= check_box_tag "cleaner[appointment_ids][]", appointment.id %><label></label>
</div>
</td>
<td><%= appointment.name %></td>
<% end %>
That way you should have something like params[cleaner][appointment_ids] to get the selected appointments

Rails class based on index value of in_groups_of

The following is intended to distribute array items into two columns.
<% #entitiquestions.in_groups_of(2, false) do |entitiquestions| %>
<tr>
<% entitiquestions.each do |entitiquestion| %>
<td>
<span data-tooltip class="hint--bottom hint--info" data-hint="<%= entitiquestion.question.query %>">
However, there is a class that should be set based on the index of the array item (if it is in fact an index...)
Can a condition be set somehow based on this position?
You can get the index of the array item by using each_with_index, for example the following will give you a row_index variable which starts from 0 for the first row:
<% #entitiquestions.in_groups_of(2, false).each_with_index do |entitiquestions, row_index| %>
Likewise, you can get the column index with:
<% entitiquestions.each_with_index do |entitiquestion, column_index| %>
Now you have the exact position of the element within the table, so you can use a ternary operator to add a class. As an example, if you wanted to add the highlight class when the row is even you could do:
<span data-tooltip class="hint--bottom hint--info <%= 'highlight' if row_index.even? %>"
Here's a full example:
<table>
<% #entitiquestions.in_groups_of(2, false).each_with_index do |entitiquestions, row_index| %>
<tr>
<% entitiquestions.each_with_index do |entitiquestion, column_index| %>
<td>
<span data-tooltip class="hint--bottom hint--info <%= 'highlight' if column_index.even? %>" data-hint="<%= entitiquestion.question.query %>">
<%= entitiquestion.question.query %>
</span>
</td>
<% end %>
</tr>
<% end %>
</table>

Conditional hidden tag based on checkbox condition in Rails

How can I send a hidden tag based on whether or not a checkbox is checked?
I have a table with a product title and product price and check box selection on each row and on the form submit I'd like to send both of these values to a controller. I was only able to get one value to submit with a single checkbox, so I added a hidden tag field, however, this hidden tag will submit every row, which is not what I want. In the params sent example below it should have two items and two prices sent, but it sends all the prices for each row. (As an aside, if there is a better way to send both params without using a hidden tag please let me know!)
This is data from a google analytics API report request FYI =>
#product_revenue.reports[0].data.rows
p.dimensions[0] = "Product Title"
p.metrics[0].values[0] = "Product Price"
The structure of this comes from here.
View Code:
<div class="col-md-6">
<%= form_tag add_multiple_path, method: :post do %>
<table>
<thead>
<th><strong>Product Title</strong></th>
<th><strong>Product Price</strong></th>
<th><strong>Add?</strong></th>
</thead>
<% #product_revenue.reports[0].data.rows.each do |p| %>
<tr>
<td><%= p.dimensions[0] %></td>
<td><%= p.metrics[0].values[0] %></td>
<td>
<%= check_box_tag 'price_test_datum[product_title][]', p.dimensions[0] %>
<%= hidden_field_tag('price_test_datum[product_price][]', p.metrics[0].values[0]) %>
</td>
</tr>
<% end %>
</table>
<%= submit_tag "Add selected" %>
<% end %>
</div>
The hidden field is dumping all of the column values instead of the one associated with that row?
Parameters sent:
{
"utf8"=>"✓",
"authenticity_token"=>"token here",
"price_test_datum"=>{
"product_price"=>["29.98", "14.99", "14.99", "14.99", "14.99", "14.99", "299.95", "35.97", "21.98", "10.99", "33.98", "27.98", "13.99", "59.99", "29.98", "59.98", "29.99", "110.93", "4088.79"],
"product_title"=>["Turquoise Bracelets", "Red Bracelets"]
},
"commit"=>"Add selected"
}
So I added an index to the table loop and used the checkbox value to submit the relevant row value (index) to the controller. I then used hidden tag fields to send all the product title and price values in as arrays to the controller and used the row key to find the relevant value. This seems like an inelegant solution, but it worked.
<%= form_tag add_multiple_path, method: :post do %>
<table>
<thead>
<th><strong>Product Title</strong></th>
<th><strong>Product Price</strong></th>
<th><strong>Add?</strong></th>
</thead>
<% #product_revenue.reports[0].data.rows.each_with_index do |p, index| %>
<tr>
<td><%= p.dimensions[0] %></td>
<td><%= p.metrics[0].values[0] %></td>
<td>
<%= check_box_tag 'row[]', index %>
<%= hidden_field_tag 'price_test_datum[product_title][]', p.dimensions[0] %>
<%= hidden_field_tag 'price_test_datum[product_price][]', p.metrics[0].values[0] %>
</td>
</tr>
<% end %>
</table>
Controller Code
def add_multiple
params[:row].each do |r|
PriceTestDatum.create(product_title: params[:price_test_datum][:product_title][r.to_i],
product_price: params[:price_test_datum][:product_price][r.to_i])
end
respond_to do |format|
format.html { redirect_to price_test_data_path }
format.json { head :no_content }
end
end

Dynamic checkbox with Ajax in Rails

I have a Form with some checkboxes loaded from the Database, and an option to add other items manually to the items table. This is done by Ajax in the code below...
item_controller.rb
def manual_item_add
#manual_item = Item.find(params[:id_item].to_i)
respond_to do |format|
format.js
end
end
manual_item_add.js.erb
$("#items_table").append("<%= escape_javascript(render 'manual_item_add', :manual_item => #manual_item) %>")
_manual_item_add.html.erb
...
<td><%= check_box_tag("manual_items[]", item.id, true) %></td>
...
edit_items.html.erb
<%= form_tag( {controller:"item", action:"edit_items"}) do %>
<p align="center">
<%= select_date(#account.start_date, prefix: 'start_date') %>
to
<%= select_date(#account.end_date, prefix: 'end_date') %>
</p>
<%= hidden_field_tag 'id_account', #account.id %>
<table id="items_table" class="subtable" align="center" width="55%">
....
<tr>
<th colspan="6">Items added manually</th>
</tr>
<tr>
<th># ID</th>
<th>Type</th>
<th>Description</th>
<th>Ammount</th>
<th>Date</th>
<th>Include in the account</th>
</tr>
</table>
<p align="center"><%= submit_tag("Save", class: "btn") %></p>
<% end %>
<%= form_tag( {controller:"item", action:"manual_item_add"}, method:"get", remote: true) do %>
<h4 align="center">Add item manually</h4>
<p align="center">Item ID:
<%= text_field_tag "item_id", nil , size:5, maxlength:5 %>
<%= submit_tag("Add Item", class: "light_btn") %>
</p>
<% end %>
So... the problem here is that though I see the new checkboxes i am adding to the table (they are being created normally), the "manual_items[]" array is not being passed to the controller when I submit the resulting form (by the way, the "items_table" is inside the form definition).
Does anybody know what I am doing wrong? Sorry for the newbie question, I'm starting to work with Ruby + Rails.
Unfortunately, I don't have a definitive answer for this problem. The only working solution I've tried was to use JQuery to force parameters to be part of the form:
$(document).ready(function() {
$("#edit_items_form").submit(function(event) {
$(this).append($("input[name='manual_items[]']:checked"));
$(this).submit();
});
});
I am definitely not comfortable to this solution, I'd like to know why these Ajax checkboxes are not automatically recognized as being part the form.

Rails 3 return query results to bottom of form page

I have a simple select form. When a year is selected from the form I would like the results to be returned to the same page but below the form. Can someone explain how to do this? Here is the form page (index.html.erb)
<%= form_tag("lookup/show", :method => "get") do %>
<%= label_tag(:q, "Pub Year :") %>
<%= collection_select(:lookup, :pubyear, #pubyears, :pubyear, :pubyear) %>
<%= submit_tag("Find") %>
<% end %>
Here is the show method from the Lookup controller
def show
#lookuprows = Lookup.return_lookup_row(params[:lookup][pubyear])
respond_to do |format|
format.html
end
end
Here is the show.html.erb page that the results currently go to
<tbody class="lkuptbody">
<% #lookuprows.each do |lkup| %>
<tr class="lkuprow">
<td><input type="text" class="lkupcode" value=<%= lkup.codetype %> /></td>
<td><input type="text" class="lkupdesc" value=<%= lkup.codedesc %> /></td>
<td><input type="text" class="lkuprmks" value=<%= lkup.rermark %> /></td>
</tr>
</tbody>
I understand that I will have to make a partial _show.html.erb, but how do I reference that from the form page (index.html.erb)?
Thanks
If you want the results to appear on the same page but below the form, then the form should send the results to the index action, not to the show action:
<%= form_tag("lookup", :method => "get") do %>
<%= label_tag(:q, "Pub Year :") %>
<%= collection_select(:lookup, :pubyear, #pubyears, :pubyear, :pubyear) %>
<%= submit_tag("Find") %>
<% end %>
and in your LookupController:
def index
#lookuprows = Lookup.return_lookup_row(params[:lookup][pubyear]) unless params[:lookup].nil?
...
end
Then just append the table HTML in your show page below the form (in index.html.erb) wrapped in an if block to filter out the case where #lookuprows is nil:
<% if #lookuprows %>
<tbody class="lkuptbody">
<% #lookuprows.each do |lkup| %>
<tr class="lkuprow">
<td><input type="text" class="lkupcode" value=<%= lkup.codetype %> /></td>
<td><input type="text" class="lkupdesc" value=<%= lkup.codedesc %> /></td>
<td><input type="text" class="lkuprmks" value=<%= lkup.rermark %> /></td>
</tr>
<% end %>
</tbody>
<% end %>
This will show the results in #lookuprows as a table if there are any, if not it will not show the table.
You may want to put that table HTML in a separate partial to clean up the view, but that is not essential to the problem you asked.
Hope that helps.
You want to avoid reloading the page and put it under the form? Here's how to do it with ajax :
Index.html.erb.
<%= form_tag("lookup/show", :method => "get", :data => {:remote => true, :type => "html"}, :id => "lookup_form") do %>
<%= collection_select(:lookup, :pubyear, #pubyears, :pubyear, :pubyear, id: 'lookup_show_select') %>
<%# Add More fields here %>
<%= submit_tag "Submit" %>
<% end %>
<div id='lookup_show_result'></div>
In app/assets/lookup.js.coffee. If you don't use coffeescript, it's easy to translate to JS, just ask.
$ ->
$(document).on 'ajax:success', '#lookup_form', (evt, data) ->
$('#lookup_show_result').html(data)
Controller unchanged, just process the request according to all parameters
This is a minimal untested version, tell me if you're stuck
On a side note, I'm starting to develop a gem that will extend UJS implementation of Rails with jQuery here to make standard update/delete etc easier with ajax:
jQuery UJS extended

Resources