Dynamic column in ASP.NET MVC 5 [duplicate] - asp.net-mvc

I am writing some very poor code right now and before I even save it I was hoping to get some input on improving it. I am trying to build an html table with three cells to every row. If the collection has 5 items then that should render as two rows.
The code I have written so far I can see is not very robust and will require constant maintenance but I am unsure of other tools / methods for accomplishing the task.
<table>
#foreach (VideosModel item in Model)
{
if (cellCount == 0 || cellCount == 3)
{
#Html.Raw("<tr>")
}
<td style="padding:0px 20px;">
#item.VideoTitle <br />
<a href="#item.VideoUrl" target="_blank">
<img src="../../.../Video.jpg" /> <br />
</a>
#item.VideoDescription
<br />
</td>
cellCount++;
if (cellCount == 3 || cellCount == 6)
{
#Html.Raw("</tr>")
}
if (cellCount > 3) { cellCount = 0; }
}
</table>

You should considering using modulo instead of comparing the values of cellCount to 0, 3 or 6:
<table>
#foreach (VideosModel item in Model)
{
if (cellCount % 3 == 0)
{
#:<tr>
}
<td style="padding:0px 20px;">
#item.VideoTitle <br />
<a href="#item.VideoUrl" target="_blank">
<img src="../../.../Video.jpg" />
</a><br />
#item.VideoDescription
<br />
</td>
cellCount++;
if (cellCount % 3 == 0)
{
#:</tr>
}
}
</table>

Related

Asp-action edit not getting the data from razor page

Im trying to submit a form that consist of checkboxes.
When I submit the form I don't get the selected data from the form. I have been trying to use asp-for but I don't understand what I'm doing wrong.
this is my razor page:
#model TheaterReservering.Models.KlantReservering
#{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Reservering voor: #Model.Klant.Naam</h4>
<form asp-action="Edit">
<input type="hidden" asp-for="Klant" />
<table class="table">
<thead>
<tr>
<th>
1
</th>
<th>
2
</th>
<th>
3
</th>
<th>
4
</th>
<th>
5
</th>
<th>
6
</th>
<th></th>
</tr>
</thead>
<tbody>
#{
var count = 0;
}
#foreach (var item in Model.Reserveringen)
{
if ((count % 6) == 0)
{
#:<tr>
}
<td style="text-align:center; vertical-align:middle">
<div class="form-group">
#if (item.KlantId == Model.Klant.Id)
{
<input type="checkbox" asp-for="Reserveringen.ElementAt(count).Bezet" checked />
<br />
<div style="background-color: blue; text-align: center">
<label style="color:white" asp-for="#item.Naam">#item.Naam</label>
</div>
}
else if (item.KlantId == null)
{
<input type="checkbox" asp-for="Reserveringen.ElementAt(count).Bezet" />
<br />
<div style="background-color: green; text-align: center">
<label style="color:white" asp-for="#item.Naam">#item.Naam</label>
</div>
}
else
{
<input type="checkbox" checked disabled />
<br />
<div style=" background-color: red; text-align: center">
<label style="color:white" asp-for="#item.Naam">#item.Naam</label>
</div>
}
</div>
</td>
if ((count % 6) == 5)
{
#:</tr>
}
count++;
}
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Reserveringen vastleggen" class="btn btn-primary" />
</div>
</form>
My controller methode:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Klant,Reserveringen")] KlantReservering klantReservering)
{
if (id != klantReservering.Klant.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
_context.Update(klantReservering);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(klantReservering);
}
and this is the class i created to combine the class Klant with Reservering.
public class KlantReservering
{
public Klant Klant { get; set; }
public List<Reservering> Reserveringen { get; set; }
}
}
As far as I know, the tag helper couldn't work with a model class, it could only work for the model's property.
That means we couldn't use tag helper like this <input type="hidden" asp-for="Klant" />. If we want to achieve model binding in the controller method. I suggest you could add all the property as below:
<input type="hidden" asp-for="#Model.Klant.Id" />
<input type="hidden" asp-for="#Model.Klant.Naam" />
Besides, for the foreach item, tag helper couldn't figure out what the "Reserveringen.ElementAt(count).Bezet" means, we could only use this "#Model.Reserveringen[count].Bezet".
More details, you could refer to below example view:
Notice: Since I don't know your details codes about the Klant and the Reserveringen class, I created a test class in my side which just contains Naam and Id property.
#model CoreNormalIssue.Models.KlantReservering
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#*
For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
*#
#{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Reservering voor: #Model.Klant.Naam</h4>
<form asp-controller="Verify" asp-action="Edit" method="post" asp-route-id="#Model.Klant.Id">
<input type="hidden" asp-for="#Model.Klant.Id" />
<input type="hidden" asp-for="#Model.Klant.Naam" />
<table class="table">
<thead>
<tr>
<th>
1
</th>
<th>
2
</th>
<th>
3
</th>
<th>
4
</th>
<th>
5
</th>
<th>
6
</th>
<th></th>
</tr>
</thead>
<tbody>
#{
var count = 0;
}
#foreach (var item in Model.Reserveringen)
{
<input type="text" asp-for="#item.Bezet" />
if ((count % 6) == 0)
{
#:<tr>
}
<td style="text-align:center; vertical-align:middle">
<div class="form-group">
#if (item.KlantId == Model.Klant.Id)
{
<input type="checkbox" asp-for="#Model.Reserveringen[count].Bezet" checked />
<br />
<div style="background-color: blue; text-align: center">
<label style="color:white" asp-for="#item.Naam">#item.Naam</label>
</div>
}
else if (item.KlantId == null)
{
<input type="checkbox" asp-for="#Model.Reserveringen[count].Bezet" />
<br />
<div style="background-color: green; text-align: center">
<label style="color:white" asp-for="#item.Naam">#item.Naam</label>
</div>
}
else
{
<input type="checkbox" checked disabled />
<br />
<div style=" background-color: red; text-align: center">
<label style="color:white" asp-for="#item.Naam">#item.Naam</label>
</div>
}
</div>
</td>
if ((count % 6) == 5)
{
#:</tr>
}
count++;
}
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Reserveringen vastleggen" class="btn btn-primary" />
</div>
</form>
Result:

