Using if has value statement in razor view not working - asp.net-mvc

I have a db table with 3 different {price (value> int)} parameters
I would like in my view that in case one of them has value in it to display same html code
I had tried something like this in my view (not working)
#if(item.price_e.HasValue )
<text> €
}
#if(item.price_d.HasValue)
<text>$
}
else
item.price
what the way to do it?
My view
#foreach (var item in Model) {
<div class="prod" >
<div class="prodh">
<h3> #item.destination
#item.City
#item.pkg_type
</h3>
#item.description
//i have also tryed this Not working
#if(item.price !=0)
{
<text>bla
}
#if(item.price_d !=0)
{
<text>$
}
</div>
<div class="prodb">
#item.date
#item.company.company_id
#item.destination</div>
</div>
}

You are missing some } and haven't closed the <text> with </text>
#if(item.price_e.HasValue ) {
<text> €</text>
}
#if(item.price_d.HasValue) {
<text>$</text>
}
else {
#item.price
}
Your second code sample is also missing a </div>

Related

Razor View IF to a partial div

The thing is that Im trying to change background color of a div depending on an IF condition inside a foreach and I didnt wanted to make an entire replication of the code for every single condition(3 conditions actually).
My idea was to do something like:
#foreach (var item in Model.Models)
{
#if (item.Status == "COMPLETED")
{
<div class="card teal darken-2 white-text">
}
#if (item.Status == "NOT STARTED")
{
<div class="card grey white-text">
}
#if (item.Status == "RUNNING")
{
<div class="card blue white-text">
}
<div class="card content">
</div>
</div>
</div>
}
But it seems that HTML detects the 3 divs with no closure and it crushes saying that the foreach needs an ending }.
Any ideas?
Your current code is failing because you are trying to mix C# code with plain text.
The if condition opens a C# code block. So if you want to mix plain text or html inside that, you need to use #: prefix. #: tells razor that the following is not C# code, but plain text. It is same as <text></text> tag
You also had an extra closing div.
This should work.
#foreach (var item in Model.SomeCollection)
{
if (item.Status == "COMPLETED")
{
#:div class="card teal darken-2 white-text">
}
if (item.Status == "RUNNING")
{
#:div class="card grey white-text">
}
<div class="card content">#item.Name</div>
#:</div>
}
I personally prefer to add less C# code inside views. I like to keep my views more Htmly. I would create a separate method which can return the css class you need based on the Status value.
Here is an extension method.
public static class UiExtensionMethods
{
public static IHtmlString GetStatusClass(this string item)
{
switch (item)
{
case "COMPLETED":
return MvcHtmlString.Create("teal darken-2 white-text");
case "RUNNING":
return MvcHtmlString.Create("blue white-text");
default:
return MvcHtmlString.Create("gray white-text");
}
}
}
Now all you have to do is, call this method in your view.
<div>
#foreach (var item in Model.Tags)
{
<div class="card #item.Status.GetStatusClass()">
<div class="card content">
#item.Status
</div>
</div>
}
</div>
I created the extension method on string. You can create it on more specific type (Your Status class/Status type(enum?)/ The type of each item in your collection.)

Problems with partialview data

