Razor View dynamic table rows - c#

I want have a table in my view that is going to put 3 elements from my Model in each row. So the way I was going to do this is to loop through the model and inside of the foreach loop do a check on a count variable I have set up. If count mod 3 == 0 I would do something like </tr><tr> to start a new row. This isn't working the way I want it to because I would have a } following the <tr>. So basically my question is, how would I create a dynamic table inside of a razor view based on the elements in the model where each row has 3 items?
#{
int count = 0;
<div>
<table>
<tr>
#foreach (var drawing in Model)
{
<td style="width:240px;margin-left:30px; margin-right:30px;">
<img src="#Url.Action("GetImage", "Home", new { id = drawing.drw_ID })" alt="drawing" />
</td>
count++;
if(count%3==0)
{
</tr>
<tr>
}
}
</tr>
</table>
</div>
}
Maybe there is a much easier way of doing this that I am not thinking of

How about using two loops - this will make your document be setup much more nicely and make it a bit more readable. Also, it takes care of the problems that occur if the number of rows is not divisible by three:
<div>
<table>
#for(int i = 0; i <= (Model.Count - 1) / 3; ++i) {
<tr>
for(int j = 0; j < 3 && i + j < Model.Count; ++j) {
<td style="width:240px;margin-left:30px; margin-right:30px;">
<img src="#Url.Action("GetImage", "Home", new { id = Model[i + j].drw_ID })" alt="drawing" />
</td>
}
</tr>
}
</table>
</div>
Edited to reflect your pasted code. Note, this assumes the model implements IList or an array

Maybee this is the solution you are looking for works for me
#{
int count = 0;
**
var tr = new HtmlString("<tr>");
var trclose = new HtmlString("</tr>");
**
<div>
<table>
<tr>
#foreach (var drawing in Model)
{
<td style="width:240px;margin-left:30px; margin-right:30px;">
<img src="#Url.Action("GetImage", "Home", new { id = drawing.drw_ID })" alt="drawing" />
</td>
count++;
if(count%3==0)
{
**
trclose
tr
**
}
}
</tr>
</table>
</div>
}

Check this out, this should work for you !!!
<h2>Index</h2>
<table>
<tr>
#{
var index = 0;
}
#foreach (int num in Model)
{
if ((index % 10) == 0)
{
#Html.Raw("</tr>");
#Html.Raw("<tr>");
}
<td>
<h2>#num</h2>
</td>
index++;
}
</tr>
</table>

The #christian solution worked for me.I was not sure of "trclose" and "tr" hence posting here the solution that worked for me in razor view.
<table>
<tr><td><input type="checkbox" id="chkAssetCategories" /> SELECT ALL</td></tr>
<tr>
#{
var count=0;
foreach (var item in Model.AssetCategories)
{
<td><input type="checkbox" class = "Catgories" id='#item.ID' value ='#item.ID' /><label>#item.Name</label></td>
if (count%5 == 0)
{
#:</tr><tr>
}
count++;
}
}
</table>

#{ int counter = 0;}
<div>
<table>
#for(int i = 0; i <= (Model.Count - 1) / 3; ++i) {
<tr>
for(int j = 0; j < 3; ++j) {
<td style="width:240px;margin-left:30px; margin-right:30px;">
#Model[counter]
</td>
counter++;
}
</tr>
}
</table>
</div>

Related

Out of stock message passed to View If quantity <= 0

