Change table row colour on condition in Rails - css

I'm creating multiple tables by date and I want my html table rows to be a different colour depending on a number of conditions. With the help of this question I tried out the following in my shift view:
<% (Date.current - 6.months..Date.current + 6.months).each do |date|%>
<% if !Shift.where(date: date).blank? %>
<% #shifts = LaunchShift.where(date: date).all.order(start_time: :asc, booked: :desc) %>
<h2><%= date.strftime('%e %b %Y') %></h2>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>...</th>
</tr>
</thead>
<% #shifts.each_with_index do |shift, index| %>
<% if shift.booked? %>
<% #booker = Member.find(shift.booked_by) %>
<% end %>
<tbody>
<% if shift.booked? %> <---Trying this for changing colour
<tr style="background-color:red">
<% else %>
<tr>
<% end %>
<td><%= shift.start_time.strftime("%H:%M") %></td>
<% if shift.booked? %>
<td>Booked</td>
<td><%= link_to #booker.name, member_path(#booker) %></td>
<% else %>
<td>Free</td>
<td></td>
<% end %>
[...]
</tr>
</tbody>
<% end %>
</table>
</div>
<% end %>
But only some of the rows marked as booked are red, though the shifts.booked? returns as True. Does this approach work differently than I think it does? Is there a better way to do this that that doesn't use JS/JQuery (Don't know those). Any advice?
Thank you!

You can try like
.booked{
background-color: red;
}
.available{
background-color: grey;
}
<tr class="<%= shift.booked? ? 'booked' : 'available' %>">
</tr>
If shift is booked then booked class will apply otherwise available class will apply using ternary operator.

#ashvin's solution is fine but it would be nice to go one step farther and put the ternary operator into a helper method, thereby keeping your view free of logic. e.g.
<tr class="<%= booked_class(shift) %>">
create a shift_helper.rb file in the helpers folder
module ShiftHelper
def booked_class(shift)
shift.booked? ? "booked" : "available"
end
end

Related

How to display empty td values which is coming from loop in a table in Rails views

https://i.stack.imgur.com/7M5eg.png
I have to show the images in a table td column. So, I wrote the loop for one td to show at least four images according to uploads. But when images attachments less than 4 another column values shifting to this td column. So, I need to display the empty one also. How to solve it. Here is my code
<% hp.fi_attachments.last(4).each_with_index do |fi,index| %>
<td>
<div class="image_address">
<%= image_tag fi.image, :class => "style_image"%>
</div>
</td>
<%end%>
Try this:
<% last_four = hp.fi_attachments.last(4) %>
<% 4.times do |index| %>
<td>
<% if last_four[index] %>
<div class="image_address">
<%= image_tag last_four[index].image, :class => "style_image"%>
</div>
<% end %>
</td>
<% end %>

How to convert a SQL query to a multidimensional hash?