I have a problem with a partial view. The first time when it is rendered everything is ok, but after that some data is loosed.
This is how my page should look: this is when the partial view is rendered the first time
but when I'm clicking on a category to check his subcategories, the image is null, it is not visible anymore. (only the name is visible)
This is my partial view:
#model IEnumerable<OnlineCarStore.Models.CategoriesVM>
<div class="container">
<div class="row">
#using (Html.BeginForm("SubCategories", "Product"))
{
<div class="list-group col-sm-3" style="width:280px;">
#{var selected = string.Empty;
if (#HttpContext.Current.Session["selectedCar"] == null)
{
selected = string.Empty;
}
else
{
selected = #HttpContext.Current.Session["selectedCar"].ToString();
}
foreach (var c in Model)
{
<a href="#Url.Action("SubCategories", "Product", new { selected = #selected, id = #c.ID, category = #c.CategoryName })" class="list-group-item">
<span> #c.CategoryName</span>
</a>
}
}
</div>
<div class="col-sm-9">
#foreach (var c in Model)
{
<div class="card-group" style="width:200px; display: inline-block">
<div class="card card">
<a href="#Url.Action("SubCategories", "Product", new { selected = #HttpContext.Current.Session["selectedCar"].ToString(), id = #c.ID, category = #c.CategoryName })" id="linkOnImg" class="card-group">
<img class="card-img-top center-block" src="#string.Format("../content/images/categories/{0}.jpg", #c.AtpID)" alt=#c.CategoryName style="padding-top: 5px">
<div class="card-text text-center">
<p class="category-card-title ">
<span class="text-muted">#c.CategoryName</span>
</p>
</div>
</a>
</div>
</div>
}
</div>
}
</div>
and this is the Subcategoris view, where the partial view is rendered second time:
<div class="container">
<div class="row">
#Html.Partial("/Views/Home/CategorieTypes.cshtml");
Here is the Product controller Subcategories method:
public ActionResult SubCategories(string selected, int id, string category)
{
List<CategoriesVM> listOfCategories = new List<CategoriesVM>();
var list = db.Categories.ToList();
var root = list.GenerateTree(c => c.ID, c => c.ParentId).ToList();
TreeItem<Categories> found = null;
var test = new TreeItem<Categories>();
foreach (var rootNode in root)
{
found = TreeGenerator.Find(rootNode, (n) => n.Item.ID == id);
if (found != default(TreeItem<Categories>))
{
test = found;
break;
}
}
foreach (var item in found.Children.ToList())
{
CategoriesVM categoryv = new CategoriesVM();
categoryv.ID = item.Item.ID;
categoryv.AtpID = item.Item.AtpID;
categoryv.Childrens = item.Children.ToList();
categoryv.CategoryName = item.Item.AtpName;//.Name;
listOfCategories.Add(categoryv);
}
SiteMaps.Current.CurrentNode.Title = selected + " " + category;
var tests = found.Children.ToList();
if (found.Children.ToList().Count == 0 )
{
return View("Index");
}
else
{
return View("SubCategories", listOfCategories);
}
}
I've checked in developer tool if the source for the image is correct, and although it is correct, the image is not showed:
Can you please help me in this problem? What I do wrong? Why the images don't appear after the first render of the partial view? Thanks in advance!
The path of the partial view is /Views/Home/CategorieTypes.cshtml and the path of the images is /Content/images/categories. In the partial view you are using ../content/images/categories/ as the path of the images which means that it will search for the path /Views/Content/Images/Categories which is invalid.
Remove the two dots in the src property and add a ~ so it will be like: ~/Content/Images/Categories/{img}.
or
Add one more ../ in order to go one level down to the directory like:
../../Content/Images/Categories/{img}

Razor parse error- nested if and html within a foreach loop

I'm trying to execute the following code in asp.net razor view-
#foreach (var contact in ViewBag.ContactInfo.Rows)
{
if (columnCount>4)
{
<div class="row-fluid">
}
<div class="span4">#ViewBag.SomeText</div>
//This if block is treated as normal text.
if (columnCount > 4)
{
</div>
columnCount = 0;
}
columnCount++;
}
But it gives parse error.
Any help?
Try something like below. As you are opening div tag in one if and closing in other, razor viewengine is somehow not able to parse it. Check here for more
#foreach (var contact in ViewBag.ContactInfo.Rows)
{
if (columnCount>4)
{
<div class="row-fluid">
<div class="span4">#ViewBag.SomeText</div>
</div>
}
else
{
<div class="span4">#ViewBag.SomeText</div>
}
columnCount++;
}
#foreach (var contact in ViewBag.ContactInfo.Rows)
{
if (columnCount>4)
{
#:<div class="row-fluid">
}
<div class="span4">#ViewBag.SomeText</div>
//This if block is treated as normal text.
if (columnCount > 4)
{
#:</div>
columnCount = 0;
}
columnCount++;
}

The model item passed into the dictionary is of type 'BlogHomePageModel', but this dictionary requires a model item of type 'BlogHomePageModel'