The problem is that if i have 2 items in cart that do not have the desired amount in stock, it will show only a message for one of them. Also i do not know how i can pass the information at catch{} part. Can someone please point me in the right direction, i am relatively new to asp.net mvc and programming in general.
There is a constraint in db to check quantity >= 0
Controller
public ActionResult CreateOrder()
{
List<ItemViewModel> cart = (List<ItemViewModel>)Session["cart"];
Check check = new Check();
decimal s = 0;
foreach (var item in cart)
{
var device = db.Devices.Single(d => d.DeviceID == item.Device.DeviceID);
if (device.Quantity <= 0)
{
TempData["Message"] = string.Format("Out of stock for {0}. In stock: {1}. ", device.DeviceName, device.Quantity);
return View("Cart");
}
device.Quantity -= item.Quantity;
check.DateTime = DateTime.Now;
check.CustomerName = User.Identity.Name;
s = s + item.Device.Price.Value * item.Quantity;
check.Device += item.Device.DeviceName + " x " + item.Quantity + " - $" + (item.Device.Price *= item.Quantity) + ", " ;
}
check.Total = (int)s;
check.Tax = check.Total * 20 / 100;
try
{
db.Checks.Add(check);
db.SaveChanges();
foreach (var item in cart.ToList())
{
cart.Remove(item);
}
}
catch (DbUpdateException)
{
TempData["Message"] = TempData;
return View("Cart");
}
if (User.IsInRole(RoleName.Admin))
{
return RedirectToAction("Details", "Checks", new { id = check.CheckID });
}
return RedirectToAction("PurchaseDetails", "Checks", new { id = check.CheckID });
}
View
#{
ViewBag.Title = "Cart";
}
#using WebShop.ViewModels;
<h2>Cart</h2>
<br />
#using (#Html.BeginForm("Update", "Devices", FormMethod.Post))
{
<div class="col-lg-12 col-md-12 col-sm-12">
<table class="table table-bordered table-hover" cellpadding="2" cellspacing="2" border="1">
<thead>
<tr>
<th width="5%"></th>
<th>Device</th>
<th width="7%">Price</th>
<th width="7%">Quantity</th>
<th width="7%">Total</th>
<th width="9%"></th>
</tr>
</thead>
<tbody>
#{
decimal s = 0;
decimal total = 0;
int index = 1;
decimal one = 0;
}
#foreach (ItemViewModel item in (List<ItemViewModel>)Session["cart"])
{
s = s + item.Device.Price.Value * item.Quantity;
one = item.Device.Price.Value;
total = item.Device.Price.Value * item.Quantity;
<tr>
<td><img src="#item.Device.Image" width="50" height="50" /></td>
<td>#item.Device.DeviceName</td>
<td>$#one.ToString("n2")</td>
<td><input class="form-control" type="text" name="quantity" value="#item.Quantity" style="width: 50px"></td>
<td>
$#total.ToString("n2")
#{index++;}
</td>
<td>
<button type="button" class="btn btn-bitbucket" onclick="location.href='#Url.Action("Remove", "Devices", new { id = item.Device.DeviceID })'">
<i class="fa fa-remove"></i>
</button> |
<button type="submit" class="btn btn-bitbucket">
<i class="fa fa-refresh"></i>
</button>
</td>
</tr>
}
<tr>
<td align="right" colspan="4">Total:</td>
<td>$#s.ToString("n2")</td>
</tr>
</tbody>
</table>
</div>
}
<br />
<button class="btn btn-bitbucket" type="button" onclick="location.href='#Url.Action("Shop", "Devices")'">Continue shoping</button>
<button class="btn btn-bitbucket" type="button" onclick="location.href='#Url.Action("CreateOrder", "Devices")'">Create order</button> | #TempData["Message"]
Thanks mjwills for the problem location :)
Do not know if this is the best solution but it's working so i am happy with it.
if (device.Quantity <= 0)
{
foreach (var outOfStockItem in cart)
{
string messages = string.Format("Out of stock for {0}. In stock: {1}. | ", outOfStockItem.Device.DeviceName, outOfStockItem.Device.Quantity);
TempData["Messages"] += messages;
}
return View("Cart");
}
Cart Image

asp.net paramter always null

