How to apply DRY with a tr - asp.net-mvc-3

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")">

Related

How to create logic / find style for tr id in table

I've got a table defined as below:
<table id="DateTable" width="100%">
<tbody>
<tr id="prior" style="display: none;" ><td>
. .. .. . prior
</td></tr>
<tr id="current"><td>
. .. .. current
</td></tr>
</tbody>
</table>
I need to have logic put in place that determines if the style="display: none;" exists for the "prior" id.
I have this, but it doesn't work:
if($("#DateTable tr").find("prior").html("style=display: none;").length > 1)
alert("Style exists!!");
}
else {
alert("Style doesn't exist.");
}
Where am I going wrong?
You need to use css method:
if($("#DateTable tr").find("#prior").css("display") === 'none')
Also note that ID should be unique in DOM and you forget to add # symbol in your selector for prior element.
So your code can be simple:
if($("#prior").css("display") === "none") {
alert("Style exists!!");
} else {
alert("Style doesn't exist.");
}

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.
}

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.

Even and odd table rows with Razor

I'm using the Razor view engine with MVC 3 and I'm trying to make even and odd rows have different classes in a table.
So far I've got this
#{ var odd = true; }
#foreach(var userLot in Model) {
if (!odd) {
<tr id="lot#userLot.Id" class="even">
else
<tr id="lot#userLot.Id" class="odd">
}
<td>#userLot.Id</td>
<td>#userLot.Description</td>
<td>#userLot.Carat</td>
<td class="averageBid">#userLot.AverageBid</td>
<td class="rank">#userLot.Rank</td>
<td class="currentBid">#userLot.CurrentBid</td>
<td style="width: 200px; height: 30px;" class="tdWithBidInput"><input type="text" style="display: none" /></td>
</tr>
#{ odd = !odd; }
}
This is giving me endless trouble with the stupid view engine unable to figure out what is markup and what is code. I've tried wrapping the tr opening tags in a text directive, but then the stupid view engine moans about the closing tr tags. If I then wrap the closing tr tag in a text directive the stupid view engine moans that the text directive has no opening tag.
Just to be clear, this
<text></ tr></text>
gives an error that the text tag has no matching opening tag. Lovely.
How do I write this so that Razor doesn't give an error?
Please don't recommend a JavaScript solution, I'm trying to get around the Razor issues here.
How about this:
#{ var odd = true; }
#foreach(var userLot in Model) {
<tr id="lot#(userLot.Id)" class="#(odd ? "odd": "even")">
<td>#userLot.Id</td>
<td>#userLot.Description</td>
<td>#userLot.Carat</td>
<td class="averageBid">#userLot.AverageBid</td>
<td class="rank">#userLot.Rank</td>
<td class="currentBid">#userLot.CurrentBid</td>
<td style="width: 200px; height: 30px;" class="tdWithBidInput"><input type="text" style="display: none" /></td>
</tr>
odd = !odd;
}
#( ... ) is a valid and very useful statement.

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