Div Tables with ASP.NET MVC - html

I'm trying to find a better way to use a div table with ASP.NET MVC, the problem I see is that you need to do loads of looping, rather than one loop if I had to use a traditional <table> table.
Example
<div class="column">
<div class="row">Name</div>
<% foreach (Person person in (List<Person>)ViewData.Model) {%>
<div class="row"><%= Html.Encode(person.Name) %></div>
<%} %>
</div>
<div class="column">
<div class="row">Email</div>
<% foreach (Person person in (List<Person>)ViewData.Model) {%>
<div class="row"><%= Html.Encode(person.Email) %></div>
<%} %>
</div>
<div class="column">
<div class="row">Phone</div>
<% foreach (Person person in (List<Person>)ViewData.Model) {%>
<div class="row"><%= Html.Encode(person.Phone) %></div>
<%} %>
</div>

If it looks like a table and smells like a table why not use a table?
But if you want to do it in this way well try to build a extention method for your Html property that generates this html code and have the list as a parameter and maybe a list for your columns, To generate your html code you can use the TagBuilder class.

It's rather subjective issue, but I think you don't really need to use divs to do so, coz you are simply displaying table of data and this is why we need "table" tag.
The introduction of div and CSS layout is not to replace the table tag, but to free table tag from doing formatting and layout job.
Edit
Moreover, you can still do your job in one loop. Rather than loop through columns, why not loop through rows (name, phone... )
<% foreach(Person person in (List<Person>)ViewData.Model)) %>
<div class="row">
Name: <%= Html.Encode(person.Name) %>
Email: <%= Html.Encode(person.Email) %>
...
</div>
Although I personally still prefer using table (together with tr and td) instead.

If you are dislaying tabular data, that's why the table tag is there. People only suggest div, instead of table when it's about layout. So it's perfectly OK to use the table tag when you are displaying key-value type of information.

I agree with what everyone else have said (that you really should just use a table) - however I will try to come up with a solution to your issue too.
I don't think there's an elegant way to overcome the "loop more than once" issue, but at the very least we can make it a bit "easier" to add new columns to the list:
var myList = (List<Person>)ViewData.Model;
var myColumns = new Dictionary<string, List<string>>();
myColumns.Add("Name", new List<string>());
myColumns.Add("Email", new List<string>());
myColumns.Add("Phone", new List<string>());
foreach(var person in myList){
myColumns["Name"].Add(Html.Encode(person.Name));
myColumns["Email"].Add(Html.Encode(person.Email));
myColumns["Phone"].Add(Html.Encode(person.Phone));
}
Then now you can do this:
<% foreach(var column in myColumns){ %>
<div class="column">
<div class="row"><%= column.Key %></div>
<% foreach (string value in column.Value) {%>
<div class="row"><%= value %></div>
<%} %>
</div>
<% } %>
It is still poor performance compared to using the -tag and really I don't see why you'd want to avoid that in this scenario.

Related

Can't access deeply nested objects and arrays in EJS template

Hello fellow stackers,
I trying to get the following response to my EJS template.
Currently I have a for-loop which iterates all campaigns.
campaigns.facebook.data[i].insights .data
Just tried this, which works fully and the output is being shown below:
<% switch (campaigns.facebook.data[i].status) {
case 'ACTIVE' : %>
<div class="ui grid">
<p><%- JSON.stringify(campaigns.facebook.data[i].insights) %></p>
...
However, while trying to get the .data object I encounter problems
<p><%- JSON.stringify(campaigns.facebook.data[i].insights.data) %></p>
Even while trying JSON.stringify(campaigns.facebook.data[i].insights.data[0]) doesn't give any luck. What is possibly wrong here?
After adding a conditional statement for checking if the desired object exist, we won't encounter the undefined error anymore.
<% if (campaigns.facebook.data[i].insights) { %>
<p><%- JSON.stringify(campaigns.facebook.data[i].insights.data[0]) %></p>
<%console.log(campaigns.facebook.data[i].insights.data[0])%>
% } %>

How to assign an div id a variable without using Javascript?

I'm trying to create multiple divs inside a for loop on a jsp page. I'm loading all the posts in a forum from a database, each one being a new div. I'm trying to make divs having id like id= "post-" + title, where title is a variable.
I tried with this way of puting out.printlnt(title) and is not working, I also found a solution saying to put smth like div id = {{title}} that still didn't work. Do you know if is possible to do this without using javascript? I just want to assign the id from the for loop.
for (ForumPost fp : allForumPosts) {
//get title and likes variables
<div id = "<%out.println(title);%>" >
<%out.println(title); out.println(likes);%>
<a>LIKE</a>
</div>
}
If you don't mind using jstl (which is preferred way to scriptlets) you can do this the following way:
<c:forEach var="post" items="${allForumPosts}">
<div id="post-${post.title}">
${post.title}; ${post.likes} <a>LIKE</a>
</div>
</c:forEach>
Just make sure to include this tag at the top of your jsp:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
If you want to use scriptlets as you do now, I think you should do something like:
<% for (ForumPost fp : allForumPosts) {%>
<div id="post-<%out.write(fp.title)%>">
<%out.write(fp.title)%>;<%out.write(fp.likes)%>
<a>LIKE</a>
</div>
<% } %>
But you really should consider using jstl instead of scriptlets
Java Server Pages (JSP) is a server-side programming technology for your front-end.
Assuming that you have passed the object from your controller to JSP, then you can achieve the desired for loop with JSTL
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${allForumPosts}" var="post">
<div id="post-${post.title}"></div>
</c:forEach>
If you however prefer scriptlet (not recommended), here is how it's done
<% for (ForumPost post : allForumPosts) { %>
<div id="post-<%=post.title%>"></div>
<% } %>

Empty div is showing up with ruby .each enumerable on HTML.erb page.

I can't seem to figure out why my ruby .each enumerable is churning out an empty div if my array of objects is empty, or adding an empty div at the bottom if there is one object in my #posts variable.
Here is my index.html.erb page:
<div id="post_feed">
<%if #posts.any?%>
<%#posts.each do |p|%>
<div class="post_text_box">
<%=p.body%>
</div>
<%end%>
<%end%>
</div>
Post Controller:
def index
#posts = current_user.posts
#new_post = current_user.posts.new
end
CSS:
#post_feed{
margin-right:auto;
margin-left:auto;
width:400px;
}
.post_text_box{
padding:10px;
margin:10px;
background-color:#FFFFFF;
}
rails console shows 1 item.
irb(main):014:0> Post.count
(1.3ms) SELECT COUNT(*) FROM "posts"
=> 1
Here is an image of the empty div.
I figured it out. In my controller, I am creating an new object but not saving it. My .each iterator is recognizing it as an object in my #posts object array even though its not saved.
I fixed it by check if the record was new using the new_record? method.
<div id="post_feed">
<%if #posts.any?%>
<%#posts.each do |p|%>
<%if ! p.new_record?%>
<div class="post_text_box">
<%=p.body%>
</div>
<%end%>
<%end%>
<%end%>
</div>
Even though it hasn't been saved yet, Rails is considering the #new_post to be part of current_user.posts, so you have a blank post at the end of your #posts list.
It doesn't turn up in the database query because it hasn't been saved.
Depending on what you need to do, you could make #new_post just an empty post (#new_post = Post.new) and assign the user when saving.
Or in your each loop you you can check to see if the post has a body before creating the div if you can rely on that check to give you the results you want:
<div id="post_feed">
<%#posts.each do |p|%>
<% if p.body %>
<div class="post_text_box">
<%=p.body%>
</div>
<%end%>
<%end%>
</div>
You don't need the if #posts.any? check as it will always evaluate to true because of the new post created with #new_post = current_user.posts.new.
And generally in ruby, you won't need to check if an array is empty before running an each loop because the each loop won't do anything (or throw an error) with an empty array.

