How to format view results in mvc3? - asp.net-mvc-3

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

Related

Creating grid with 2 axis

I am trying to create a grid that contains Events on the x axis and Requirements on the y axis and is filled with solutions.
Event1 Event2
Req1 Sol1
Req2 Sol2
My Model contains a list of Events, which contains their related Requirements, which contain their related Solutions. Every Event can have 0 or more Requirements and each Requirement can have 0 or more solutions.
How can I accurately show this grid in razor?
Here is my attempt:
<table border="1">
<tr>
<td class="span-6"></td>
#foreach(var events in Model.Events)
{
<td colspan="3">
#events.Name
</td>
requirementsList.AddRange(events.Requirements);
}
</tr>
#foreach(var req in requirementsList)
{
<tr>
<td>
#req.Name
</td>
<!--Insert logic to align solution with Event-->
<td>
#req.Solution
</td>
</tr>
}
</table>
Of course this is only showing all solutions in the first event column.
I've done a similar thing in PHP for my timesheet system, I want hours worked for each employee on each day (between 2 dates):
| 1 May | 2 May | ... May
Fred | 6 |
George | | 4 |
I used 3 foreach loops, first I outputted the dates, the I went rond each employee, and inside the employee loop, I looped round the dates again.
So for you it would be:
<table border="1">
<tr>
<td class="span-6"></td>
#foreach(var events in Model.Events)
{
<td colspan="3">
#events.Name
</td>
requirementsList.AddRange(events.Requirements);
}
</tr>
#foreach(var req in requirementsList)
{
<tr>
<td>
#req.Name
</td>
#foreach(var events in Model.Events)
{
#curRec = events.Requirements
#if (curRec.HasSolution) // If has a solution.
// Very important so solutions can be aligned properly
{ // Output the solution
<td>
#curRec.Solution
</td>
} else { // Output a empty cell
<td></td>
}
}
</tr>
}
</table>

select two cells from table with span class

How can I select two cells in table bases on span class?
my html looks like this.
what I want is to select innertext of span class="store-name-span"
and span class="price"
<table class="list mixed zebra-striped">
<tbody>
<tr data-pris_typ="normal">
<td class="span4-5">
<span class="store-name-span">Electroworld</span>
<a data-drg="store-2641" class="drg-sidebar"></a>
</td>
<td class="span3 cell-bar">
<span class="chart-bar price" style="width:50px"></span>
<span class="price" title="Uppdaterad 2013-02-18 08:23">1 690:-</span>
</td>
</tr>
<tr data-pris_typ="normal">
<td class="span4-5">
<span class="store-name-span">Webhallen</span>
<a data-drg="store-113" class="drg-sidebar"</a>
</td>
<td class="span3 cell-bar">
<span class="chart-bar price" style="width:50px"></span>
<span class="price" title="Uppdaterad 2013-02-18 13:55">1 690:-</span>
</td>
</tr>
</tbody>
</table>
var Nodes = from x in doc2.DocumentNode.Descendants()
//where x.Attributes["class"].Value == "store-name-span"
where x.Name == "span" && x.Attributes["class"].Value == "store-name-span"
select x.InnerText;
I'd use xpath for this:
var nodes = doc.DocumentNode.SelectNodes("//span[#class='store-name-span' or #class='price']");
foreach (var node in nodes)
Console.WriteLine(node.InnerText);
By using LINQ:
var nodes = doc.DocumentNode.Descendants("span")
.Where(s =>
s.GetAttributeValue("class", null) == "store-name-span" ||
s.GetAttributeValue("class", null) == "price"
);
this will get you:
Electroworld
1 690:-
Webhallen
1 690:-
In that particular HTML layout, you can do:
var items = doc.DocumentNode.SelectNodes("//tr[#data-pris_typ='normal']").Select(x => new
{
Store = x.SelectSingleNode(".//span[#class='store-name-span']").InnerText,
Price = x.SelectSingleNode(".//span[#class='price']").InnerText
});
On items you'll get what you need. Each item will be an anonymous type with the Store and Price fields.
One important thing:
You might want to clean the fields (like Price) using HttpUtility.HtmlDecode(). To do that you will have to add a reference to the System.Web assembly.
I would use a combination of querySelectorAll and fetching innerHTML.
queryselectors work both on calling globally (on document) as well as for a single element.

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.

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