Question about nested code block declarations in Razor - asp.net-mvc-3

I've recently upgraded a project from MVC 1 to MVC 3 and now I'm trying out Razor.
In one View, I have a foreach code block, but the nested if statement does not seem to want the # in front of it.
My original code was:
#foreach(var r in Model.Results)
{
string css = r.Result.Count() > 0 ? "fail" : "pass";
<p class="#css"><strong>#r.Description</strong></p>
#if(r.Result.Count() > 0)
{
<p>Count: #r.Result.Count()</p>
<table>
<thead>
<tr>
<th>ID</th><th>Title</th><th>Description</th>
</tr>
</thead>
<tbody>
#foreach(var e in r.Result) {
<tr><td>#e.Id</td><td>#e.Title</td><td>#e.Description</td></tr>
}
</tbody>
</table>
}
}
I'll get a runtime error with #if that says: Unexpected "if" keyword after "#" character. Once inside code, you do not need to prefix constructs like "if" with "#".
If I remove the # the code runs fine. I expected to need the # because of the HTML immediately preceding it. What confuses me more is that I do need the # before the nested foreach. What are the rules in play here?

Within any parentheses in razor it expects a matching start and end end tag. Thats how the parser works.
So far example the following is valid:
#for (var i = 0; i < 10; i++) {
<p>
#i.ToString()
</p>
}
And this is not:
#for (var i = 0; i < 10; i++) {
<p>
#i.ToString()
</p>
#if (i == 2) {
<p>2</p>
}
}
To get around this you can place it within a <text> block like:
#for (var i = 0; i < 10; i++) {
<text>
<p>
#i.ToString()
</p>
#if (i == 2) {
<p>2</p>
}
</text>
}
So in your case it would become:
#foreach(var r in Model.Results)
{
#string css = r.Result.Count() > 0 ? "fail" : "pass";
<text>
<p class="#css"><strong>#r.Description</strong></p>
#if(r.Result.Count() > 0)
{
<p>Count: #r.Result.Count()</p>
<table>
<thead>
<tr>
<th>ID</th><th>Title</th><th>Description</th>
</tr>
</thead>
<tbody>
#foreach(var e in r.Result) {
<tr><td>#e.Id</td><td>#e.Title</td><td>#e.Description</td></tr>
}
</tbody>
</table>
}
</text>
}

The nested foreach is inside of HTML (which happens to be inside of other code).
To go from markup to code, you need an #.
It's only unnecessary when directly nesting code blocks.

Related

How to use arithmetic operator in golang html template

I want to compare field 'FileSize' in my html go temple with variable 'minsize' in my code (.FileSize < *minsize). I have no idea how to do it. See below
{{ if lt .FileSize *minsize }}
<td style="color:red;">{{.FileSize}}</td>
{{else}}
<td>{{.FileSize}}</td>
{{end}}
The issue is the * in your minsize variable. If you are trying to dereference a pointer you have to do that in the go code, not in the template. That's why 9000 worked and the *minsize didn't.
Akama Razor tells me, that you don't need to use GO code here.
it's much better to use JS in such situation.
Good luck!
s = document.getElementsByTagName('td');
for (i = 0; i < s.length; i++) {
if (parseInt(s[i].innerText) > 123) {
s[i].style = 'color:red';
}
}
<head lang="en">
<title>123</title>
</head>
<body>
<table>
<tbody>
<tr>
<td>123</td>
<td>1234</td>
</tr>
</tbody>
</table>
<script>
s = document.getElementsByTagName('td');
for (i = 0; i < s.length; i++) {
if (parseInt(s[i].innerText) > 123) {
s[i].color = '#fff';
}
}
</script>
</body>

How to Display Conditional Plain Text with Razor

