below code working perfectly . but i need to convert it from foreach to for loop .please help me to iteration by for loop. because i have to introduce some if else statement in entire code
#foreach (var item in ViewData["productSl_1"] as IEnumerable<Nazmulkp.Models.Product>)
{
<div class="col-md-3 ">
<div class="thumbnail">
<img src="#Url.Content(item.ImagePath)" alt="Image" style="max-width:100%;">
<div class="caption">
<h5>#item.ProductName</h5>
<h4>Tk.#item.Price</h4>
</div>
</div>
</div>
}
Example:
I have to make sure if index number 2 than execute <div class="col-md-3>"
Thank you
You do not need to convert your foreach to a for loop for adding a conditional css class. Simply add a counter variable to your code and use that for your if condition as needed.
For example, the below code will add the css class "col-md3" to the 3rd item in your collection.
#{ var counter = 0;}
#foreach (var item in YouCollectionHere)
{
<div class="#(counter==2?"col-md-3":"")">
<h2>#item.Name</h2>
</div>
counter++;
}
Related
Here is how my structure is setup:
I have many Services (DocType) which hold children Documents (DocType).
The Document DocType can have other Document elements as its children.
This way, it's possible for editors to create that kind of tree:
Service > Document> Document >Document > Document
There's no limits to the amount of levels this can go on for.
I'm trying to find a way to loop recursively through each Document and their descendants, but they need to be nested within eachother. This is where I'm having trouble.
I can't seem to find a simple way to loop recursively through each levels per children to generate the content.
Here is what I have so far:
#{ var selection = Model.Children.Where("Visible");
if (selection.Any()) {
<ul>
#foreach (var item in selection) {
<li>
<div class="ServiceDocCenterDocumentation">
<h4>#item.Name</h4>
<div class="DocCenterDocumentationDescription">#item.GetPropertyValue("bodyText")</div>
</div>
<div>
#foreach (var children in item.Descendants()){
#* This is the part I'm struggling with for the last few days *#
var actualChildren = children;
<h5>#children.Name</h5>
<div class="DocCenterDocumentationDescription">#children.GetPropertyValue("bodyText")</div>
}
</div>
</li>
}
</ul>
}
}
Here's what I would like to achieve (recursively, not manually):
<div class="myService">
<div class="Documents">
<div class="Document_#elem.Id">
#elem.bodyText
foreach (var child in elem.Children){
<div class="Document_#child.Id">
#child.bodyText
foreach (var grandchild in child.Children){
#* It goes on and on for the amount of levels available *#
}
</div>
}
</div>
</div>
</div>
I'm still not very fluent in Razor, and I'm wondering if there's a way of achieving what I would like to achieve.
You should use Razor helpers to create your recursive function.
Apart of that, you shouldn't use Descendants in each children as it would return every node below this one. You just need its children, then the children of each children and so forth. So you will pass each children list to the function to display it.
#{ var selection = Model.Children.Where("Visible");
if (selection.Any()) {
<section class="DocCenter">
#foreach (var item in selection) {
<section class="Service">
<div class="ServiceDocCenterDocumentation">
<h1>#item.Name</h1>
<div class="DocCenterDocumentationDescription">#item.GetPropertyValue("bodyText")</div>
</div>
#DisplayChildren(item.Children().Where("Visible"))
</section>
}
</section>
}
}
#helper DisplayChildren(IEnumerable<IPublishedContent> children){
if(children.Any()){
<section class="children">
foreach(var child in children){
<section class="Document_#child.Id">
<div class="DocumentDetails">
<h1>#children.Name</h1>
<div class="DocCenterDocumentationDescription">#children.GetPropertyValue("bodyText")</div>
</div>
//Recursive call here
#DisplayChildren(child.Children().Where("Visible"))
</section>
}
</section>
}
}
On the other hand, although is not related to the recursive question, I would use the <section> element to separate parents and children, that way you can also use h1 for all the headings as they are created in a section hierarchy:
Using HTML sections and outlines
I have the following code in my View.
#model MovieApp.Models.HomeIndexViewModel
#foreach (var item in Model.Movies)
{
<div class="container">
<div class="row">
<div class="col-xs-4">
<img src=item.posterPath id="picture1" class="img-responsive" />
</div>
</div>
</div>
}
I retrieve the image Url's on item.Posterpath as a string.
When I try to add my Url's on item.PosterPath as <img src=item.posterPath id="picture1" class="img-responsive"/>I can see that the item is not in scope.
My question is how i should iterate over my Model to stay in the scope and retrieve my paths?
have you tried src="#item.posterPath" ?
I am trying to display images in a carousel on my Umbraco from a macro and I am using Library.GetMediaById(child.picture). Here is my code:
#foreach (var child in slider.Children.Where("Visible"))
{
var background = Library.MediaById(child.picture);
if (i == 0)
{
<div id="#i" class="item active" data-id="#i" style="background-image: url(#background.UmbracoFile)">
</div>
}
else
{
<div id="#i" class="item" data-id="#i" style="background-image: url(#background.UmbracoFile)">
</div>
}
i++;
}
However when I do this instead of getting <div id="1" class="item" data-id="1" style="background-image: url('/media/1007/slide-2.png')"></div> like I should I am getting a bunch of extra stuff:
<div id="1" class="item" data-id="1" style="background-image: url({src: '/media/1007/slide-2.png', crops: []})"></div>
How do I just get that media item url and not all the extra stuff?
BTW I am using Umbraco 7.4
If you are using Umbraco 7 or later, I strongly recommend using the new APIs to retrieve property values and content or media nodes, rather than using the Library.MediaById method which is now obsolete.
If you prefer a dynamic view model, you can use the DynamicPublishedContent API, which lets you write dynamic queries using the #CurrentPage model. So your example would be:
#foreach (var child in CurrentPage.AncestorOrSelf(1).Children.Where("isVisible"))
{
var backgroundPicture = Umbraco.Media(child.Picture); //assuming an image property on child
var backgroundPictureUrl = picture.Url;
// your markup here
}
If you instead prefer a strongly typed model, you can use the IPublishedContent API. Please bear in mind that your view must inherit from a suitable type, such as Umbraco.Web.Mvc.UmbracoTemplatePage.
#foreach (var child in Model.AncestorOrSelf(1).Children().Where(c => c.IsVisible))
{
var backgroundPicture = Umbraco.TypedMedia(child.GetPropertyValue<int>("picture");
var backgroupdPictureUrl = backgroundPicture.Url;
// your markup here
}
Also, from your example I'm suspecting that you may be using an image cropper property to store the background image, in which case the property will have a json (JObject) value rather than an int corresponding to the media Id.
In this case, the code retrieving the picture property needs to be adapted, have a look at the documentation for image cropper to see the different ways you can get the image url depending on whether you've specified crops and/or a focal point. As an example, if you're using the dynamic API and you're only interested in the image URL, use the following:
<div style="background-image: url('#child.picture.src')">
So the way I got around this was to, make a partial instead of a macro because partials inherit Umbraco.Web.Mvc.UmbracoTemplatePage so then I could use Umbraco.Media() instead. Here is the working code in case anyone comes across this and needs help:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var root = Model.Content.AncestorOrSelf(1);
int i = 0;
}
<div class="container">
<div id="photo-carousel" class="carousel slide">
<div class="carousel-inner">
#foreach (var child in root.Children().Where("naviHide == true"))
{
if (child.DocumentTypeAlias.Equals("slider"))
{
foreach (var picture in child.Children.Where("naviHide != true"))
{
var background = Umbraco.Media(picture.GetPropertyValue("picture"));
if (i == 0)
{
<div id="#i" class="item active" data-id="#i" style="background-image: url('#background.Url')">
</div>
}
else
{
<div id="#i" class="item" data-id="#i" style="background-image: url('#background.Url')">
</div>
}
i++;
}
}
}
</div>
<a class="carousel-control left" href="#photo-carousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="carousel-control right" href="#photo-carousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
</div>
I have used the media picker as data type for the type, for which the user is going to choose what image they want as the deal image.
But for some reason i can't get the razor syntax to show the image. If I make an If statement to check if the page contains an image then it won't. I think this is a problem that occurs because i have misunderstood something.
My current razor statement:
<img src="#Umbraco.TypedMedia(Model.Content.GetPropertyValue("deal1image")).Url" />
The above code won't show anything.
Hope any of you can guide me to what i do wrong and evt. stuff I'm missing.
This is how my current home.cshtml looks like:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
Layout = "Master.cshtml";
}
<div class="container">
<div class="col-md-4">
<!--Image here-->
<img src="#Umbraco.Media(CurrentPage.deal1image).Url" />
<div class="thumbnail thumbnailcustom thumbnailbg1">
<h3>#Umbraco.Field("dealtitle1")</h3>
<p>#Umbraco.Field("dealdescription1")</p>
</div>
</div>
<div class="col-md-4">
<!--Image here-->
<div class="thumbnail thumbnailcustom thumbnailbg2">
<h3>#Umbraco.Field("dealtitle2")</h3>
<p>#Umbraco.Field("dealdescription2")</p>
</div>
</div>
<div class="col-md-4">
<!--Image here-->
<div class="thumbnail thumbnailcustom thumbnailbg3">
<h3>#Umbraco.Field("dealtitle3")</h3>
<p>#Umbraco.Field("dealdescription3")</p>
</div>
</div>
</div>
You need to use Umbraco.Media to get the media. So like this
<img src="#Umbraco.Media(Model.Content.GetPropertyValue("deal1image").ToString()).Url" />
Or
<img src="#Umbraco.Media(CurrentPage.deal1image).Url" />
An example of using Umbraco.Media:
var myPage = CurrentPage.AncestorsOrSelf().Where("DocumentTypeAlias == #0", "yourPageAlias").First();
Umbraco.Media(myPage.myImage.ToString()).Url
Link on OUR Umbraco offers two solutions:
Typed:
#if (Model.Content.HasValue("caseStudyImages"))
{
var caseStudyImagesList = Model.Content.GetPropertyValue<string>("caseStudyImages").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse);
var caseStudyImagesCollection = Umbraco.TypedMedia(caseStudyImagesList).Where(x => x != null);
foreach (var caseStudyImage in caseStudyImagesCollection)
{
<img src="#caseStudyImage.Url" style="width:300px;height:300px" />
}
}
Dynamic:
#if (CurrentPage.HasValue("caseStudyImages"))
{
var caseStudyImagesList = CurrentPage.CaseStudyImages.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
var caseStudyImagesCollection = Umbraco.Media(caseStudyImagesList);
foreach (var caseStudyImage in caseStudyImagesCollection)
{
<img src="#caseStudyImage.Url" style="width:300px;height:300px" />
}
}
Also, double check your media picker data type alias. Typos are rather common in this part.
This may be a bit clunky compared to other answers but this is what I currently have.
var imageId = Model.Content.GetPropertyValue<int>("eventPoster"); // gets node id
var evId = evpId.Id; // gets image id
var evMd = Umbraco.Media(evId); // I believe this turns the id into a string
var evUrl = evMd.Url; // gets the url of the string
My app is crashing my browser after implementing this columnWidth helper method. All I'm trying to do is rotate between col-md-7 and col-md-5 (Bootstrap classes) so that no two consecutive posts are the same width.
columnWidth: function() {
if (Session.get('columnWidth') === 'col-md-7') {
Session.set('columnWidth', 'col-md-5');
} else {
Session.set('columnWidth', 'col-md-7');
}
return Session.get('columnWidth');
}
The post template:
{{#each this}}
<div class="{{columnWidth}}">
<img src="{{image}}" height="350" width="{{imageWidth}}" alt="">
<div class="content">
<h2>{{title}}</h2>
<p>{{content}}</p>
<span class="dateAuthored">{{date}}</span>
</div>
</div>
{{/each}}
this refers to:
data: function() {
return Articles.find();
}
Any ideas why this is happening? I'm not receiving any errors. The browser tab just becomes unresponsive. Thanks.
You are constantly setting the same reactive variable so for example with the first div when the helper is called it will set it to col-md-7, then when it is called for the 2nd row you are changing the same variable to col-md-5 which is problematic for 2 reasons:
a) the template will redraw the first column and so they will both be col-md-5
b) the same helpers will get called again. I believe your browser crashes because you have created an infinite loop. Try console logging something inside your columnWidth helper and see how many times it gets called.
To achieve what you want you need to get the index of the {{#each }} loop and then have the column class dependent on whether it's odd or even. Unfortunately getting the index in meteor handlebars is a little tricky.
Try:
{{#each articles}}
<div class="{{columnWidth index}}">
<img src="{{image}}" height="350" width="{{imageWidth}}" alt="">
<div class="content">
<h2>{{title}}</h2>
<p>{{content}}</p>
<span class="dateAuthored">{{date}}</span>
</div>
</div>
{{/each}}
Then the following helpers:
articles: function() {
//'this' in this context should work.
//if not just replace with Articles.find().map(...
var articles = this.map(function(article, index) {
var i = _.extend(article, {index: index});
return i;
});
return articles;
},
columnWidth: function(index) {
if (index % 2 === 0)
return "col-md-5";
else
return "col-md-7"
}