I have a problem with my asp.net app. This is my index.html
#using BricksBreaking;
#model FieldModel
#{
ViewData["Title"] = "Game";
}
<h2>Index</h2>
<table class="field">
#for (int row = 0; row < Model.Field.RowCount; row++)
{
<tr>
#for (int column = 0; column < Model.Field.ColumnCount; column++)
{
var tile = Model.Field.Tiles[row, column];
if (tile == null)
{
<td />
}
else
{
if (Model.Field.Tiles[row, column].Color == TileColor.Red) {
<td>
<a href='/BricksBreaking/Click?r=#row?c=#column'>
<img src='/images/cervena.png' />
</a>
</td>
}if(Model.Field.Tiles[row, column].Color == TileColor.Yellow)
{
<td>
<a href='/BricksBreaking/Click?r=#row?c=#column'>
<img src='/images/zlta.png' />
</a>
</td>
}if(Model.Field.Tiles[row, column].Color == TileColor.Blue)
{
<td>
<a href='/BricksBreaking/Click?r=#row?c=#column'>
<img src='/images/modra.png' />
</a>
</td>
}
}
}
</tr>
}
</table>
And this is my controller
public class BricksBreakingController : Controller
{
ScoreServiceDatabase scoreService = new ScoreServiceDatabase();
public IActionResult Index()
{
var field = new Field(9, 9, 5);
HttpContext.Session.SetObject("field", field);
var model = new FieldModel
{ Field = field, Scores = scoreService.GetTopScores() };
return View(model);
}
public IActionResult Click(int r, int c)
{
var field = HttpContext.Session.GetObject("field") as Field;
field.ClickTile(r,c);
HttpContext.Session.SetObject("field", field);
var model = new FieldModel
{ Field = field, Scores = scoreService.GetTopScores() };
return View("Index", model);
}
}
}
Problem is. that always here at this line
<a href='/BricksBreaking/Click?r=#row?c=#column'>
Arguments passed to Function Click in controller are always 0. No matter if i write something like this
<a href='/BricksBreaking/Click?r=2?c=2'>
There will be always 0.
Can somebody help me with this? I am new to .NET.
You only need to write a ? before the first parameter. Every parameter after the first needs a &
<a href='/BricksBreaking/Click?r=2&c=2'>

How to correctly get separate values from HTML in C# [duplicate]

I start my code with:
private int GetSizeOf(IEnumerable<HtmlNode> tables)
{
int size = 0;
var infos = tables.ElementAt(0).Elements("td");
foreach (var info in infos)
size++;
return (size);
}
private void saveButton_Click(object sender, EventArgs e)
{
var doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(tooltip.GetToolTip(labelFile));
var element = doc.DocumentNode
.Element("html")
.Element("body")
.Element("div")
.Element("center");
var tables = element.Elements("table").ElementAt(2).Elements("tr");
arrayInfos = new string[GetSizeOf(tables), tables.Count()];
}
I would like get value of a table (td) in html, I would like also stored all values in a multidimensional array (display_name (0.x), pseudo (1.x), age (2.x), confirmed (3.x), admin (4.x))
The html code look likes this:
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" width="80%">
<tr>
<td nowrap bgcolor="#FFFFCE"><b><font color="#DC883D">display_name</font></b></td>
<td nowrap bgcolor="#FFFFCE"><b><font color="#DC883D">pseudo</font></b></td>
<td nowrap bgcolor="#FFFFCE"><b><font color="#DC883D">age</font></b></td>
<td nowrap bgcolor="#FFFFCE"><b><font color="#DC883D">confirmed</font></b></td>
<td nowrap bgcolor="#FFFFCE"><b><font color="#DC883D">admin</font></b></td>
</tr>
<tr>
<td bgcolor="#FFF7F2">Example</td>
<td bgcolor="#FFF7F2">Example</td>
<td bgcolor="#FFF7F2">20</td>
<td bgcolor="#FFF7F2">1</td>
<td bgcolor="#FFF7F2">0</td>
</tr>
How can I do that ?
var doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(...);
var element = doc.DocumentNode
.Element("html")
.Element("body")
.Element("div")
.Element("center");
var trs = element.Element("table").Elements("tr").ToArray();
var array = new string[trs.Length, trs[0].Elements("td").Count()];
for (int row = 0; row < trs.Length; row++)
{
var tds = trs[row].Elements("td").ToArray();
for (int col = 0; col < tds.Length; col++)
{
array[row, col] = tds[col].InnerText;
}
}

Cant get model fields to display on the page