I'm using Umbraco 7.04. I would post code but I can't determine what is causing the problem. I did make some edits to a class in my App_Code folder and my website started displaying this error. I reverted those edits but still get the error.
A coworker mentioned that .net can cache files so I tried recycling app pool and editing web.config to no avail.
EDIT: here is the code I believe was causing the problem, although it seemed to have gone away randomly.
BlogHomePage View
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
Layout = "BlogLayout.cshtml";
var BlogBackgroundImageCss = Html.Raw(HttpUtility.HtmlDecode(Model.BannerImageBackgroundImageCss));
var BlogHomeContent = Html.Raw(HttpUtility.HtmlDecode(Model.BlogHomeContent));
var AllTags = Html.Raw(HttpUtility.HtmlDecode(thunder.TagHelper.GetAllTags(Model.Content)));
var PagingHtml = Html.Raw(HttpUtility.HtmlDecode(Model.PagingHtml));
}
<div class="blog-area">
<div class="blog-banner-area" style="#BlogBackgroundImageCss" >
<span>#Model.BannerImageTitle</span>
</div>
<div class="blog-nav-area">
<button class="blog-nav-collapse-button"><span>Search</span></button>
<div class="blog-nav-inner-area">
#{ Html.RenderPartial("BlogHomeSearchInformation", Model); }
#{ Html.RenderPartial("BlogPostSearch"); }
#AllTags
#{ Html.RenderPartial("BlogHomeAside", Model); /*use partial to render blog post aside*/ }
</div>
</div>
<div class="blog-main-area">
<div class="blog-heading-area">
<div class="blog-heading-text-container">
#BlogHomeContent
<button class="blog-about-this-blog-expand-button">Read More</button>
</div>
</div>
#if (Model.Posts.Count() > 0) {
foreach (var Post in Model.Posts) {
Html.RenderPartial("BlogHomePostPartial", Post); /*use partial to render blog post content*/
}
#PagingHtml
} else {
<p>Sorry, but no posts matched your query.</p>
}
</div>
</div>
BlogHomeSearchInformationPartial
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
string SearchTerm = (!string.IsNullOrEmpty(Request.QueryString["s"])) ? Request.QueryString["s"] : "";
string TagTerm = (!string.IsNullOrEmpty(Request.QueryString["t"])) ? Request.QueryString["t"] : "";
}
<div id="blog-search-results-information">
#if (!string.IsNullOrEmpty(SearchTerm)) {
if (Model.TotalResults == 1) {
<p>Your search for "#SearchTerm" returned #Model.TotalResults result. Click here to return to home page.</p>
} else {
<p>Your search for "#SearchTerm" returned #Model.TotalResults results. Click here to return to home page.</p>
}
}
#if (!string.IsNullOrEmpty(TagTerm)) {
if (Model.TotalResults == 1) {
<p>There is #Model.TotalResults post tagged "#TagTerm". Click here to return to home page.</p>
} else {
<p>There are #Model.TotalResults posts tagged "#TagTerm". Click here to return to home page.</p>
}
}
</div>
BlogPostSearch
#inherits UmbracoTemplatePage
#{
string SearchTerm = "";
SearchTerm = Request.QueryString["s"];
}
<form role="search" method="get" id="searchform" action="/">
<div class="blog-search-area">
<input type="search" name="s" value="#SearchTerm">
<button type="submit">Search</button>
</div>
</form>
BlogPostAside
#inherits Umbraco.Web.Mvc.UmbracoViewPage<BlogHomePageModel>
#{
var AsideLinks = Html.Raw(HttpUtility.HtmlDecode(Model.AsideLinks));
}
#if (!string.IsNullOrEmpty(Model.AsideHeading) || !string.IsNullOrEmpty(Model.AsideSubheading) || !string.IsNullOrEmpty(Model.AsideContent) || !string.IsNullOrEmpty(Model.AsideLinks)) {
<div class="blog-contact-area">
<span class="blog-contact-heading">#Model.AsideHeading</span>
<span class="blog-contact-subheading">#Model.AsideSubheading</span>
<p>#Model.AsideContent</p>
#AsideLinks
</div>
}
Seems to me you have defined a special model on your view (or you did inherit form something).
Try to remove the #model and the #inherits from your view.
problem solved itself mysteriously :( After a little more research I believe it may be related to this question: The model item passed into the dictionary is of type ‘mvc.Models.ModelA’ but this dictionary requires a model item of type ‘mvc.Models.ModelB‘

Hide table or grid and display "No records found" message in ASP.NET MVC

What is the best practice for hiding a custom grid or a table or a div and display a "No Records Found" message when there are no records.
I have come up with this idea.
<div class="<%= Html.IsVisible(Model.Count)">
...
..
..
</div>
.displayNone {display:none;} .displayInherit {display:inherit;}
public static string IsVisible(this HtmlHelper helper,int recordCount)
{
return recordCount == 0 ? "displayNone" : "displayInherit";
}
Your solution would work fine, but I think you might be overthinking it a little :)
This would work perfectly fine:
<% if (Model.Count == 0) { %>
No Records Found
<% } else { %>
// do something to show the Model information here
<% }
Make the if in the controller?
if Model.Count == 0 display the "EmptyView" else show the GridView
Empty view could be made generic to be use from several objects.
Following solution is better for razor engine
#model IEnumerable<WebApp.Models.ArticleViewModel>
<div id="answers">
#if (Model.Count() == 0)
{
<div class="question-summary">
<p>No answer found</p>
</div>
}
else
{
foreach (var item in Model)
{
<div class="question-summary">
#Html.Raw(item.Body)
</div>
}
}
</div>

Resources