MVC3 Razor Syntax troubles - syntax

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>

Related

Encounter error when there is if else in mvc view

i am new in mvc and trying to learn.i want to display a form when ViewBag.Success is null or empty but if ViewBag.Success is true then i want to render a partial view.
here is my code
<div id="mydiv">
#if (ViewBag.Success != null && ViewBag.Success == true) //Show the message
{
Html.RenderPartial("Message");
}
else
{
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>
Name :
</td>
<td>
<input name="name" type="text" />
</td>
</tr>
<tr>
<td>
Salary :
</td>
<td>
<input name="salary" type="text" />
</td>
</tr>
<tr>
<td colspan="2">
<input name="btnSubmit" type="submit" value="Save" />
</td>
</tr>
</table>
}
}
</div>
the error message i am getting when i am running like
Expected a "{" but found a "/". Block statements must be enclosed in "{" and "}". You cannot use single-statement control-flow statements in CSHTML pages. For example, the following is not allowed:
what i am doing wrong not being able to understand. please help & guide. thanks
# symbol is only required when your code is contained within an HTML element. The using statement does not need the # because it is a direct decedent of your if else block.
Example:
<div> <!-- html tag -->
#if(something == somethingElse) // requires # because direct decedent of html tag <div>
{
<p>
#for (var i=0; i < len; i++) // requires # because direct decedent of html tag <p>
{
if(i == 1) // doesnt require #, not decedent of any HTML tag, instead direct decedent of another razor statement (for)
{
//do something
}
}
</p>
}
</div>
The # sign is use to distinguish between a simple string / HTML and razor statements. You only need that when you are writing C# code between HTML code. But when you are have started a C# code block, the ASP.NET MVC View Engine is intelligent enough to understand that the code that follows is C# and not simply some string.

How can I create a dynamic image source with MVC3 and Razor?

I have a view that attempts to build a table off of the passed in Model. I'd like to generate an image with a source that is changed based on the iteration of a loop but can't seem to get it to work. I can do this in JQuery but I would like to do it with razor. I have the following table body:
<tbody>
#{for (var ix = 0; ix <= Model.Value.Count - 1; ix++)
{
<tr>
<td style="width: 10%"><img src="http://gmap.com/marker" + #ix + 1 + ".png" /></td>
<td style="width: 75%">#Model("fullname")</td>
</tr>
}
<tbody>
That first TD is the problem area. I attempted it but... Thanks for the help.
Since it is razor you do not need to add the rendered output to your url. Try this:
#{for (var ix = 0; ix <= Model.Value.Count - 1; ix++)
{
<tr>
<td style="width: 10%"><img src="http://gmap.com/marker#(ix + 1).png" /></td>
<td style="width: 75%">#Model("fullname")</td>
</tr>
}
I haven't tested it but I believe it will fix your issue.

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

Question about nested code block declarations in Razor

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.

Resources