html5 in rails3 views - ruby-on-rails

I have a view with some embedded ruby in it... i want to insert a cell <td></td> into it, but when i do that it gives several error messages? This is because i concatenate a text field and a submit button into the embedded ruby.
This is my code:
<table>
<% for answer in #question.answers %>
<tr>
<!-- this displays all the possible answers -->
<td>
<%= answer.text %>
</td>
<% if current_user.can_vote_on? (#question) %> <!-- if a current user has not yet voted.. -->
<td> <%= form_tag('/vote', :method => "post") do
hidden_field_tag('vote[answer_id]', answer.id) +
submit_tag("Vote")
end %> <!-- vote button.. -->
<% end %>
</td>
</tr>
<% end %>
<% if current_user.can_vote_on? (#question) %> <!-- this shows a answer text field -->
<tr>
<td>
<%= form_tag('/vote/new_answer', :method => "post") do
hidden_field_tag('answer[question_id]', #question.id) +
hidden_field_tag('answer[user_id]', current_user.id) +
text_field_tag('answer[text]') + <!-- in here i want an extra </td><td> tag -->
submit_tag('Vote')
end %>
</td>
</tr>
<% end %>
My question is: how can i exit the embedded ruby and at the same time staying in the concatenated string...? I want to add the </td> and the <td> after the text_field_tag('answer[text]')
I tried this:
<td>
<%= form_tag('/vote/new_answer', :method => "post") do %>
<%= hidden_field_tag('answer[question_id]', #question.id) %>
<%= hidden_field_tag('answer[user_id]', current_user.id) %>
<%= text_field_tag('answer[text]') %>
</td>
<td>
<%= submit_tag('Vote') %>
<% end %>
</td>
And it works!
Thijs

Simple answer: It's not possible.
I suggest you try a different approach such as using divs inside your td elements. If I were you I wouldn't concatinate the strings together.
<%= form_tag('/vote/new_answer', :method => "post") do %>
<%= hidden_field_tag(answer[question_id], #question.id %>
... so on ...
<div class="position_it_somewhere_with_this_class"><%= submit_tag("vote") %></div>
<% end %>

You don't concatenate tags!
Also you don't use divs in table rows. put the classes in your tds
...
<%= form_tag('/vote/new_answer', :method => "post") do %>
<%= hidden_field_tag('answer[question_id]', #question.id) %>
<%= hidden_field_tag('answer[user_id]', current_user.id) %>
<%= text_field_tag('answer[text]') %>
<%= submit_tag('Vote') %>
<% end %>
</td>
</tr>
..

Related

How to place two elements in a row while using .each loop in rails

I want to show two columns of the code in table data tag"" per row while using '.each' method. But the issue is that the following code displays one column in a row.
<table>
<% #lease.apartment.roommates.each do |roommate| %>
<tr>
<td colspan="5">
<% unless roommate == #lease.second_occupant || roommate == #lease.user %>
<% if roommate.current_room.present? %>
<p>
<%= roommate.full_name %> -
<% if roommate.current_room.apartment == #lease.apartment%>
<%= roommate.current_room&.label %>
<% end %>
<br>Email:<%= roommate.email %><br>Phone:<%= roommate.phone %><br>
<% if #lease.end_at.present? %>
Lease End date (if applicable):<%= #lease.end_at %>
<% end %>
</p>
<% end %>
<% end %>
</td>
</tr>
<% end %>
</table>
You can use the each_slice method for dividing the array into slices of 2 elements each:
<table>
<% #roommates.each_slice(2) do |roommate_slice| %>
<tr>
<td colspan="5">
<%= roommate_slice[0].full_name %>
<%= roommate_slice[1].full_name %>
</td>
</tr>
<% end %>
</table>

Rails: How to access two models in a single loop

I am using Audited gem to track the changes done on users. What I want to display exactly is the changes made which is the audits with the time they are updated at in a same row.I tried to display it this way but it makes repetitions.
<% #users.each do |user| %>
<% user.audits.each do |audit| %>
<% if audit.action != "create" %>
<% user.revisions.each do |revision| %>
<tr class="list-item">
<td>
<%= user.role %>
</td>
<td>
<%= audit.action %>
</td>
<td>
<%= audit.audited_changes %>
</td>
<td>
<%= revision.created_at %>
</td>
<td>
<%= revision.updated_at %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
<% end %>
What I want is to be able to display them with out displaying a single change multiple times.
I am looking for an expression like
for(i=5,j=3;j<5;i++,j++){
....
}
in rails, to avoid the repetition. Thank you
I solved it this way since both audits and revision has same number of elements.I hope it helps for the others.
<% #users.each do |user| %>
<% user.audits.each_with_index do |audit, i| %>
<% if audit.action != "create" %>
<% user.revisions[i] %>
<tr class="list-item">
<td>
<%= user.role %>
</td>
<td>
<%= audit.action %>
</td>
<td>
<%= audit.audited_changes %>
</td>
<td>
<%=user.revisions[i].created_at %>
</td>
<td>
<%= user.revisions[i].updated_at %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
You could also try zip:
user.audits.zip(user.revisions) do |audit, revision|

Why does the "submit" button display before the <form>?

This is kind of surprising. Even though it looks to me like my submit tag is supposed to occur within the form, it displays before the form. The html source looks ok to me, but the resultant display and DOM is wrong. Not sure what would have shuffled it. The submit button is displayed BEFORE the form.
Can you see something?
view file:
<%= content_tag :table do %>
<%= content_tag :thead do %>
<% 5.times do |q| %>
<%= content_tag :th, "1" %>
<% end %>
<% end %>
<%= content_tag :tbody do %>
<%= form_tag program_participant_round_survey_path(
program_id: #program.id, participant_id: #participant.id, round_id: #current_round.id), :method => 'put' do %>
<%= render partial: 'value', collection: #values %>
<%= submit_tag "Save" %>
<% end %>
<% end %>
<% end %>
key part of the html:
...
<tr>
<td>
Scaling Up vs. Scaling Out
</td>
<td>
<input id="values__q0" name="values[]" type="radio" value="q0" />
</td> <td>
<input id="values__q1" name="values[]" type="radio" value="q1" />
</td> <td>
<input id="values__q2" name="values[]" type="radio" value="q2" />
</td> <td>
<input id="values__q3" name="values[]" type="radio" value="q3" />
</td></tr>
<input name="commit" type="submit" value="Save" />
</form></tbody></table>
</div>
</div>
</body>
</html>
Here's what the page looks like in the browser:
And here's what it looks like as DOM:
That's how a browser handles elements inside tables that don't belong there - it assumes they're a caption and moves them before the table.
You have a <input type="submit"> inside a table but not inside a <tr> in the generated code.
If you wrap the <input> in <tr><td>, it will no longer move before the table. Note that using tables for layout is not recommended.
I don't know the exact reason for what's happening, but I would personally do it like this instead:
<%= form_tag program_participant_round_survey_path(
program_id: #program.id, participant_id: #participant.id, round_id: #current_round.id), :method => 'put' do %>
<%= content_tag :table do %>
<%= content_tag :thead do %>
<% 5.times do |q| %>
<%= content_tag :th, "1" %>
<% end %>
<% end %>
<%= content_tag :tbody do %>
<%= render partial: 'value', collection: #values %>
<% end %>
<% end %>
<%= submit_tag "Save" %>
<% end %>

Ruby On Rails - Acts As Taggable - Change name of param: keyword

I wonder if/how to change the name of the param :keyword when using acts as taggable?
Today my url looks like this:
http://www.foo.bar/tagged?keyword=baz
I would like to change the "keyword" to another word.
controller
def tagged
#current_keyword = params[:keyword]
#tags = FeedEntry.tag_counts_on(:keyword)
#tagged_feed_entries = FeedEntry.tagged_with(params[:keyword]).order("published_at desc").paginate :page => params[:sida]
end
View:
<table class="table table-striped">
<tbody>
<% if #tags %>
<% #tagged_feed_entries.each do |feed_entry| %>
<tr>
<td>
<% today = Date.today %>
<% if (today === feed_entry.published_at.to_date) %>
<span class="label label-success">
<% else %>
<span class="label">
<% end %>
<%= format_stamp_to_date(feed_entry.published_at) %>
kl:
<%= I18n.localize(feed_entry.published_at, :format => '%H:%M') %>
</span>
</td>
<td><%= link_to feed_entry.name, feed_entry_path(feed_entry) %></td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
<%= will_paginate #tagged_feed_entries, :param_name => :sida %>
You should just be able to replace all instances of params[:keyword] to params[:whatever]. Your path then becomes http://www.foo.bar/tagged?whatever=baz.
If you have a search form, you'll have to make the relevant changes there, as well.

Rails anyway to add an if statement to a loop

In my rails application I have a set of attachments that display, with a main image being one of them. However, I would like to loop through all of them except the main attachment. My view code right now is:
<% if #asset.attachments.size > 0 %>
<table>
<tr>
<% #asset.attachments.each_with_index do |attachment, i| %>
<% if i%5 == 0 %>
</tr><tr>
<%end%>
<td style="width: 150px;" valign="bottom" align="center">
<%= image_tag(attachment.attachment.url(:thumb)) if attachment.is_image? %>
<%= image_tag("/images/Excel.png") if attachment.is_excel? %>
<%= image_tag("/images/Word.png") if attachment.is_word?%>
<br />
<%= link_to attachment.name.to_s,attachment.attachment.to_s %>
</td>
<%end%>
</tr>
</table>
<%end%>
but, I would like to add something like if !main_image to this line of code:
<% #asset.attachments.each_with_index do |attachment, i| %>
I don't know if that is possible though.
This answer is in continuation to answer on this question
Add another method to your model, which return you the attachments which are not main image.
scope :not_main_image, where(:main_image => false)
On a side note, you might want to move all this logic into a helper method:
<%= image_tag(attachment.attachment.url(:thumb)) if attachment.is_image? %>
<%= image_tag("/images/Excel.png") if attachment.is_excel? %>
<%= image_tag("/images/Word.png") if attachment.is_word?%>
<br />
<%= link_to attachment.name.to_s,attachment.attachment.to_s>
Say you create a helper method like:
def link_to_attachment attachment
html = ""
html += image_tag(attachment.attachment.url(:thumb)) if attachment.is_image?
html += image_tag("/images/Excel.png") if attachment.is_excel?
html += image_tag("/images/Word.png") if attachment.is_word?
html += "<br />"
html += link_to(attachment.name.to_s, attachment.attachment.to_s)
html.html_safe
end
Then in you view you can replace it with:
<td style="width: 150px;" valign="bottom" align="center">
<%= link_to_attachment attachment %>
</td>
<% #asset.attachments.each_with_index do |attachment, i| %>
&lt% next if attachment.main_image %>
It depends on how you define the main attachment
<% #asset.attachments.each_index do |attachment, i| %>
<% unless attachment.main? %>
...
<% end %>
<% end %>
OR
<% #asset.attachments.each_index do |attachment, i| %>
<% if attachment.main? %>
<% next %>
<% else %>
...
<% end %>
<% end %>
OR put this in your controller
#attachments = #asset.attachments.where(:main => false)
after that, iterate over #attachments instead of #asset.attachments

Resources