Logic inside table. for each loop for formatting - html

Is there a way I could limit the tds to 4 or any number in the following set up ..please see code below. Right now, its displaying all model items in one single row (as it should according to the code). If the items are a dozen, they are all displayed one single row.. I would like a way to display this four in each row instead of all in one row... (am I talking about table inside a table?) can this be done?
<table>
<tr>
#foreach (var item in Model)
{
<td>
#Html.DisplayFor(modelItem => item.fld1)
#Html.DisplayFor(modelItem => item.fld2)
</td>
}
</tr>
</table>

You could group them:
#{
var chunkSize = 4;
var groupedResult =
from i in Model.Select((value, index) => new { Value = value, Index = index })
group i.Value by i.Index / chunkSize into g
select g;
}
<table>
#foreach (var result in groupedResult)
{
<tr>
#foreach (var item in result)
{
<td>
#Html.DisplayFor(modelItem => item.fld1)
#Html.DisplayFor(modelItem => item.fld2)
</td>
}
</tr>
}
</table>
Obviously the fact that you need to do this means that your view model is not adapted to this view. So adapt it and perform this grouping inside your controller action. Then your view will become simple and readable and not resemble some spaghetti code.

Related

How can I assign unique anchor tags to each row to return to that row after a page reload in MVC?

I have a view that contains a table of items. In each row of the table, you have the option to click on a link to edit the item which takes you to a different page. I'm trying to make it so that once you finish editing the item and save your changes, it takes you back to the original view but at the same spot.
So, for example, if you had 300 rows in this table and were working with row 247. I click Edit, make some changes, and when I save I'd like to go back to row 247. Instead, I'm brought back to the top of the page after saving. I've seen some stuff for jquery, but isn't there something simple that can be done in razor with anchor tags?
My Code looks like this:
View
Index.cshtml
...
...
...
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.AID)
</th>
<th>
#Html.DisplayNameFor(model => model.Comment)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.AID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comment)
</td>
<td colspan="5" align="right">
<button type="button" class="btn btn-primary" onclick="location.href='#Url.Action("Edit", new {id = item.AID })'">Action Event</button>
</td>
</tr>
}
</table>
Controller
DatabaseController.cs
public ActionResult Index()
{
return View(db.ActionableEvents.ToList());
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ActionableEvents actionableEvents = db.ActionableEvents.Find(id);
if (actionableEvents == null)
{
return HttpNotFound();
}
return View(actionableEvents);
}
[HttpPost]
public ActionResult Edit([Bind(Include = "AID,Comment")] ActionableEvents actionableEvents)
{
if (ModelState.IsValid)
{
db.Entry(actionableEvents).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(actionableEvents);
}
Ideally, it would be nice in my HttpPost for the Edit to do something like:
return RedirectToAction("Index",idtag);
where idtag could be a route value that loads the page at the specific anchor tag. Something to the effect of "https://www.mywebsite.com/Home/Index#247".
The question is, how can I append the model.AID value to the anchor tag (or maybe just do something in my tag) in my for loop and then reference this in the controller?
Add an id attribute matching the item id to each row:
#foreach (var item in Model)
{
<tr id="#item.AID"> #* assuming AID is the item id (e.g. 247)*#
<td>
#Html.DisplayFor(modelItem => item.AID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comment)
</td>
<td colspan="5" align="right">
<button type="button" class="btn btn-primary" onclick="location.href='#Url.Action("Edit", new {id = item.AID })'">Action Event</button>
</td>
</tr>
}
Then in your controller set the anchor to the html row's id which should be the same as the item id:
return Redirect(Url.Action("Index") + "#" + idtag); // assuming idtag is the item id (e.g. 247)
The idtag anchor must match the table row (tr) id attribute to make the page jump to the row.

Razor table with two columns in mvc

this my controller:
public ActionResult Index(int PID = -1, int TID = -1, string DateT = "")
{
return View(barcodes);
}
in my view :
#model IEnumerable<barkod.Models.Barcode>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.barC)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
</tr>
}
It is okay, but I want the table information to be in two columns.
Just add the table tag around your foreach loop. If you want to have 4 columns you have to add a counter. Either use a for loop instead of foreach (depending on your model type) or add your own row counter.
#model IEnumerable<barkod.Models.Barcode>
#{ int counter = 0; }
<table>
<tr>
#foreach (var item in Model)
{
<td>
#Html.DisplayFor(modelItem => item.barC)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
#if (++counter % 2 == 0)
{
</tr><tr>
}
}
</tr>
</table>
Like this on every 2nd loop a new row is added. You will have to add some additional logic to handle the case when the number of items is not equal.

What is the cleanest way to render a collection into a html table with "n" number of entries per row

I have an asp.net-mvc website. In my viewmodel I have a collection of cars that I want to display on an HTML table.
I want to show 5 cars per row, so I started something like this:
<table>
#foreach (var car in Model.Cars) {
if (counter == 0) {
<tr>
}
<td>#car.Name</td>
counter++;
if (counter == 5) {
</tr>
}
}
</table>
The issues are I feel like the code above is a little hacky and also what if I have 7 cars, should I put 3 blank <td>s in the last row or cut it off (again even more hacky code)?
I wanted to see if there was a cleaner way in an asp.net-mvc to display a collection in a table with a specific number of entries in the table on a row.
If you want to stick to tables, this looks the least hacky to me
#{
var colSize = 5;
var rows = (int)(Model.Cars.Count() / colSize);
}
<table>
#for (var row = 0; row <= rows ; row++){
<tr>
#foreach(var car in Model.Cars.Skip(row * colSize).Take(colSize))
{
<td>#car.Name</td>
}
</tr>
}
</table>
if you want to fill out the last row with <td> elements, you can put this in front of the <tr>:
#if (row == rows)
{
for(var i=0;i<colSize -( Model.Cars.Count() % colSize); i++){
<td></td>
}
}
You could make this slightly cleaner with something along these lines:
<table>
<tr>
#foreach (var car in Model.Cars) {
<td>#car.Name</td>
<!-- If we've output a fifth cell, break to a new row -->
if (++counter % 5 == 4)
{
</tr><tr>
}
}
</tr>
</table>
However it would probably be better to instead output block-level elements with a fixed width and float them left, like this (excuse the inline styles ;-)):
<div style="width: 300px;">
#foreach (var car in Model.Cars) {
<div style="float: left; width: 55px;">#car.Name</div>
}
</div>