I'm using this model:
public class ListCoins
{
public Dictionary<string,Dictionary<string,float>> listCoins{ get; set; }
}
when I try to display them in the view using this method:
model IEnumerable<Crytocurrency_Web___Main.JResult.ListCoins>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<h4>Coin Value: #ViewBag.WalletValue</h4>
<table class="table">
<tr>
<th>
#Html.DisplayName("Name"))
</th>
<th>
#Html.DisplayName("CoinValue")
</th>
<th>
#Html.DisplayName("CoinAmmount")
</th>
<th></th>
</tr>
#for (var i = 0; i < Model.ElementAt(i).listCoins.Count; i++)
{
foreach (var coin in Model.ElementAt(i).listCoins)
{
<p>#coin.Key + " " + #coin.Value)</p>
}
}
i get the error on the line:
#for (var i = 0; i < Model.ElementAt(i).listCoins.Count; i++)
but in the controller i have checked that count is over one:
int counter = listOfCoins.Count;
which equals four and all the data is there.
i may just be displaying them wrong but i cant figure it out
controller code:
List<ListCoins> newListCoins = new List<ListCoins>();
foreach (var coin in listOfCoins)
{
using (WebClient client = new WebClient())
{
var json = client.DownloadString(
"https://min-api.cryptocompare.com/data/pricemulti?fsyms=" + queryString + "&tsyms=" +
queryString);
var result = Newtonsoft.Json.JsonConvert
.DeserializeObject<Dictionary<string, Dictionary<string, float>>>(json);
newListCoins.Add(new ListCoins
{
listCoins = result,
});
}
}
return View(newListCoins.ToList());
I don't think you need to use: Model.ElementAt(i). You can do this:
#for (var i = 0; i < Model.listCoins.Count; i++)
rather than this:
#for (var i = 0; i < Model.ElementAt(i).listCoins.Count; i++)
You can then loop through all of the elements in listCoins and display the values in the view.
You are getting ArgumentOutOfRangeException because you are trying to access an item in the collection with an index which does not exist!
This part in your for loop
i < Model.ElementAt(i).listCoins.Count
You are trying to loop until n where n is the Count of your child property listCoins of each item.
Your view is strongly typed to a collection of ListCoins. So Your outer loop should be from 0 to Model.Count
#for (var i = 0; i < Model.Count; i++)
{
foreach (var coin in Model.ElementAt(i).listCoins)
{
<p>#coin.Key + " " + #coin.Value)</p>
}
}
Here , the coin.Value is again another dictionary(Dictionary<string,float>), so you probably want to loop through the items in that as well.
I feel the foreach version could be more readable.
#foreach (var item in Model)
{
foreach (var coin in item.listCoins)
{
<h1>#coin.Key</h1>
foreach (var v in coin.Value)
{
<p>#v.Key - #v.Value</p>
}
}
}

Programmatically start new TableRow in table

I am trying to load models and set every model in a separate, <td> when I reach 5 <td> I want to automatically start a new <tr> but it isn't really working with an if statement. Is it possible or should I go for an entire different approach?
Here is my code:
<tr>
#for (int i = 0; i < Model.Count; i++)
{
<td>
<img width="200px" src="#Url.Action("GetImage", "Beheer", new { productId = Model[i].product_id }) " alt="pasfoto"/><br />
<center><b>#Html.ActionLink(Model[i].naam, "PrProduct", "Categorie", new { id = Model[i].product_id }, null)</b></center>
<center>€ #Html.Label(Model[i].prijs)</center>
</td>
}
</tr>
Use the modulo operator %. Each time i%5 == 0, print a row around the td
#for (int i = 0; i < Model.Count; i++)
{
#if(i%5 == 0)
{
<tr>
}
<td>
<img width="200px" src="#Url.Action("GetImage", "Beheer", new { productId = Model[i].product_id }) " alt="pasfoto"/><br />
<center><b>#Html.ActionLink(Model[i].naam, "PrProduct", "Categorie", new { id = Model[i].product_id }, null)</b></center>
<center>€ #Html.Label(Model[i].prijs)</center>
</td>
#if(i%5 == 0)
{
</tr>
}
}
So you're going to have a table row when i is 0, 5, 10, 15, etc.
#for (int i = 0; i < Model.Count; i++)
{
#if(i%5 == 0)
{
<tr></tr>
}
<td>
<img width="200px" src="#Url.Action("GetImage", "Beheer", new { productId = Model[i].product_id }) " alt="pasfoto"/><br />
<center><b>#Html.ActionLink(Model[i].naam, "PrProduct", "Categorie", new { id = Model[i].product_id }, null)</b></center>
<center>€ #Html.Label(Model[i].prijs)</center>
</td>
}
The above code worked for me. Is it not much different from the answer Havelock gave, but it will not close the brackets in the above code if you do not close the html tags within the same if statement. This way may not look as good if you use borders because I think it will display one empty row? But, for me this worked fine:)

Categories

Resources