I am wishing to have a multidimensional hash, given a query which joins 4 relevant tables.
Mainly I want this to serve a screen where I have three levels of information. When I click Process, I get a table with activities, and when clicking activities, get a table with both pollution_origins and sub_pollution_origins.
So, I have 5 models, where one of them is a relational one (process_model_maps), which connects the other four.
There is an hierarchy between them (sub_pollution_origin_models are inside pollution_origin_models, which are inside of activity_models, which are part of at least one process_model)
Currently I have this:
_process_models_maps_list.html.erb
<table id="all_processes">
<tbody>
<% #process_models.each do |process_model| %>
<tr class="process_line_color"> <td><%= process_model.name %></td> </tr>
<tr>
<%= render partial: "process_activities",
locals: { process_model: process_model} %>
</tr>
<% end %>
</tbody>
</table>
_process_activities.html.erb
<table id = "process_activities">
<tbody>
<% process_model.activity_models.each do |activity_model| %>
<tr class="activity_line_color"> <td><%= activity_model.name %></td> </tr>
<tr>
<%= render partial: "activity_sub_pollution_origin_models",
locals: { activity_model: activity_model} %>
</tr> <!-- row activity_model details-->
<% end %>
</tbody>
</table>
_activity_sub_pollution_origin_models.html.erb
<table id = "activity_details">
<tbody>
<% activity_model.process_model_maps.each do |process_model_map| %>
<tr>
<td> <%= process_model_map.pollution_origin_model.name %></td>
<td> <%= process_model_map.sub_pollution_origin_model.name %> </td>
</tr>
<% end %>
</tbody>
</table>
The issue is that if I just use regular activerecord, rails goes on and sets a great number of queries, which kills performance for the screen.
So I thought that if I had a pre-loaded hash somehow, this would make the task easier for the end user.
in my ProcessModel.rb I have
def self.get_tree_map
joins(process_model_maps: [:activity_model, :pollution_origin_model, :sub_pollution_origin_model]).select("process_models.id, process_models.name, activity_models.id,activity_models.name, process_model_maps.id , pollution_origin_models.name,sub_pollution_origin_models.name")
end
and am now thinking on getting something like:
{Project_id: 1, name: Fundicao, {activity_id:1, name: Decapagem,{process_model_maps_id: 2, pollution_origin_models_id: 1, pollution_origin_models_name: " Energia ", sub_pollution_origin_models_id: 1, sub_pollution_origin_models_name: "Energia Eletrica" },...}}}
In your controller:
#process_models = Process.all.joins(:activities).merge(
Activity.joins(:pollution_origins))
That should fetch all of the data you want with a single SQL call.

Rails, is it possible to change the css depending on the value of an model column?

Lets say i have a table like this:
I want to style the rows of the table dependent on the type {id1: 'Anamnse', id2: 'Befund', id3: 'Therapie'}. Manually i would simply add the bootstrap classes
My question is how can I achieve this automatically with ruby? Here is my code, for the table:
<table id="report" class="table table-striped ">
<tr>
<th>Typ</th>
<th>Beschreibung</th>
<th>Datum</th>
<th> </th>
</tr>
<% #patient.treatments.each do |treatment| %>
<tr>
<td><%= treatment.category.try(:typ) %></td>
<td><%= treatment.content %></td>
<td><%= treatment.day %></td>
<td><div class="arrow"></div></td>
</tr>
<tr>
<td colspan="5">
<%= link_to 'Löschen', [treatment.patient, treatment],
:confirm => 'Sind sie sicher?',
:method => :delete %>
<% treatment.paintings.each do |paint| %>
<%= image_tag paint.name.url(:thumb) %>
<% end %>
</td>
</tr>
<% end %>
</table>
For conclusion: The styling has to be dependent on the value of the
<td><%= treatment.category.try(:typ) %></td>
You can also use an helper method in this way
<td <%= row_classname(:typ) %> ><%= treatment.category.try(:typ) %></td>
and in your related helper
def row_classname(type)
switch type
when "somevalue"
classname = "someclass"
when "othervalue"
classname = "otherclass"
"class=\"#{classname}\"" unless classname.nil?
end
or something similar
You could define mapping, e.g.:
category_classes = { "Anamnse" => "success", "Befund" => "warning", "Therapie" => "error" }
And use this mapping to assign the class:
<% category_classes = { "Anamnse" => "error", "Befund" => "warning", "Therapie" => "success" } %>
<% #patient.treatments.each do |treatment| %>
<tr class="<%= category_classes[treatment.category.try(:typ)] %>">
You could also extract this as a helper method, e.g. in app/helpers/application_helper.rb:
def category_table_row_class(category_typ)
{ "Anamnse" => "success", "Befund" => "warning", "Therapie" => "error"}[category_typ]
end
Or use category.id instead:
def category_table_row_class(category)
{ 1: "success", 2: "warning", 3: "error"}[category.id]
end
And call it like:
<tr class="<%= category_table_row_class(treatment.category) %>">
BTW, you should use <thead> and <tbody> for the head and body sections.
Don't try to "dynamically change the CSS". That's not how CSS is meant to work. Instead, conditionally add a class to the element, and write some new CSS which targets that class.
Something like this:
<tr class="<%= treatment.category.try(:typ) %>">
<tr class="<%= treatment.category.try(:typ) %>">
This will add to tr class equal to typ value.