The "show" page isn't displaying the property of the correct data

I'm making a website using ror and I have a list of fandoms, and I want to display different pictures and writing for that fandom. Right now, just for testing, I'm having it just display the name of the fandom at the top of the page, but no matter which one I click on, it only displays the name of the first fandom. Here's the parts of the files I think are relevant, but if you need to see more, I'll post it.
Section of routes.rb:
get 'fandoms' => 'fandoms#index'
get 'fandoms/new' => 'fandoms#new'
post 'fandoms' => 'fandoms#create'
get 'fandoms/:id' => 'fandoms#show', as: :fandom
resources :fandoms
The show method in fandoms_controller:
def show
#fandom = Fandom.find_by(params[:id])
end
The index.html.erb for fandoms:
<div class="main">
<div class="container">
<h2>Fandoms</h2>
<%= link_to "New Fandom (dev only)", "fandoms/new" %>
<% #fandoms.each do |fandom| %>
<div class="fandoms">
<%= link_to fandom.name, fandom_path(fandom) %>
</div>
<% end %>
</div>
And finally the show.html.erb for fandoms:
<div class="main">
<div class="container">
<h2>Fandoms</h2>
<div class="fandom">
<h1><%= #fandom.name %></h1>
</div>
</div>
</div>
I double checked my code with the Ror tutorial on codecademy, but I still couldn't find any differences for what I wanted to do.
Thanks.
Your show action has a subtle typo that's breaking your logic:
#fandom = Fandom.find_by(params[:id])
Should actually be:
#fandom = Fandom.find(params[:id])
The difference is, find_by will return the first row for which the conditions passed are met. You're not actually passing any conditions; just an ID, which in Postgres doesn't even work:
irb> Fandom.find_by(1)
PG::DatatypeMismatch: ERROR: argument of WHERE must be type boolean, not type integer
LINE 1: SELECT "fandoms".* FROM "fandoms" WHERE (1) LIMIT 1
Your database is more permissive, but seems to be treating it just as a WHERE TRUE clause and thus every single row meets the condition. As such, it returns the first row every time. Using find(id) will give you the desired result.

input type button value not formatting HTML properly

I am pulling values from a database which are formatted as so:
147 cm<sup>2</sup>
The aim is to make the 147 cm value squared, but in the button elements it displays as 147 cm<sup>2</sup>
Here is my code, any help would be greatly appreciated:
<div class="catbuttons">
<% foreach (var ssitem in item.Items) { %>
<input type="button" class="BTN-FPC answer floatleft" value='<%: #Html.Raw(ssitem.itemvalue) %>' id='<%:ssitem.itemid %>' name='answer' />
<% } %>
</div>
An interested point is it works when the values aren't being inserted into button elements as such:
<div>
<% foreach (var ssitem in item.Items) { %>
<p style="text-align: justify;"><%: #Html.Raw(ssitem.itemvalue) %></p>
<% } %>
</div>
I found a solution in case any one with the same issue happens upon this question:
You can just paste a superscript 2 from the character map into your database. Simple solution.