Reputation: 317
I have a sidebar item which contains a list of comments. I want this item to show only if there are any available comment in the beginning and in order for my template to work I have to put a different style to the first comment than the rest. All the comments are being passed on my Model.
Here is my approach:
@if(Model.Comments?.Count > 0) {
<div class="sidebar_item">
<div class="item_inner slider">
<h4>See what students say:</h4>
<div id="single_banner">
<ul class="slides">
@for (int i = 0; i < Model.Comments.Count; i++)
{
if (i > 0){
<li style="display:none;">
}
@if( i == 0)
{
<li>
}
@Model.Comments[i].Comment
<div class="carousal_bottom">
<div class="thumb">
<img src="img/courses/testi_thumb.png" draggable="false" alt="" />
</div>
<div class="thumb_title">
<span class="author_name">@Model.Comments[i].Student</span>
</div>
</div>
</li>
}
</ul>
</div><!--end banner-->
</div><!--slider-->
</div><!--end sidebar item-->
}
The problem is that this doesn't work and I get errors that some curly brackets are missing or that some elements haven't closed properly. Any help appreciated.
Upvotes: 0
Views: 990
Reputation: 54618
I get errors that [...] some elements haven't closed properly.
The following code isn't recommended because the engine isn't smart enough to determine start/ends for html elements in c# code:
if (i > 0){
<li style="display:none;">
}
@if( i == 0)
{
<li>
}
So I generally put the logic directly in the tag:
<li style="@(i > 0 ? "display:none;" : string.Empty)">
However I'm not really a fan of logic in my view. Additionally to make things easier IMHO, I would have a comment display template. And I personally think there is no good reason to not use classes. Eventually my code would look like:
controller:
foreach(var comment in Model.Comments)
{
comment.IsVisible = comment == Model.Comments.First();
}
view:
// Update Model with Property
// bool HasComments { get { return Comments.Any(); } }
// Then the code actually reads/documents itself
@if(Model.HasComments) {
<div class="sidebar_item">
<div class="item_inner slider">
<h4>See what students say:</h4>
<div id="single_banner">
<ul class="slides">
@Html.DisplayFor(m => m.Comments);
</ul>
</div><!--end banner-->
</div><!--slider-->
</div><!--end sidebar item-->
}
displaytemplates/comments.cshtml
@{
// View logic, it only deals with html/css/javascript
var liClass = model.IsVisible ? string.Empty : "is-not-visible";
}
<li class="@liClass">
@Model.Comments[i].Comment
<div class="carousal_bottom">
<div class="thumb">
<img src="img/courses/testi_thumb.png" draggable="false" alt="" />
</div>
<div class="thumb_title">
<span class="author_name">@Model.Student</span>
</div>
</div>
</li>
Less code and more encapsulated.
I'd also recommend reading Philip Walton - Decoupling Your HTML, CSS, and JavaScript
Upvotes: 4