I am having issues with displaying (rather NOT displaying) plain text in an else block.
if (Model.CareerFields != null && ViewBag.CFCount > 0)
{
<h3>Careerfields Listing</h3>
<table>
<tr>
<th></th>
<th>Careerfield Name</th>
</tr>
#foreach (var item in Model.CareerFields)
{
<tr>
<td>
#Html.ActionLink("Select", "Index", new { careerFieldID = item.CareerFieldId })
</td>
<td>
#item.CareerFieldName
</td>
</tr>
}
</table>
}
else
{
No Careerfields associated with #ViewBag.SelectedDivisionTitle
}
The if blocks works fine. The text only renders when true. However, the else block text renders when the page loads, not if it evaluates to false only.
I've tried using
Hmtl.Raw("No Careerfields associated with ")
<text>No Careerfields associated with #ViewBag.SelectedDivisionTitle</text>
#:No Careerfields associated with #ViewBag.SelectedDivisionTitle
But it still renders the plaintext before evaluation.
Any suggestions?
Put your "plain text" inside of a naked <span> tag:
else
{
<span>No Careerfields associated with #ViewBag.SelectedDivisionTitle</span>
}
The browser shouldn't render it special (unless you have css selecting every span) and it'll help razor sense the end of the C# and print your HTML.
The following code worked perfectly for me:
#if (false) {
<h3>
Careerfields Listing
</h3>
<table>
<tr>
<th>
</th>
<th>
Careerfield Name
</th>
</tr>
</table>
}
else
{
#:No Careerfields associated with #ViewBag.SelectedDivisionTitle
}
You can see that the contents of if are rendered when you change condition to true.
Looks like you've forgotten the # sign before your if statement. Try this:
#if (Model.CareerFields != null && ViewBag.CFCount > 0)
{
<h3>Careerfields Listing</h3>
<table>
<tr>
<th></th>
<th>Careerfield Name</th>
</tr>
#foreach (var item in Model.CareerFields)
{
<tr>
<td>
#Html.ActionLink("Select", "Index", new { careerFieldID = item.CareerFieldId })
</td>
<td>#item.CareerFieldName</td>
</tr>
}
</table>
}
else
{
<text>No Careerfields associated with #ViewBag.SelectedDivisionTitle</text>
}
The most concise and correct answer is:
Prepend #: before the text.
(note the : after the #)
This still allows to embed variables in the text by prepending an # to the variable name:
#if (someCondition)
{
#:Some text you want to see.
}
else
{
#:Some other text, with a variable #someVariable included in the text.
}

How to format view results in mvc3?

I have List of checkbox in my view. it shows me in vertical format.
Like
a
b
c
d
...
But i want to format that in such a way that will look like.
a b c d
e f g h
i j k l
My code looks like this
#foreach (var item in Model)
{
<table>
<tr>
<td><input type="checkbox" id="#item.DataId" name="Data"/>#item.DataName</td>
</tr>
</table>
How can i format this?
Hoping you're not using the table for layout purposes ;)
Anyway this should do the trick, it's rough code, and could be polished but hopefully this will give you a good start
<table>
<tr>
#{var rower = 0;}
#foreach (var item in Model)
{
if (rower % 4 == 0 && rower != 0)
{
#:</tr>
#:<tr>
}
<td><input type="checkbox" id="#item.DataId" name="Data"/>#item.DataName</td>
rower++;
}
</tr>
</table>
Assuming you need a list, not a table:
// You may to check here whether model contains any items
<ul>
#foreach (var item in Model)
{
<li><input type="checkbox" id="#item.DataId" name="Data"/>#item.DataName</li>
}
</ul>
In your CSS you need to set display property of the list to inline

How to apply DRY with a tr

How can I write the following statement with Razor?
#{
if (isOddRow)
{
<tr class="PadColumns">
}
else
{
<tr class="PadColumns AlternateRow">
}
//then...
<td>content</td>
</tr>
}
Razor gets mad and Intellisense busts.
so I tried wrapping my tr's in <text>
if (isOddRow)
{
<text><tr class="PadColumns"></text>
}
...which causes a runtime parser error regarding tr with no matching start tag.
I would like to apply DRY by avoiding
if (isOddRow)
{
<tr class="PadColumns">
//then...
<td>content</td>
</tr>
}
else
{
<tr class="PadColumns AlternateRow">
//then...
<td>content</td>
</tr>
}
Why not just do something like this? Put the if statement inside the class attribute. If it's false, it'll print out AlternateRow, otherwise it prints out nothing.
<tr class="PadColumns #(isOddRow ? "" : "AlternateRow")">

MVC3 Razor Syntax troubles

I'm trying to make a very simple view using Razor syntax in MVC3, but it seems I can't get the syntax right.
I have a simple table like this
<table>
<tr>
#{
var counter = 0;
}
#foreach (var category in ViewBag.Categories)
{
counter++;
<td>
<input type="checkbox" checked="checked" name="#("category" + category.Code)" />
#category.Description
</td>
if (counter % 2 == 0)
{
</tr>
<tr>
}
}
</tr>
</table>
When I insert the and inside the if-statement, I receive this error
The using block is missing a closing "}" character.
If I try to wrap those two tags inside and , I get this error instead:
The "tr" element was not closed.
Your </tr><tr> messes up the "flow" of the html/code mix.
You are closing the tr-tag on a different level, not a different level in the html, but inside the code. You should trick razor into outputting html, that it does not parse itself.
You could include them like this:
#:</tr><tr>
or
#Html.Raw("</tr><tr>")
The result:
if (counter % 2 == 0)
{
#:</tr><tr>
}
Click for Haack's quick reference of Razor syntax
I would say you're missing the # in front of the if statement. Try #if(counter % 2 == 0).
Hope that helps.
Update
I checked it out and the answer from GvS seems to work just fine. The # is not necessary for the if statement.
#for (int i = 0; i < 5; i++)
{
if (i == 3)
{
#:</tr><tr>
}
}
You are mixing HTML and code in the foreach. That's why you get problems.
Either use <text></text> block around the HTML, or do the following:
<table>
<tr>
#{
var counter = 0;
}
#foreach (var category in ViewBag.Categories)
{
#{
counter++;
}
<td>
<input type="checkbox" checked="checked" name="#("category" + category.Code)" />
#category.Description
</td>
#if (counter % 2 == 0)
{
</tr>
<tr>
}
}
</tr>
</table>

Resources