I've created a multinode tree picker datatype and i'm trying to list the thumbnails of a vehicle as part of the foreach loop, however i keep getting ID rendering in the src of the image, i'm having trouble getting the URL of the image.
MVC Razor Code
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#using Umbraco.Web
#*
Macro to list nodes from a Multinode tree picker, using the pickers default settings.
Content Values stored as xml.
To get it working with any site's data structure, simply set the selection equal to the property which has the
multinode treepicker (so: replace "PropertyWithPicker" with the alias of your property).
*#
#* Lists each selected value from the picker as a link *#
<div class="featuredVehicles">
#foreach (var id in CurrentPage.featuredVehicles.Split(','))
{
#*For each link, get the node, and display its name and url*#
var vehicleContent = Umbraco.Content(id);
<div class="col-xs-6 col-md-4 col-xs-height">
<a href="#vehicleContent.Url">
#if (vehicleContent.HasValue("vehicleThumbnail"))
{
var mediaItem = Umbraco.TypedMedia(vehicleContent.GetPropertyValue("vehicleThumbnail"));
<img class="featuredVehicleImg img-responsive" src="#vehicleContent.GetPropertyValue("vehicleThumbnail")" alt="#vehicleContent.Name"/>
}
else
{
<img class="comingSoon" src="http://placehold.it/650x408" alt="#vehicleContent.Name">
}
<strong>
<span class="name">#vehicleContent.Name</span>
</strong>
<span class="desc">#vehicleContent.GetPropertyValue("shortContent")</span>
<span class="prx">from, <strong>£#vehicleContent.vehiclePrice</strong> per day</span>
<span class="label label-primary moreinfo">More Info</span>
</a>
</div>
}
</div>
HTML
<img alt="Pharmaceutical Vehicle One" src="1092" class="featuredVehicleImg img-responsive">
Problem solved;
This is the bit where the problems were being caused;
if (vehicleContent.HasValue("vehicleThumbnail")){
var dynamicMediaItem = Umbraco.Media(vehicleContent.vehicleThumbnail);
<img src="#dynamicMediaItem.umbracoFile" alt="#dynamicMediaItem.Name"/>
}
else
{
<img class="comingSoon" src="http://placehold.it/650x408" alt="#vehicleContent.Name">
}
Hopefully it will help someone else out :-)
Related
I am trying bind a razor variable to html attribute with vuejs.
The variable which i must use is "#culture". It is a string variable which gives me current culture information.
My code is:
<div class="dropdown-product-item" v-for="(item, index) in card.items">
<span class="dropdown-product-remove"><i class="icon-cross" v-bind:data-id="item.Id" v-on:click="removeFromCard"></i></span>
<a class="dropdown-product-thumb" v-bind:href="/#{Html.Raw(culture);}/item.Link">
<img v-bind:src="item.ResimUrl" v-bind:alt="item.Ad">
</a>
<div class="dropdown-product-info">
<a class="dropdown-product-title" v-bind:href="/#{Html.Raw(culture);}/item.Link">{{item.Ad}}</a>
<span class="dropdown-product-details" v-if="!item.IndirimliFiyat">{{pieces[index]}} x {{item.Fiyat.PriceString}}</span>
<span class="dropdown-product-details" v-else>{{pieces[index]}} x {{item.IndirimliFiyat.PriceString}}</span>
</div>
This code doesn't work. I only see white screen.
How to I do this? Could you help me?
I'm new to aurelia. I'm looking to find the best method for adding classes on click events.
I simply want to click approve or request information, and then add a class to the corresponding "contact card". This class would change the background color.
I know it's probably simple, but I thought I'd look here for the best method.
Here's an image to what I've got:
Apologies for the wait, work has been a bit busy.
This is my first time posting on S.O., so I apologize for any expectations I'm not meeting.
<div class="col-sm-4">
<button class="btn btn-success col-sm-12" click.delegate="goodBoi()">
approve contact
</button>
</div>
<div class="col-sm-4">
<button class="btn btn col-sm-12" click.delegate="requestContact()">
request information
</button>
</div>
</div>
the element to be changed is named "list-group-item", containing the
contact's details(code shown above).
<template>
<div class="contact-list">
<ul class="list-group">
<li repeat.for="contact of contacts" class="list-group-item ${contact.id === $parent.selectedId ? 'active' : ''}">
<a route-href="route: contacts; params.bind: {id:contact.id}" click.delegate="$parent.select(contact)">
<h4>${contact.firstName} ${contact.lastName}</h4>
<p>${contact.company}</p>
<p>${contact.email}</p>
<h6>${contact.approval}</h6>
</a>
<a route-href="route: contacts; params.bind: {id:contact.id}">
<p>${contact.phoneNumber}</p>
</a>
</li>
</ul>
</div>
goodBoi() {
let result = confirm("Are you sure you want to confirm this contact?");
if (result === true) {
var standingShell = document.getElementsByClassName("list-group-item");
//im hoping here I would add a class to the new variable//
this.contact.approval = 'approved';
this.save();
}
}
//confirms contact, changing color of approved contact//
//same thing here, just plan to give it a different color//
requestContact() {
let contactRequestText = "request sent to contact";
this.routeConfig.navModel.setTitle(this.contact.approval = contactRequestText);
this.ea.publish(new ContactUpdated(this.contact));
}
There are many ways to set a CSS-class using Aurelia. Following I prepared an example gist:
Template:
<template>
<h1>${message}</h1>
<div class="form-group ${clicked ? 'red' : 'blue'}" style="width: 100px; height: 100px;">
</div>
<div class="form-group">
<button click.delegate="save()">
Click me
</button>
</div>
</template>
And the code class:
#autoinject
export class App {
#bindable clicked = false;
save(){
this.clicked = true;
}
}
https://gist.run/?id=425993b04a977466fa685758389aa2b4
But there are other, cleaner ways:
using ref in a custom element.
custom attributes.
Include jQuery for using e.g. $('#myelement').addClass()
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'm learning meteor, and finding all kinds of difficulties dealing with nested subviews. Since the application I want to write is full of them... that looks like a difficulty. I found this on github, as a readme for a Meteor project to try and deal with this problem.
"I've been playing around with Meteor for a couple weeks. The ease of setup and the powerful reactivity makes this something I want to stick with. I was however frustrated by the difficulty of programmatically configuring, instantiating, destroying and nesting subviews."
Is this an issue that can be handled in Meteor (without adding a lot of complicated work arounds) or should I look for a different platform ?
I love nesting templates. I get reliable results. I now program off a library of both templates and helper functions (usually for form elements) that compose html for me. HTML is a byproduct, and the files we call .html are really a javascript DSL.
There are many S.O. issues raised about insertions into sorted lists giving people problems. I haven't had time to look.
My rule of thumb: Meteor is (well) designed from the beginning to do this easily and reliably.
So far the harder thing to solve was when I added an accordion from foundation, and a refresh of the document led to its initial state (being all closed, or one open). I had to put code in that saved the current section, and code to re-assert that in the rendered callback for the template that used it.
Why not write a prototype of the nesting with just a field or two in places, and find what bothers you?
Here is a sample chain. You see all the nested templates. This template itself is running within multiple.
First template: called 'layout', suggested by iron router. Has basic page and menu. Main body is a yield, set by router. On a sample page, a route calls template 'availability'
<template name='availability'>
{{#each myAgents}}
<form class="custom" id="Agent_{{_id}}" action="">
<div id='availability' class="section-container accordion" data-section="accordion">
<section id="services">
<p class="title" data-section-title><a href="#">
Your Info
</a></p>
<div class="content" data-section-content>
{{>services}}
</div>
</section>
<section id="skills">
<p class="title" data-section-title><a href="#">
Skills
</a></p>
<div class="content" data-section-content>
{{>skills}}
</div>
</section>
<section id="sureties">
<p class="title" data-section-title><a href="#">
Sureties
</a></p>
<div class="content" data-section-content>
{{>sureties}}
</div>
</section>
<section id="time">
<p class="title" data-section-title><a href="#">
Time Available
</a></p>
<div class="content" data-section-content>
{{>time}}
</div>
</section>
<section id="schedule1">
<p class="title" data-section-title><a href="#">
Schedule 1
</a></p>
<div class="content" data-section-content>
{{>schedule}}
</div>
</section>
<section id="schedule2">
<p class="title" data-section-title><a href="#">
Schedule 2
</a></p>
<div class="content" data-section-content>
{{>schedule}}
</div>
</section>
<section id="distance">
<p class="title" data-section-title><a href="#">
Distance
</a></p>
<div class="content" data-section-content>
{{>distance}}
</div>
</section>
</div>
</form>
{{/each}}
</template>
sample further nest:
<template name='services'>
{{label_text fname='name' title='Agent Name' placeholder='Formal Name' collection='agent' passthrough='autofocus=autofocus ' }}
{{label_text fname='agentInCharge' title='Agent In Charge' placeholder='Owner' collection='agent' }}
{{label_text fname='phone' title='Phone Number(s)' placeholder='Include Area Code'collection='agent' }}
{{>gps }}
<h4>Not shared:</h4>
{{label_text fname='email' title='Email:' placeholder='you remain anonymous' collection='agent' }}
</template>
and label_text is a helper, learned from the https://github.com/mcrider/azimuth project:
generateField = (options) ->
options.hash.uniqueId = options.hash.fieldName + "_" + Math.random().toString(36).substring(7) if options.hash.template is "wysiwyg"
options.hash.id = options.hash.id or #_id
options.hash.value = options.hash.value or this[options.hash.fname]
# allow for simple params as default
options.hash.title = options.hash.title or options.hash.fname
options.hash.template = options.hash.template or "label_text"
options.hash.placeholder = options.hash.placeholder or options.hash.title
# compatible with old
options.hash.fieldName = options.hash.fieldname or options.hash.fname
options.hash.label = options.hash.label or options.hash.title
# FIXME: Return error if type not valid template
new Handlebars.SafeString(Template[options.hash.template](options.hash))
Handlebars.registerHelper "label_text", (options) ->
options.hash.collection = options.hash.collection or 'generic'
generateField.call this, options
I am fairly new to Meteor, but I found out really soon that I wanted nested views (aka dynamic includes or sub-templates). I'm not sure whether this is what you mean, but here is my solution.
I created the following handlebars helper, that can be used to create sub-templates:
Handlebars.registerHelper('subTemplate', function(container, property, context, options) {
if (container && container.hasOwnProperty(property)) {
var subTemplate = container[property];
if (typeof subTemplate === 'function') {
return new Handlebars.SafeString(subTemplate(context || this));
}
else if (typeof subTemplate === 'string') {
return new Handlebars.SafeString(Template[subTemplate](context || this));
}
}
});
It can be used inside something I call a generic template. For example to create a list:
<template name="item_list">
<ul class="items-list">
{{#each items}}
<li class="listview-item">
{{subTemplate .. 'listItem' this}}
</li>
{{/each}}
</ul>
</template>
Now invoking this generic template requires that a 'listItem' property is present within its context. This can be either a string with the name of the sub-template, or the inline definition of a sub-template. The example below shows both options:
<template name="my_list">
{{! First option, referring to the sub-template by name:}}
<div>
{{#with listData listItem="my_list_item"}}
{{> item_list}}
{{/with}}
</div>
{{! Second option, inlining the sub-template:}}
<div>
{{#with listData}}
{{#assignPartial 'listItem'}}
<span>{{name}}</span>
{{/assignPartial}}
{{> item_list}}
{{/with}}
</div>
</template>
<template name="my_list_item">
<span>{{name}}</span>
</template>
Template.my_list.listData = function() {
return {
items: collections.people.find()
};
};
The second option requires an extra handlebars helper.
Handlebars.registerHelper('assignPartial', function(prop, options) {
this[prop] = options.fn;
return '';
});
I made more of these kinds of useful helpers, at some point I will probably share them on GitHub.
I'll start by saying that I am working within the context of DotNetNuke7, which is essentially ASP.net based framework, and that i am fairly new to KO.
I am trying to have one ko viewmodel and have two foreach loops in it. Each loop renders an array which is part of the view model definition like so:
//We build two arrays: one for the users that are in the group
//and one for the users that are not in the group
var nonGroupMembers = $.map(initialData.NonGroupUsers, function (item) { return new Member(item); });
var groupMembers = $.map(initialData.GroupUsers, function (item) { return new Member(item); });
//The members we start with before we added new members
self.SearchTerm = ko.observable('');
self.CircleMembers = ko.observableArray(groupMembers);
self.NonCircleMembers = ko.observableArray(nonGroupMembers);
In the html context (or the asp user control) i placed the following code
<div id="socialDirectory" class="dnnForm dnnMemberDirectory">
<ul id="mdMemberList" class="mdMemberList dnnClear" style="display:none"
data-bind="foreach: { data: NonCircleMembers, afterRender: handleAfterRender },
css: { mdMemberListVisible : Visible }, visible: HasMembers()">
<li class="memberItem">
<div data-bind="visible: $parent.isEven($data)">
<%=MemberItemTemplate %>
</div>
<div data-bind="visible: !$parent.isEven($data)">
<%=MemberAlternateItemTemplate %>
</div>
</li>
</ul>
</div>
<div class="circleDirectory" id="circleDirectory" >
<ul id="cdMembersList" data-bind =" foreach: {data: CircleMembers, afterRender: handleAfterRender}">
<li class="memberItem">
<div class="mdMemberDetails">
<a href="" class="mdMemberImg" data-bind="attr: { title: DisplayName, href: ProfileUrl }">
<span><img data-bind="attr: { src: getProfilePicture(50,50), title: DisplayName }" /></span>
</a>
<ul class="MdMemberInfo">
<li class="mdDisplayName" >
<a href="" title="" class="mdMemberTitle"
data-bind="attr: { title: DisplayName, href: ProfileUrl },
event: { mouseover: $parent.showPopUp }">
<span data-bind="text: DisplayName"></span>
</a>
</li>
<li class="mdTitle"><p><span data-bind="text: Title"></span></p></li>
<li class="mdLocation"><p><span data-bind="text: Location()"></span></p></li>
</ul>
</div>
</li>
</ul>
</div>
Each one of the DIVs which contain the foreach binding loop in them works perfectly well without the other. For instance, the bottom div (id= cdMembersList) will work fine but when I add the upper div with the binding markups it will stop working. The same thing happens vise verse.
Does anybody have a clue why it might happen? Can i not have 2 loops in one view model?
looking forward to solving this mystery.
thanks,
David
Ok, I hate to say it but the answer is very simple as always. I didn't add to my view model the Visible property for
css: { mdMemberListVisible : Visible }
When I created a new script file I simply skipped this property. A few lessons:
You can run more than one loop in one view model.
Always check that you have all the properties defined in the view model.
Also, apparently it helps creating a question on this board since it makes you think clearly about the problem and revisit your actions. I had spent 2 hours chasing this problem before i posted my question, and then it took me 15 minutes to solve it after I posted it.