All my recent projects has implemented umbracoNaviHide inside a True/False property, and they all work just fine. In my 7.6.9 upgraded project, I simply cannot get a True/False value to work.
On my Master composition, I have a "Navigation" tab together with a True/False property. All my pages inherit through that composition.
When I do something like:
var menuItems = CurrentPage.Site().Children;
#foreach(var item in menuItems) {
if(item.IsVisible()) {
<!--show element-->
}
}
It doesn't work. It should work, as it has in all my lastest projects. Here's what I've tried:
var menuItems = CurrentPage.Site().Children.Where("Visible");
var menuItems = CurrentPage.Site().Children.Where("umbracoNaviHide == false"); //setting this to true gives me no results
var menuItems = CurrentPage.Site().Children.Where(x => x.IsVisible());
var menuItems = CurrentPage.Site().Children.Where("randomProperty == false"); //or true
foreach(var item in menuItems) {
if(!item.HasValue("umbracoNaviHide)) { <!-- show item --> }
if(item.GetPropertyValue("umbracoNaviHide")) == "false") { <!-- show item --> }
}
I think that's all. I did update my ModelsBuilder. I did restart the project. I did remove the property and readd it. I basically tried everything, but it just won't work.
What on earth?
UPDATE: Check out this. This is soooooooooooooooooooooooooooooooooooo weird:
#foreach(var item in menuItems) {
<p>#item.GetPropertyValue("umbracoNaviHide") - #item.Name</p>
}
This gives me the following:
FALSE - Our offers
FALSE - Technology
TRUE - Projects
FALSE - About us
FALSE - Gallery
TRUE - Contact
However, this is how the umbracoNaviHide is setup in the backoffice:
Ticked - Our offers
Not ticked - Technology
Ticked - Projects
Not ticked - About us
Not ticked - Gallery
Ticked - Contact
How the flying hell is this possible?
Ok, everything's clear now :)
You're using dynamic objects and you're trying to treat them as IPublishedContent. If they are not mapped correctly it behave weird and unpredictable.
As dynamic objects will be removed in the following Umbraco versions, I suggest to use strongly typed IPublishedContent objects or take advantage of ModelsBuilder and operate on generated models of specific types.
My test code is below. Both versions works in my test 7.6.9 solution.
// Dynamic object version - will be deprecated - don't use!
//var visibleChildItems = CurrentPage.Site().Children.Where("Visible");
// Strongly Typed version - suggested
var visibleChildItems = Model.Content.Site().Children(x => x.IsVisible());
<ul>
#foreach (var item in visibleChildItems)
{
<li>
#item.Name
</li>
}
</ul>
Hope it will solve your problem. If you'll be interested about operating through dynamic objects and how to get properties from them, check a little bit old, but still valid Razor Cheetsheet for Umbraco: https://our.umbraco.org/projects/developer-tools/umbraco-v6-mvc-razor-cheatsheets.
I cannot leave a comment so I'll post this as an answer. I had the same issue. In my case I had the default value set to checked, which I assumed was true. I set the default to unchecked. I went to umbracoNaviHide and then checked the box and it worked perfectly for me. I do thank you for pointing me in the right direction.
Related
I have the following web grid inside my Razor view on asp.net MVC 5 and i am using Entity framework 6.0:-
Now the web grid is working well on all the paging except for one paging, and when i checked it i found that the WebGrid will return this error:-
Column "SDUser.Department.Definition.DEPTNAME" does not exist.
So seems some items inside this page does not have those navigation properties SDUser.Department.Definition.DEPTNAME,, so how i can overcome this issue?
EDIT:- Here is my updated code, where i added If/Else but still i am getting the same error:-
Before adding new WebGridColumn in gridcolumns, you check whether DEPTNAME property is there or not.
#if(#Model.Content.FirstOrDefault().SDUser.Department.Definition.HasProperty("DEPTNAME"))
{
gridcolumns.Add(new WebGridColumn()
{
ColumnName = "SDUser.Department.Definition.DEPTNAME",
Header = Html.DisplayNameFor(model => model.Content.FirstOrDefault().SDUser.Department.Definition.DEPTNAME).ToString(),
CanSort = true
});
}
Additionally, if you want to check its value is there or empty then use this
#if(#Model.Content.FirstOrDefault().SDUser.Department.Definition.HasProperty("DEPTNAME") && #Model.Content.FirstOrDefault().SDUser.Department.Definition.GetProperty("productSalePrice").Value != String.Empty)
{
//your code
}
Note: I don't know actually your hierarchy of Model, I consider that specific page has not DEPTNAME property. (you are free to modify according to your requirement)
I'm building a image slider using Archtype in Umbraco.
I was using umbraco 7.5.9 and Umbraco.MediaPicker when I started this but in the mean time I started a new project with the newest version Umbraco (7.6.2) which uses Umbraco.MediaPicker2
It was no problem rendering images with the old MediaPicker but with the MediaPicker2 it seems impossible.
Here is my setup.
The Archtype:
Here is the partial view that rendered the old MediaPicker
<div class="fullWidthSlider">
#foreach (var image in #CurrentPage.SliderImages)
{
<div>Id: #image.GetValue("image")</div>#*Line added for debug*#
var media = #Umbraco.Media(image.GetValue("image"));
<img src="#media.Url" />
}
</div>
This used to work for the old Media picker and the #image.GetValue returned int id. But with the new MediaPicker2 it returns Umbraco.Core.Udi[]
If I foreach through the properties of the archtype with the code below I get this result (see below code)
#foreach (var fieldset in Model.Content.GetPropertyValue<ArchetypeModel>("sliderImages"))
{
foreach(var prop in fieldset.Properties){
<p>#prop.Alias - #prop.Value</p>
}
}
href -
altText - alt test
image - umb://media/c33bfe07a82b4df18a79db154139cb91
href -
altText - Fjall
image - umb://media/40d5778d34bb4035b5146c901de75212
Can anyone tell me how I can render image from this data.
Thanks
I just went on a roller-coaster figuring this out!
You can get an IPublishedContent from your image string using this code:
// Your string which is retrieved from Archetype.
var imageString = "umb://media/c33bfe07a82b4df18a79db154139cb91";
// Get the guid from this string.
var imageGuidUdi = GuidUdi.Parse(imageString);
// Get the ID of the node!
var imageNodeId = ApplicationContext.Current.Services.EntityService.GetIdForKey(guidUdi.Guid, (UmbracoObjectTypes)Enum.Parse(typeof(UmbracoObjectTypes), guidUdi.EntityType, true));
// Finally, get the node.
var imageNode = Umbraco.TypedMedia(imageNodeId.Result);
Check out this thread on Our Umbraco which covers this issue.
I used this comment to figure out how to get the ID from the image's guid.
It looks like Umbraco HQ is pushing for people to use the new ModelsBuilder with typed models. I'm not sure if Archetype is supported by the ModelsBuilder which is why there's so much trouble.
I personally use Nested Content on all of my projects as it performs the same functionality but (IMO) is better supported by Umbraco because it uses Document Types to store repeatable content schema. Because of this, it can then easily be mapped to IPublishedContent and therefore is supported by the ModelsBuilder!
I have created a folder in Umbraco and I would like to display a random image from that folder on my page.
I found a solution from a few years ago which was giving me compile errors
dynamic folder = Library.MediaById(1054);
var randomImage = folder.Children.Where("nodeTypeAlias = \"Image\"").Random();
I found that I have to add the proper inherits in my file
#using umbraco.MacroEngines
#inherits DynamicNodeContext
but this it gives me an error because I already have a #model I'm using in the first line
The 'inherits' keyword is not allowed when a 'model' keyword is used.
Thanks for any help
You can take a look and learn from sample macro partial views pre-installed in each Umbraco website. There is a snippet called List Images From Media Folder.
The code of the default snippet looks like this:
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#*
Macro to display a series of images from a media folder.
How it works:
- Confirm the macro parameter has been passed in with a value
- Loop through all the media Id's passed in (might be a single item, might be many)
- Display any individual images, as well as any folders of images
Macro Parameters To Create, for this macro to work:
Alias:mediaId Name:Select folder with images Type:Single Media Picker
*#
#{ var mediaId = Model.MacroParameters["mediaId"]; }
#if (mediaId != null)
{
#* Get all the media item associated with the id passed in *#
var media = Umbraco.Media(mediaId);
var selection = media.Children("Image");
if (selection.Any())
{
<ul>
#foreach (var item in selection)
{
<li>
<img src="#item.umbracoFile" alt="#item.Name" />
</li>
}
</ul>
}
}
We need to remember to add the parameter to macro if we're using them there.
Then we can use both: Media or TypedMedia helper methods to retrieve folder (which is typical media item with different type), despite of the required returned type. I usually use TypedMedia to be able to operate on strongly typed object and preview properties in Visual Studio.
If we create macro properly and insert it on the template using code like this (with proper folder ID):
#Umbraco.RenderMacro("Test", new { mediaId="1082" })
we should see a list of images from this folder (all of them at that moment).
The final part is almost the same as you previously did it, but we need to adjust it a little bit. My final code and suggestion is below:
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#{
var folderId = Model.MacroParameters["mediaId"];
if (folderId != null)
{
var media = Umbraco.TypedMedia(folderId);
var rand = new Random();
var imagesInFolder = media.Children("Image");
if(imagesInFolder.Any()) {
var pick = imagesInFolder.ElementAt(rand.Next(0, imagesInFolder.Count()));
if (pick != null)
{
<img src="#pick.GetCropUrl()" alt="#pick.Name" />
}
}
}
}
Let me know if it solved your problem :)
I have a checkbox and a textbox (both are enabled and the checkbox starts unchecked [false]).
What I need is the following:
When I write something in the textbox and leave it (loses focus) the
checkbox is checked automatically.
When I write something in the
textbox, remove it and leave it the checkbox should remain
unchecked.
When I write something in the textbox and click the
checkbox, the checkbox is checked now and the data in the textbox is
not cleared.
When I write something in the textbox and click the
checkbox twice, first happens step 3 and then the checkbox is
unchecked and the data in the textbox is cleared.
When I click in the checkbox the checkbox is checked, then I write in the textbox
and uncheck the checkbox, then the data in the textbox is cleared.
What I tried so far is the following code:
//The checked property in the checkbox is binded to
that.BuildingCriteria.IncludeLoadingDocks
that.BuildingCriteria.IncludeLoadingDocks.subscribe(function (newValue) {
if (!that.updatingTextBox && !newValue) {
that.BuildingCriteria.LoadingDocksMin(null);
}
});
//The textbox value is binded to that.BuildingCriteria.LoadingDocksMin
that.BuildingCriteria.LoadingDocksMin.subscribe(function (newValue) {
that.updatingTextBox = true;
that.BuildingCriteria.IncludeLoadingDocks(true);
that.updatingTextBox = false;
});
This works if you try all the steps above, for all of them but then, when you try some of them again stops working for some... specially if you write something in the textbox with the checkbox unchecked and then leave the textbox, it doesn't check the checkbox automatically anymore.
I tried using flags as you can see but I couldn't make it to work on ALL the cases ALWAYS.
I've been working on this for days so if you can help me out soon I'd appreciate it a lot!
Thanks in advance!!
It's near impossible to gave a straight up answer to your question, but from it I feel the closest thing may be to note a few KO features that you may yet need to consider.
The value binding supports a valueUpdate = 'afterkeydown' version, which would allow you to keep your textbox and checkbox in synch real time. This may well remove the need for requirement 3.
The computed observable supports specializing read and write operations, which at times may be clearer than using subscriptions.
You may need to introduce a "grace" period for the checkbox, if you must stick with requirement 3. Just don't allow updating the checkbox too shortly after leaving the textbox. The throttle extender and hasfocus binding can help you with that.
There's a great blogpost on when to use which feature.
In any case, your requirements are a bit hard to understand without the business case, and it might even be that you're experiencing an XY-problem. From your implementation requirements I'd assume functional (not implementation) requirements like this:
There's a textbox to hold the actual order/criterium/name/whatever.
There's a checkbox to indicate such an order/etc is wanted.
This checkbox should be in synch (checked) with whether the user typed some text.
This checkbox should be in synch (unchecked) if the user empties the textbox.
If the user checks the checkbox then
If there was text for the order/etc it should be cleared.
If there was no text a default order/etc should be suggested.
Here's a jsfiddle with a demo of how you could approach these functional requirements. For completeness, here's the relevant code, starting with the View:
<input type="checkbox" data-bind="checked: isChecked" />
<input type="textbox" data-bind="value: someText, valueUpdate: 'afterkeydown', selectSuggestion: someText" />
The custom binding for selecting the "default suggestion text":
var suggestion = "<enter something>";
ko.bindingHandlers.selectSuggestion = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var currentText = ko.utils.unwrapObservable(valueAccessor());
if (currentText === suggestion) element.select();
}
};
And the ViewModel:
var ViewModel = function() {
var self = this;
var privateIsChecked = ko.observable(false);
var privateText = ko.observable("");
self.isChecked = ko.computed({
read: privateIsChecked,
write: function(value) {
if (!privateIsChecked() && value && privateText() === "") {
privateText(suggestion);
}
if (privateIsChecked() && !value) {
privateText("");
}
privateIsChecked(value);
}
});
self.someText = ko.computed({
read: privateText,
write: function(value) {
privateIsChecked(value !== "");
privateText(value);
}
});
}
I'm aware that this doesn't directly answer your question, but like I said that's pretty hard to do for us on Stack Overflow, without knowledge of your business case.
I am using Knockout Js for my view page. I have a requirement where if any editable field changes, I have to enable Save button else not. This is working nicely.
My issue is I have checkboxes too for each row of item. These are observable items in my viewModel. What happens now is when I check or uncheck any checkbox, Knockout considers that as Dirty item and enables the Save button which I don't want.
How can I tackle this?
I am not sure of the exact code that you are using for a dirty flag, but if it involves using ko.toJS in a dependentObservable like this, then there is a trick that you can use to have it skip some observables.
If you create an observable that is a property of a function, then ko.toJS will not find it.
Here are two examples (someFlag and anotherFlag):
function Item(id, name) {
this.id = ko.observable(id);
//create a sub-observable that the dirty flag won't find
this.id.someFlag = ko.observable(false);
this.name = ko.observable(name);
this.dirtyFlag = new ko.dirtyFlag(this);
//or similarly, place an observable on a plain ol' function
this.forgetAboutMe = function() { };
this.forgetAboutMe.anotherFlag = ko.observable(false);
}
Sample here: http://jsfiddle.net/rniemeyer/vGU88/