I'm new to Umbraco, the issue that I have a 5 root nodes, and I've got a list of random pages that are contained within those root nodes. The data I'm receiving back from these pages are NodeId, NodeName and Level. What I'm trying to do is get root node information for each of the pages I have. Unfortunately this is where I'm getting issues, is there a way to get the root node or level 1 node's information based on a NodeId.
This is what I've got so far:
foreach (var item in pages)
{
int level = item["level"].AsInt();
if (level > 1){
var currentItem = library.GetCurrentDomains(item.Id);
}
}
Ive tried library.GetCurrentDomains(item.Id) however this doesnt work.
Not entirely sure if this is what you need, nor if it's the best way, but you could do something like
item.Path.Split(',')[1]
to get the second level "root" of any node. I think ;-)
Assuming the list of random pages are all IPublishedContent, you can use the extension method AncestorOrSelf(1) on the page, which will get the root node for the page. E.g.
foreach (var item in pages)
{
var rootPage = item.AncestorOrSelf(1);
//do something with the root node here
}
Related
Hello I currently have a TreeView with the following structure:
Root
Child
Root
Child
Root
Child
Child
RootN
ChildN
The TreeView structure can basically have NRootNodes - NChildren and the NRootNodes can have NRoots and NChildren so basically just like Windows Explorer Window.
My current issue that I have is that I have to get all the Parents or Root, in this case Roots / RootN and then I have to Remove all of their Child Nodes, in this case Child / ChildN. In the end I have to have only the Parent Nodes and then Clone them so I can move them to a different location within the TreeView.
RootNodes have a unique Tag - Folder and ChildNodes have another unique Tag - Calculations, as I have said earlier, I have to get rid of all Calculations in the Selected Node so only the Structure of that Selected Node will Remain.
Basically in the end I have to have something like this:
Root
Root
Root
Root
Root
I have a recursive method that "scans" the SelectedNode and gets all the Parents:
public List<TreeNode> CollectParentNodes(TreeNodeCollection parentCollection, List<TreeNode> collectedNodes)
{
foreach (TreeNode node in parentCollection)
{
if (!collectedNodes.Contains(node.Parent))
{
collectedNodes.Add(node.Parent);
parentNodeAdded = true;
}
if (node.Level != 0 && node.Tag.ToString() != Enumerations.NodeType.Calculation.ToString())
collectedNodes.Add(node);
if (node.Nodes.Count > 0)
CollectParentNodes(node.Nodes, collectedNodes);
}
parentNodeAdded = false;
return collectedNodes;
}
In the end I have a List that will hold all the Parents but the problem I'm facing is that that Parents also contain their descendents, in this case the Calculations
I have searched Google and StackOverFlow but I could not find anything of help, I appologize in advance if this has already been answered.
Thank you.
You can create an extension method GetAllNodes for TreeView that return List
Remember using using System.Linq; at top of your code
public static class Extensions
{
public static List<TreeNode> GetAllNodes(this TreeView tree)
{
var firstLevelNodes = tree.Nodes.Cast<TreeNode>();
return firstLevelNodes.SelectMany(x => GetNodes(x)).Concat(firstLevelNodes).ToList();
}
private static IEnumerable<TreeNode> GetNodes(TreeNode node)
{
var nodes = node.Nodes.Cast<TreeNode>();
return nodes.SelectMany(x => GetNodes(x)).Concat(nodes);
}
}
And the usage will be:
var result = this.treeView1.GetAllNodes().Where(x => x.Tag == "FOLDER").ToList();
Remember to add namespace of your extensions class at top of your code wherever you want to use it.
As an example you can set All nodes with tag of Folder to be in Red forecolor:
var result = this.treeView1.GetAllNodes().Where(x => (x.Tag as string) == "FOLDER").ToList();
result.ForEach(x => x.ForeColor = Color.Red);
And here is an Screenshot
This will create a new tree with the selected node as root and which child nodes consists only of nodes that are tagged "Folder".
You need to create a copy constructor (or extension method) to deep copy the node to prevent the manipulation on the node objects to impact your original tree source:
public TreeNode CollectFolderChildNodes(TreeNode selectedNode)
{
if (selectedNode.Tag == "Calculation")
return null;
// Get all the children that are tagged as folder
var childRootNodes = selectedNode.Children.Where((childNode) => childNode.Tag == "Folder";
// Clone root node using a copy constructor
var newRoot = new TreeNode(selectedNode);
newRoot.Children.Clear();
foreach (var childNode in childRootNodes)
{
// Iterate over all children and add them to the new tree
if (childNode.Children.Any())
{
// Repeat steps for the children of the current child.
// Recursion stops when the leaf is reached
newRoot.Children.Add(CollectFolderChildNodes(childNode));
}
else
{
// The current child item is leaf (no children)
newRoot.Children.Add(new TreeNode(childNode));
}
}
return newRoot;
}
I think this should do it, but I didn't tested it. But maybe at least the idea behind it is clear.
But as I mentioned before, maybe it's better to traverse the tree (using same ItemsSource) and set a property (e.g. IsHidingCalculations) to true so that only the folders will show up. You would need to implement an ItemsStyle and use a trigger that sets the items Visibility to Collapsed when your IsHidingCalculations evaluates to true.
To clone a node without its children you can create an extension method like this:
public static TreeNode CloneWithoutChildren(this TreeNode node)
{
return new TreeNode(node.Text, node.ImageIndex, node.SelectedImageIndex)
{
Name = node.Name,
ToolTipText = node.ToolTipText,
Tag = node.Tag,
Checked = node.Checked
}
}
and then:
collectedNodes.Add(node.CloneWithoutChildren());
Doing this code will expand all the main nodes under root.
root
images
files
docs
But I want to make that if I change it from 0 to 1 somehow to change the level so it will expand the next level.
root
images
myimages
files
myfiles
docs
mydocs
foreach (TreeNode tn in treeView1.Nodes)
{
if (tn.Level == 0)
tn.Expand();
}
I tried to add in the foreach:
if (tn.Level == 1)
tn.Expand();
But that's not a solution.
Maybe I need foreach in foreach?
All this code is part of a method that is working under BackgroundWorker that get a list of my FTP server directories and files recursively.
So in real time while it's getting the directories and adding the nodes I want to expand the nodes level.
Because the data structure is recursive, IMHO the most appropriate way to deal with the issue is to traverse it recursively. Something like this:
void ExpandToLevel(TreeNodeCollection nodes, int level)
{
if (level > 0)
{
foreach (TreeNode node in nodes)
{
node.Expand();
ExpandToLevel(node.Nodes, level - 1);
}
}
}
You would call it like this:
ExpandToLevel(treeView1.Nodes, 1);
That would expand just the first level. Pass 2 to expand the first two levels, etc.
Should be a simple answer.
I am using Umbraco 4.11 and I need to get the parent Node of a cast node. I am a bit of a noob to C# and I am fixing a control someone else made. Should be simple but it was originally written before the DLL update from 4.7 to 4.11.
So below is my code. I need to get the parent Node. What would be the correct syntax to do this. You can see where the old code is commented out.
Thanks in advance.
//New using
using umbraco.NodeFactory;
private string GetEmailContactProperty()
{
Node node = Node.GetCurrent();
string email = null;
do
{
if (node.NodeTypeAlias == NodeTypeAlias)
{
email = node.GetProperty("emailContact").Value;
if (!String.IsNullOrEmpty(email))
break;
}
//node = node.Parent;
//***Need Parent Node here. new Node is asking for Overload.
node = new Node().Parent;
} while(node.Parent.Id > -1);
The original code should do what you are asking with regards to getting the parent node.
node = node.Parent;
Basically, from your code you want to traverse up the tree, across your ancestors, to find a property named "emailContact" that is not IsNullOrEmpty.
I think what you are looking for is a piece of code like this:
var emailContact = CurrentModel.AncestorsOrSelf().Items.Where(n => !string.IsNullOrWhiteSpace(n.GetProperty("emailContact").Value))
Another way would be to get property with the recursive flag set to true like so:
var emailContact = Model.GetProperty("emailContact ", true).Value;
(See this post: http://our.umbraco.org/forum/developers/razor/19005-Recursive-fields-using-Razor-macro?p=1)
On a side not, it looks like you are currently working with Documents and not "content nodes", is this a back office control or a front end control?
Hope this helps
In my umbraco project, i require values in the "last Edited" tab, inside C# code.
How can i get those values?
Please Help,
Thanks.
It's quite simple. Here's one way of doing it:
// Assure the query is done to the root node, in this case I was on the root controller.
var recentUpdatedNodes =
Model.Content.DescendantsOrSelf().OrderByDescending(x =>
x.UpdateDate).Take(50);
foreach (var node in recentUpdatedNodes)
{
#node.Name
#node.Url
#node.Id
}
Hi I am populating an dynamic XML file into telerik treeview as hierarchy tree view as below.
Modules //root node
* Organization //Parent node
*Policy //Child of Organization
*Transports
* Employess
*Salary
* Rewards
*Winners
When i am going to select Modules-> Organization -> Policy , I want to get this hierarchy in my client event but Now I am getting the last node value only as "Policy". I want to get the full path of this herarchy.
And my client event code is:
function onSelect(e) {
debugger;
var tv = $('#HierarchyView').data('tTreeView');
var file = tv.getItemValue(e.item); // Here I am getting the last node name as "Policy", I want to get it as Modules-> Organization -> Policy
var nodeElement = e.item;
}
Can anyone please tell me the way to get that Hierarchy? Its Urgent.
Thanks.
This is the solution:
Telerkik Documentation for Node Path with javascript
regards