Working with each AND window.location on Rails - ruby-on-rails

I have another question involving each loops. I have a view which displays a current classroom. It shows how many students are online atm, etc. Within a div located on the bottom right i have a table that lists all the available classrooms. The "name" of the classroom is a button which makes the page refresh with new parameters (:class_id) and then shows the "clicked" classroom.
My problem is identifying the proper ID for each row in the table within the each do loop.
I have this code in my view (Example)
<% #classrooms.each do |room| %>
<table>
<tr>
<td><%= room.id %></td>
<td><button onclick= "class()"><%= room.class %></button></td>
</tr>
</table>
<script>function class(){window.location = '<%= classroom_path(:class_id = room.id)%>'};</script>
<% end %>
Its redirecting with the new param, but the class_id is the same for all the entries (last one). Any help? This is probably fairly simple, not sure.

I'm confused. Why not use a real link ?
<% #classrooms.each do |room| %>
<%= link_to room.class, classroom_path(room) %>
<% end %>
If you don't want a link (which can be styled as a button with virtually any css framework; including bootstrap); you can always do :
<% #classrooms.each do |room| %>
<%= button_to classroom_path(room), method: :get, value: room.class %>
<% end %>
if you want to do it via js / jquery, here you go:
<% #classrooms.each do |room| %>
<%= tag :button, data: {url: classroom_path(room)}, class: 'js_button' ,value: room.class %>
<% end %>
<script type="text/javascript">
$(document).on('click', '.js_button', function(){
window.location = this.getAttribute("data-url");
});
<script>
also, typo: classroom_path(:class_id = room.id)