How to change span visibility based on table item property

Hi can somebody tell me if it is possible to set the visibility of a basic html element by using a property of the particular row item of the table it is contained within?
Here's some basic psuedo code to give yout some idea of what I'm trying to do.
foreach (var item in group) {
<tr>
<td>
<span if(item.IsApprovedToSayHi) then style="display:none">Hi</span>
foreach (var item in group) {
var displayStyle = item.IsApprovedToSayHi?'display:none':'display:inline';
'<tr>
<td>
<span then style='+displayStyle+'>Hi</span>'
This is how I prefer to do it -- or put a class on it and do it on page load (which may be annoying in some cases).
foreach (var item in group) {
<tr>
<td>
<span <%: (item.IsApprovedToSayHi) ? " style=\"display: none;\" : string.Empty %>>Hi</span>
If you're using the Razor view engine, try this:
foreach (var item in group) {
<tr>
<td>
<span #( item.IsApprovedToSayHi ? " style=\"display: none;\" : string.Empty )>Hi</span>
#foreach (var item in group) {
<tr>
<td>
#if(item.IsApprovedToSayHi) {
<span style="display:none">
} else {
<span>
}
Hi</span>

Split string on MVC3 + razor view

I would like to get help and guide on how can i manipulate text/string that being called from MS-SQL Database. So here is my SettingController.cs partial code for index viewing:
public ActionResult Index()
{
var datacontext = new SGM_SIDDataContext();
var dataToView = from m in datacontext.SGMs
orderby m.Seq
select m;
return View(dataToView.ToList());
}
And This is my index.cshtml codes:
#model IEnumerable<MVC_Apps.Models.SGM>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
SID
</th>
<th>
Abbrev
</th>
<th>
Val
</th>
<th>
Seq
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.SID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Abbrev)
</td>
<td>
#Html.DisplayFor(modelItem => item.Val)
</td>
<td>
#Html.DisplayFor(modelItem => item.Seq)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.GID })
</td>
</tr>
}
</table>
So roughly I got a View. Now here is what i would like to do:
1) The data 'item.Val' on Index.cshtml view will be like this:
A,L,C,H
and sort of like that. But the might be line where the data only contain:
H or C or none(Null value)
But if the data contain more than one char like say it does set for K and L, the data in item.Val will look like this:
A,L
Which the data being separate by comma. So now i want to split that item.Val data and do if statement on it. Where I would like to check every data in item.Val if it contain K or L or C or H or all of them or none of them(Sorry if my english is bad). And I would like to view it as , if all the data contain H so in table view, the will be column named Hotel while if the data also have L so another column of Lounge will be display with a check button being checked.
the possible char in item.Val is:
A = Admin
L = Lounge
H = Hotel
C = Customer
Any help and ideas much appreciated. Thank you in advanced.
Update information:
Thanks Im starting to get what is it. What i really want to do is, when the item.Val does contain H(which is for hotel) then the view will have table column with header name Hotel and at the record it will have tick checkbox.
This is sample picture of table view: http://imagebin.org/152941
But then the Hotel, Admin and User information either it is tick or not is in item.Val
For example for Smith, the item.Val data look like this : C,
For example for Anna , the item.Val data look like this : H,C,
P.S : - the var conf line is a test code. Ignore it as I already delete it from my source. :)
Create a ViewModel similar to
public class MyViewModel
{
// items from your model
public int Id{get;get;}
public String Vals{get;set;} // A,L,C,H
...
...
public bool IsHotel
{
get
{
return Vals.Split(',').Contains("H");
}
}
public bool IsAdmin
{
get
{
return Vals.Split(',').Contains("A");
}
}
public bool IsCust
{
get
{
return Vals.Split(',').Contains("C");
}
}
}
In the controller action
public ActionResult Index()
{
var datacontext = new SGM_SIDDataContext();
var dataToView = from m in datacontext.SGMs
orderby m.Seq
select new MyViewModel()
{
// items from your datacontext
Id= m.SID,
//etc...
};
var conf = from m in datacontext.SGMs // what's the purpose of this query??
select m.Val;
return View(dataToView.ToList());
}
The View will need to be updated, so include columns for Hotel, Cust, Admin and any others you need. I would suggest that you keep it simple and don't try to create the HTML columns on the fly. If you want to do this, you probably will need to inspect all Vals in every object of your list first to determine what columns are needed. In the view
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.SID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Abbrev)
</td>
<td>
#(item.IsHotel? "Checked" : "")
</td>
<td>
#(item.IsAdmin? "Checked" : "")
</td>
<td>
#(item.IsCust? "Checked" : "")
</td>
<td>
#Html.DisplayFor(modelItem => item.Seq)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.GID })
</td>
</tr>
}