How to get confirmed list (IEnumerable) in HttpPost method?

in my ASP .Net MVC 2 application the user is shown a list of items and must click confirm before the list is persisted to the database.
When the user clicks confirm, in the HttpPost method the parameter is null. Everything works until the HttpPost method is called. At this point the list that must be persisted is null.
How do I get the confirmed values ?
I've tried using TempData in the HttpGet method but TempData is also null in the HttpPost method.
Here is the controller code.
public ActionResult Confirm()
{
List<ConfirmVehicleModel> vehicles = GetAllVehicles();
return View(vehicles);
}
[HttpPost]
public ActionResult Confirm(List<ConfirmVehicleModel> model)
{
//model is null, why ?
UploadVehiclesModelService service = new Models.UploadVehiclesModelService();
service.StoreVehicles(model, User.Identity.Name);
return RedirectToAction("Index", "UploadVehicles");
}
And here is the Confirm view:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<RM.Application.Models.ConfirmVehicleModel>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Confirm
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
Confirm that the vehicles below should be added.</h2>
<table>
<tr>
<th>
ReferenceType
</th>
<th>
ReferenceName
</th>
</tr>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%= Html.Encode(item.ReferenceType) %>
</td>
<td>
<%= Html.Encode(item.ReferenceName) %>
</td>
</tr>
<% } %>
</table>
<div>
<% using (Html.BeginForm())
{ %>
<input type="submit" value="Confirm" />
|
<%= Html.ActionLink("Back to upload form", "Index") %>
<% } %>
</div>
</asp:Content>
Thanks for any help,
Kind regards
Bob
Your HTML.BeginForm() is out of place it should surround the values you wish to pass.
Try:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Confirm that the vehicles below should be added.</h2>
<% using (Html.BeginForm())
{ %>
<table>
<tr>
<th>
ReferenceType
</th>
<th>
ReferenceName
</th>
</tr>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%= Html.Encode(item.ReferenceType) %>
<%= Html.HiddenFor(model => item.ReferenceType)%>
</td>
<td>
<%= Html.Encode(item.ReferenceName) %>
<%= Html.HiddenFor(model => item.ReferenceName)%>
</td>
</tr>
<% } %>
</table>
<div>
<input type="submit" value="Confirm" />
|
<%= Html.ActionLink("Back to upload form", "Index") %>
<% } %>
</div>
Nicholas advice helped. I replaced the foreach loop with a for loop and used Html.HiddenFor.
<% for (int i = 0; i < Model.Count(); i++)
{ %>
<%= Html.HiddenFor(model=>model[i].ReferenceType) %>
<%= Html.HiddenFor(model=>model[i].ReferenceName) %>
<tr>
<td>
<%= Html.Encode(Model[i].ReferenceType) %>
</td>
<td>
<%= Html.Encode(Model[i].ReferenceName) %>
</td>
</tr>
<% } %>
I also changed the top line of the the view to (previously IEnumerable, now List).
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<RM.Application.Models.ConfirmVehicleModel>>" %>\\
The List<ConfirmVehicleModel> model parameter of the HttpPost method is now populated.

ASP.NET MVC View with embedded code displays html out of sequence

I have a view in ASP.NET MVC. It takes the model object and iterates over a list of strings and displays them in a table row, like so:
Details
<table>
<tbody>
<tr>
<th>Values in the database</th>
</tr>
<% foreach (string value in Model.lstDistinctValues)
{%>
<tr>
<%=value%>
<%} %>
</tr>
</tbody>
The problem is that the values appear ABOVE the header. So 'Values in the database' appears at the bottom, while the values are at the top.
Why would this be happening?
You need to add TD elements.
<table>
<tbody>
<tr>
<th>Values in the database</th>
</tr>
<% foreach (string value in Model.lstDistinctValues)
{%>
<tr>
<td><%=value%></td>
</tr>
<%} %>
</tbody>
</table>

Resources