Your syntax looks wrong. Try
<td><%= room.id %></td>
And also <%= room.class %>
If you want to output data in erb, you need <%= not just <%`
Also, you are redefining the class() function for each #classroom object, so any button click would call the same function each time. You aren't making a new function for each instance.
But, this could all be cleaned up much easier by just doing a simple link_to and using path helpers like <%= link_to room.class, class %>

Related

Rails - Proper way to select and submit from a list

I'm new to Rails and am trying to figure out the proper way to do this, but am having trouble finding an answer on Google. In my app, the user performs a search, which queries a 3rd party API and then displays a list of results for the user to choose from. When the user clicks the "Add" button for the result they want, I pass a hidden_field_tag that contains the API's ID to my controller and create a record in the database.
My questions are: Should I have a form for each result like my code below? Or should I use the link_to helper instead? Is there a better way?
Thanks.
My current code:
<% #series.each do |series| %>
<tr>
<td>
<%= form_tag({controller: "series", action: "create"}, method: "post") do %>
<%= hidden_field_tag(:series_id, series.xpath('seriesid').text) %>
<%= submit_tag("Add") %>
<%= series.xpath('seriesname').text %>
<% end %>
</td>
</tr>
<% end %>
You could use link to with post http method. For e.g.
link_to "Add", series_path(series_id: series.xpath('seriesid').text), method: post
(Change the param name and action to suit your need.)
Rails has js component converts this into a form submit automatically.

Passing variable param in form via dropdown

I have this form:
<tr>
<% item.inventory_items.each do |product| %>
<td>
<%= form_tag("/list_items", method: "post") do %>
<%= hidden_field_tag(:item_id, item.id) %>
<%= hidden_field_tag(:inventory_item_id, product.id) %>
<%= hidden_field_tag(:shopping_list_id, ShoppingList.first.id) %>
<%= submit_tag("#{product.price}", class: "btn btn-primary") %>
<% end %>
</td>
<% end %>
</tr>
Currently the hidden_field for shopping_list_id is being set, as you can see, by ShoppingList.first.id. That was really just a placeholder to make sure my form was working. I want the :user to be able to select which of their lists to submit this list_item to. I'm unsure of the best way to do that. Ideally I'd like to be able to have them hover over the product price and have a drop down of their lists to select from, whereby the form would get the shopping_list_id from. How can I best accomplish something like this? I'm using Twitter Bootstrap. Thanks in advance.
Something like this should get you started:
<%= select_tag(#user, :shopping_list_id, options_for_select(#user.lists)) %>

Ruby on Rails: text filed

I have a code where a user can select a specific file to be deleted or analyzed.
<% if #files%>
<%= form_tag what_to_do_files_path, method: :get do %>
<%= submit_tag "Delete selected", :name => 'delete' %>
<%= submit_tag "Analyse", :name => 'analyse' %>
<% #files.each do |file| %>
<% if (file.analyzed=="no") %>
<p><td> <%= check_box_tag "files[]", file.id %></td><%= file.name %></p>
<% else %>
<div class="my_profile_info">
<p><td> <%= check_box_tag "files[]", file.id %></td> <%= file.name %></p>
<td class="Info">
Info
</td>
</div>
<% end %>
<%end%>
<%end%>
<%else%>
<%end%>
I need to be able to give a name to every analysis.
For example: user selects 3 files, enters a name in the text field "Analysis of annual profit" and clicks on the button "Analyse".
The name "Analysis of the annual profit" and the names of the files that were selected have to be saved into the table group_analysis.
I have tried something like this after submit_tag "Analyse":
<%= form_for #groupanalysis do |f| %>
<div class="field_label">
<%= f.label :group_name, "Type group name hier" %>
</div>
<br class="clear" />
<br />
<% end %>
but it tells me undefined method model name
Thanks in advance.
I think you may need to take a step back and think of how this form represents the model that you're trying to create or update. Generally speaking the first argument to form_for and form_tag is an object and symbol, respectively, which represent the model that you're working with. The form fields map to each attribute of the object.
According to conventions and/or the :url argument, this will get routed to the appropriate controller and call an action according to the HTTP verb (again, part of many conventions in rails).
Going back to your code examples, you are using the form_tag helper incorrectly and the example using form_for may not be the right implementation. For example you're just displaying a label, with no input nor submit.
I hate to just post a link here and just tell you to read the docs, but in this case I think this is the best first step.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for

Show specific data in a index view that belongs to the view

Creating a simple todolist. Trying to show the description for a task that belongs to a list in the list index view. With the current code all data fields shows up from all tasks that belongs to the list when i use list.tasks, but i only want the task.desc. How do i specifically tell rails that i only want the task.desc to show up?
lists/index.html.erb
<h1>My Lists</h1>
<%= link_to 'New List', new_list_path, class: "btn btn-primary" %>
<h3>Name | Time Ago</h3>
<% #lists.each do |list| %>
<h4><%= link_to list.name, list %></td></h4>
<% if list.created_at > Time.now.beginning_of_day %>
<%="#{time_ago_in_words(list.created_at)} ago"%>
<% else %>
<h6><%= list.created_at.strftime("%b %d, %Y") %></h6>
<%= list.tasks %><br />
<% end %>
<%= link_to 'Edit', edit_list_path(list) %> |
<%= link_to 'Destroy', list, method: :delete, data: { confirm: 'Are you sure?' } %>
<br />
<% end %>
<br />
If i understand correctly your problem, you can use .each, which you have used for list iteration:
<% list.tasks.each do |task| %>
<%= task.desc %><br />
<% end %>
To get an array of each description
list.tasks.collect(&:desc)
The & is a Rails shortcut that got into Ruby 1.9 - it says, apply the method after the & to each member of the collection.
I think you might want
list.tasks.collect(&:desc).join("<br />").html_safe
:)
(you might not need html_safe, it's used to show you're deliberately putting markup in a string and you don't want it to be escaped)
If this works for you I would take it out of the view and put it in the list class. As in
def current_tasks
tasks.collect(&:desc)
end
This means you can test this and reuse it later.

How do I set a unique ID for checkboxes in a multi-record Rails form?

I've set up a Rails form roughly following the instructions in this Railscast.
Here's the code for the form:
<% form_tag complete_todos_path, :method => :put do %>
<ul>
<div id="incomplete_todos">
<% #incomplete_todos.each do |todo| %>
<%= render :partial => todo %>
<% end %>
</div>
</ul>
<%= submit_tag "Mark as completed" %>
<% end %>
And here's the code for the todo partial:
<div class="todo">
<li>
<%= check_box_tag "todo_ids[]", todo.id %>
<%=h todo.name %>
<%= link_to 'edit', edit_todo_path(todo) %>
<%= link_to 'delete', todo, :confirm => 'Are you sure?', :method => :delete %>
</li>
</div>
It's working great, but I'm looking to start implementing AJAX and I need each checkbox to have a unique id. Right now, the input tags generated look something like this:
<input id="todo_ids_" name="todo_ids[]" type="checkbox" value="7" />
Every check box has the same id ("todo_ids_"), which is a problem. I suspect the solution is embarrassingly simple, but I'm not seeing it. Any tips?
<%= check_box_tag "todo_ids[]", todo.id, false, :id => "todo_id_#{todo.id}" -%> or whatever you want the id to be.
I consider this a bug with check_box_tag caused by the seemingly hackish nature of manually giving it the name todo_ids[] and the method code calling sanitize_to_id(name). I just ran into this yesterday and I'm contemplating a patch.
I ended up using a solution similar to Ryan's, but as I wrote in the comment I had to make a further change. In the form:
<%= check_box_tag "todo_ids[#{todo.id}]", todo.id %>
In the action called by the form:
Todo.update_all(["completed_at = ?", Time.now], :id => params[:todo_ids].keys)
Note the "params[:todo_ids].keys" at the end, which was a workaround to deal with the odd way the parameters were formatted:
"todo_ids" => {"5"=>"5"}
Can you try this and let us know if it works:
check_box_tag "todo_ids[#{todo.id}]", todo.id %>
This is the expected behaviour of check_box_tag, as this comment on a rejected fix explains.
You can use collection_check_boxes like this (haml syntax, sorry):
# Accumulate todos in a params hash like { todos: { to_complete: [] } }
= collection_check_boxes(:todos, :to_complete, #incomplete_todos, :id, :name) do |todo_builder|
= todo_builder.label do
# This is the result of calling :name on the todo, as specified
# calling the helper
= todo_builder.text
= todo_builder.check_box
Of course you can use partials inside the block, just pass and use the builder inside.
Check more options in the API docs.

Resources