I have a collection of strings that are repeated in MVC3 Razor with the following code:
#if (Model.Publications != null)
{
<tr>
<th>Publications</th>
<td>
#foreach (var publication in #Model.Publications)
{
<text>#publication.Title</text>
}
</td>
</tr>
}
Now when I display this, all I get is:
Book1Book2Book3
But I really want is something like this:
Book1, Book2, Book3
Is there a simple way in MVC razor to achieve this without having to combine 'if' and 'foreach' statements?
#string.Join(",",Model.Publications.Select(p=>"<text>"+ p.Title+ "</text>"))
string.Join(", ", model.Publications.Select(pub => pub.Title).ToArray())
#if (Model.Publications != null)
{
<tr>
<th>Publications</th>
<td>
#var first = true
#foreach (var publication in #Model.Publications)
{
<text>#string.format("{0}{1}", first ? "" : ", ", publication.Title)</text>
#first = false;
}
</td>
</tr>
}
Related
This question already has answers here:
Conditionally change CSS class in Razor view
(4 answers)
Closed 5 years ago.
I have a For...Each loop of a list in an MVC View. What I need to do is look at a property to determine if the records has been marked as deleted and then I would set the Bootstrap class of "danger" on a table row.
I can do a look at the property and write our the table row for each condition but that seems like extra work. If I use the following code Razor doesn't like the fact that it can't see the initial tag. Any suggestions on how to cleanly accomplish this?
#foreach (var item in Model.MyList)
{
if (item.IsDeleted == 1)
{
#Html.Raw("<tr class='danger'>")
}
else
{
#Html.Raw("<tr>")
}
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.EmployeeId</td>
</tr>
}
Here is the simpler way for your problem
#foreach (var item in Model.MyList)
{
<tr class="#(item.IsDeleted ? "danger" : string.Empty) ">
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.EmployeeId</td>
</tr>
}
How about something like this?
#foreach (var item in Model.MyList)
{
<tr class="#(Model.deleted ? "danger" : "")">
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.EmployeeId</td>
</tr>
}
You can simply work with it this way
#foreach (var item in Model.MyList)
{
if (item.IsDeleted == 1)
{
<tr class="danger">
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.EmployeeId</td>
</tr>
}
else
{
<tr>
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.EmployeeId</td>
</tr>
}
or an alternative is
#foreach (var item in Model.MyList)
{
<tr #(item.IsDeleted != 1 ? String.Empty : "class=\"danger\"" )>
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.EmployeeId</td>
</tr>
}
I have a strongly typed view where I am trying to display a model when an id is passed to my Controller action method.
I am trying to construct a link to each of this models as well.
For the purpose before the beginning of my foreach I have an i=0, and then I am trying to increase it by 1 using i++. The problem is that the the i++ part doesn't work -- I have always zero as an id in my link. Why?
Can someone help with this?
#{
var i = 0;
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Content)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id = i })
i++;
</td>
</tr>
}
}
Razor does its best to distinguish code from markup/html/text, which isn't easy in general. And in this case, i++ is considered text.
The reason is that there are tags following the foreach { part, causing the reading mode to switch to markup/html/text. In that mode only #..., #{... or } are recognized as code, and everything else is treated as markup/html/text.
If this happens, just put #{ ... } around your statements, like this:
<td>
#Html.ActionLink("Details", "Details", new { id = i })
#{
i++;
}
</td>
I need to show the data on the basis on below condition. Need to show 5 columns and then next data in next row. I am new for MVC. Please help.
#{
int count = 0;
#foreach (var item in Model)
{
if (count == 0) { #:<tr> }
<td>
<p align="center">item.WeekNumber</p>
</td>
<td>
item.OpenFirst<br>
item.OpenSecond<br>
item.OpenThird
</td>
<td><font size="6">OpenResult</font></td>
<td>
item.CloseFirst<br>
item.CloseSecond<br>
item.CloseThird
</td>
if (count == 5) { count = -1; #:</tr> }
count++;
}
}
Hello I think the problem is # on the first foreach loop. Please remove it and try. And one more thing if you want to use html in the Razor code then you can use #Html.Raw(). (Example #Html.Raw("<tr>"))
Depending on my record, I'd like to change the style of the table row in my current iteration.
The below example doesn't work, but how would I go about doing this correctly?
foreach (var item in Model)
{
#{
if (item.DataState != DataState.Active)
{
<tr style="background-color: red">
}
else
<tr>
}
<td>#item.Name</td>
</tr>
}
So effectively, I'd like to dynamically render the <tr> element differently based on the DataState of my model.
Here's a shorter approach:
#foreach (var item in Model)
{
<tr #(item.DataState != DataState.Active ? "style=background-color:red" : "")>
<td>#item.Name</td>
</tr>
}
Edit: Code fixed
There are multiple way you can write condition.
Option 1:
#foreach (var item in Model)
{
if (item.DataState != DataState.Active)
{
<tr style="background-color: red">
<td>#item.Name</td>
</tr>
}
else
{
<tr>
<td>#item.Name</td>
</tr>
}
}
Option 2:
#foreach (var item in Model)
{
<tr style="#( item.DataState != DataState.Active ? "background-color: red;" : "" )">
<td>#item.Name</td>
</tr>
}
Define the attributes in a variable. The razor parser will omit the attribute if its value is null
#foreach (var item in Model)
{
var attributes = item.DataState == DataState.Active ? null : "background-color: red";
<tr style=#attributes>
<td>#item.Name</td>
</tr>
}
Not sure what kind of error you faces right now, but i gess your problem is that Razor don't understand all cases of tricky html render.
You can force him to render html where you need with #: symbol for single string or <text> tag like this:
#foreach (var item in Model)
{
if (item.DataState != DataState.Active)
{
#: <tr style="background-color: red">
}
else
{
<text><tr></text>
}
<td>#item.Name</td>
</tr>
}
You're probably going to get compile errors if you start splitting the <tr> tag up in the view and I'd not duplicate large chunks of code. I would do the following:
#foreach(var item in Model) {
string strStyle=String.Empty;
if(item.DataState!=DataState.Active) { strStyle = "background-color:red;" }
<text>
<tr style="#strStyle">
<td>#item.Name</td>
</tr>
</text>
}
#(item.DataState != DataState.Active ? "style=" + "background-color:red" : "")
#(!string.IsNullOrWhiteSpace(Model?.District?.Name) ? Html.Raw($"<span class=\"location\">{Model?.District?.Name}</span>") : string.Empty)
I'm trying to add data from my model to a table with razor. My problem is that i want an if statement to decide what class the tagg should be and i can't get this to work.
When i add the if i get the following error when i run the code
The foreach block is missing a closing "}" character
How should i add the if statement? This is my current code
#{
var counter = 0;
}
#foreach (var item in Model)
{
if(item.status == "Active") {
<tr>
}
else {
<tr class="danger">
}
<td>#counter</td>
<td>#item.FirstName #item.LastName</td>
<td>#item.Email</td>
<td>#item.PhoneNumber</td>
<td>Ändra</td>
<td>Inaktivera</td>
</tr>
counter++;
}
MVC should detect html tags and render those out, however it seem this doesnt always work.
In between the curly brackets, try adding a tag
eg:
{
<text>
your html
</text>
}
or
if you just adding the class try something like:
<tr #(item.status == "Active" ? String.Empty : "class=\"danger\"" )>
try below code.
#{
var counter = 0;
}
#foreach (var item in Model)
{
if(item.status == "Active") {
<text> <tr> </text>
}
else {
<text><tr class="danger"></text>
}
<td>#counter</td>
<td>#item.FirstName #item.LastName</td>
<td>#item.Email</td>
<td>#item.PhoneNumber</td>
<td>Ändra</td>
<td>Inaktivera</td>
</tr>
counter++;
}
MVC detect HTML tags. So it will not add if statement like that.
you can not use <text><text> also.
You need to check condition in <tr> tag itself. See given result below.
#{
var counter = 0;
}
<table>
#foreach (var item in Model)
{
<tr #(item.status=="Active" ? String.Empty : "class=\" danger\"")>
<td>#counter</td>
<td>#item.FirstName #item.LastName</td>
<td>#item.Email</td>
<td>#item.PhoneNumber</td>
<td>Ändra</td>
<td>Inaktivera</td>
</tr>
counter++;
}
</table>
You can add extension method that take bool or string depend on your needs
public static class HtmlHelpExtention
{
public static string IsChecked(this IHtmlHelper htmlHelper,bool IsCheck, string className)
{
return IsCheck? className:"";
}
}
and then use it in the view
<tr class="#Html.IsChecked(item.IsGift,"teal accent-3")">
using this method will give you the ability to use multiple classes
Love Pandey solution works for me, but only for one class name. For more than one class name browser interpret second name as separate attribute. My modification for it is as below:
#{
var counter = 0;
}
<table>
#foreach (var item in Model)
string className = item.status=="Active" ? String.Empty : "item second-class-name";
{
<tr class="#className">
<td>#counter</td>
<td>#item.FirstName #item.LastName</td>
<td>#item.Email</td>
<td>#item.PhoneNumber</td>
<td>Ändra</td>
<td>Inaktivera</td>
</tr>
counter++;
}
</table>
You cannot use tag twice in a code block.
If you encounter problem because this limitation, put the second textbox as a string and then display it using html helper.
#{
int loop=0;
string HtmlBlock = "<table><tr><td style='font-weight:bold'>Lorem Text</td></tr></table>";
}
#foreach(var itemz in Mode.List){
If(loop ==3){ Html.Raw(HtmlBlock ); }
<text>itemz.Name Itemz.NIP</text>
loop++;
}