if condition in the razor syntax for HTML table- MVC

I have a HTML table with 2 rows and 4 columns. The data in each cell is coming from the stored proc. Currently, the last column displays number, I have an image to display, but it has to be displayed only if(rejected_question>0) else it should not display anything. How do I accomplish this in razor.
I have tried this so far, the below code doesn't work:
#foreach (var item in Model)
{
//logic for first three columns..
//fourth column here.
<td align="center">
if(#Html.DisplayFor(modelItem => item.RejectedQuestion) >0)
{
return Html.Raw(string.Format("<text><img height='3' width='3' src="\{0}\" alt="\Image\" /></text>", Url.Content("../../content/images/icon_red_questions_returnedbyreviewer.gif")));
}
</td>
}
This is what your looking for, probably:
#foreach (var item in Model)
{
//logic for first three columns..
//fourth column here.
<td align="center">
#if(item.RejectedQuestion > 0)
{
<img height="3" width="3" alt="Image"
src="#Url.Content("~/content/images/icon_red_questions_returnedbyreviewer.gif")" />
}
</td>
}
Make the line inside the if statement
#Html.Raw(string.Format("<text><img height='3' width='3' src="\{0}\" alt="\Image\" /></text>", Url.Content("../../content/images/icon_red_questions_returnedbyreviewer.gif")))
to display it. view.Execute() returns void, so you cannot include a return statement.
I tried this and it worked, just in case if someone needs it in future
:
#if(item.RejectedQuestion > 0)
{
<img height="20" width="20" alt="Image"
src="#Url.Content("~/content/images/icon_red_questions_returnedbyreviewer.gif")" />
}

Input submit not included in the form

I would like to ask if why the <input type="submit" value="" is not included in the form when I tried to debug the form using F12.
Here is the code:
<table>
<tr>
#if (ViewBag.wthOutSupp == false)
{
using (#Html.BeginForm("Item_SendForApprovalMail", "BuyersTask", FormMethod.Post))
{
<td style="border-color:#1e7c97; background-color:#1e7c97" colspan="5">
#Html.Hidden("id",(int)#ViewBag.prfNo)
<center> <input type ="submit" id="subbttn1" value="Submit the Item/s to Reveiwer" /><center>
</td>
}
}
else if (ViewBag.wthOutSupp == true) {
using (#Html.BeginForm("OnHoldItems", "SearchItems", FormMethod.Post))
{
<td style="border-color:#1e7c97; background-color:#1e7c97" colspan="5">
#Html.Hidden("id",(int)#ViewBag.prfNo)
<center> <input type ="submit" id="subbttn" value="Hold Some Items that Have no Supplier Yet" /><center>
</td>
}
}
</tr>
</table>
In the F12 results:
Could someone help me with this one?
You code is generating invalid html. A <form> element cannot be a child of a <tr> element.
Change your code to
<table>
<tr>
<td style="border-color:#1e7c97; background-color:#1e7c97" colspan="5">
#if (ViewBag.wthOutSupp == false)
{
using (#Html.BeginForm("Item_SendForApprovalMail", "BuyersTask", FormMethod.Post))
{
#Html.Hidden("id",(int)#ViewBag.prfNo)
<center> <input type ="submit" id="subbttn1" value="Submit the Item/s to Reveiwer" /><center>
}
}
else
{
....
}
</td>

Dynamically generate table in loop / foreach MVC view

I am writing some very poor code right now and before I even save it I was hoping to get some input on improving it. I am trying to build an html table with three cells to every row. If the collection has 5 items then that should render as two rows.
The code I have written so far I can see is not very robust and will require constant maintenance but I am unsure of other tools / methods for accomplishing the task.
<table>
#foreach (VideosModel item in Model)
{
if (cellCount == 0 || cellCount == 3)
{
#Html.Raw("<tr>")
}
<td style="padding:0px 20px;">
#item.VideoTitle <br />
<a href="#item.VideoUrl" target="_blank">
<img src="../../.../Video.jpg" /> <br />
</a>
#item.VideoDescription
<br />
</td>
cellCount++;
if (cellCount == 3 || cellCount == 6)
{
#Html.Raw("</tr>")
}
if (cellCount > 3) { cellCount = 0; }
}
</table>
You should considering using modulo instead of comparing the values of cellCount to 0, 3 or 6:
<table>
#foreach (VideosModel item in Model)
{
if (cellCount % 3 == 0)
{
#:<tr>
}
<td style="padding:0px 20px;">
#item.VideoTitle <br />
<a href="#item.VideoUrl" target="_blank">
<img src="../../.../Video.jpg" />
</a><br />
#item.VideoDescription
<br />
</td>
cellCount++;
if (cellCount % 3 == 0)
{
#:</tr>
}
}
</table>

MVC formatting td dynamically

I am new to razor engine syntax and I have issue with formatting adding the logic in the view. Here is what I want to accomplish. I have collection of items coming from model.
I need to iterate that collection and align 6 item in a row.
This is how the final output should look like:
<table>
<tr>
<td>checkbox comes here</td>
<td>checkbox comes here</td>
<td>checkbox comes here</td>
</tr>
<tr>
<td>checkbox comes here</td>
<td>checkbox comes here</td>
<td>checkbox comes here</td>
</tr>
................. and so on
</table>
Here is the code I wrote in the view
<table>
#for (int i = 0; i <= Model.checkItems.Count; i++)
{
if (i % 6 == 0)
{ <tr> }
<td>
<input type="checkbox"
id="chk_#(Model.checkItems[i].DisplayText)"
name="chk"
nameVal = "#Model.checkItems[i].DisplayText"
value="#Model.checkItems[i].Value"/>
<label for="chkGroup_#(Model.checkItems[i].DisplayText)">#Model.checkItems[i].DisplayText
</td>
if(i % 6 == 0)
{ </tr> }
}
</table>
When the page finally gets rendered, the first if condition getting executed but not the second one.
Can somebody help to figure out how the accomplish this?
Try this
<table>
#{ int count = 0; }
<tr>
#foreach (var item in Model.checkItems)
{
<td>
<input type="checkbox"
id="chk_#(item.DisplayText)"
name="chk"
nameVal = "#item.DisplayText"
value="#item.Value"/>
<label for="chkGroup_#(item.DisplayText)">#item.DisplayText</label>
</td>
if (++count % 6 == 0)
{
#:</tr><tr>
}
}
</tr>
</table>
You're missing a closing tag on your label
<label for="chkGroup_#(Model.checkItems[i].DisplayText)">#Model.checkItems[i].DisplayText
should be
<label for="chkGroup_#(Model.checkItems[i].DisplayText)">#Model.checkItems[i].DisplayText</label>
would this work:
<table>
#for (int i = 0; i <= Model.checkItems.Count; i++)
{
if (i % 6 == 0)
{
<tr>
<td>
<input type="checkbox"
id="chk_#(Model.checkItems[i].DisplayText)"
name="chk"
nameVal = "#Model.checkItems[i].DisplayText"
value="#Model.checkItems[i].Value"/>
<label for="chkGroup_#(Model.checkItems[i].DisplayText)">#Model.checkItems[i].DisplayText
</td>
</tr>
}
}
</table>
Here's another solution that uses 2 nested loops for rows and columns. I don't know if its necessarily better (it certainly looks more complicated on the face of it), but it does at least allow you to easily see the nested nature of the rows and cells:
<table>
#{
const int cols = 3;
int rows = (Model.checkItems.Count + cols - 1) / cols;
}
#for (int rowIndex = 0; rowIndex < rows; rowIndex++)
{
<tr>
#for (int colIndex = rowIndex * cols; colIndex < Math.Min(Model.checkItems.Count, cols * (rowIndex + 1)); colIndex++)
{
<td>
<input type="checkbox"
id="chk_#(Model.checkItems[colIndex].DisplayText)"
name="chk"
nameVal="#Model.checkItems[colIndex].DisplayText"
value="#Model.checkItems[colIndex].Value"/>
<label for="chkGroup_#(Model.checkItems[colIndex].DisplayText)">#Model.checkItems[colIndex].DisplayText</label>
</td>
}
</tr>
}
</table>

Resources