Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Bo Damgaard Mortensen 719 posts 1207 karma points
    Apr 03, 2013 @ 22:42
    Bo Damgaard Mortensen
    0

    Descendant nodes and OrderBy SortOrder

    Hi all,

    I'm having a bit of trouble sorting descendant nodes by their sortOrder property.

    If I have the following content structure:

    - Content
         - News
              - 2012
                   - November
                         - Newsitem 1
                         - Newsitem 2
                   - December
                         - Newsitem 3
                         - Newsitem 4
    
               - 2013
                   - January
                         - Newsitem 5
                         - Newsitem 6
                   - February
                         - Newsitem 7
                         - Newsitem 8

    If I want the descendants nodes of type "NewsItem" like this (Model being the "News" node):

    var news = Model.Descendants("NewsItem").OrderBy("SortOrder");

    the DynamicNodeList will look like this:

    NewsItem1
    NewsItem3
    NewsItem5
    NewsItem7
    NewsItem2
    NewsItem4
    NewsItem6
    NewsItem8

    Is there any way to get the descedant nodes by their actual sort order? :-) I know I could just order the nodes by their Id, createDate or updateDate, but it doesn't make sense since it's news items.

    Thanks in advance.

    All the best,

    Bo

  • gary 385 posts 916 karma points
    Apr 03, 2013 @ 23:39
    gary
    0

    Hi Bo

    You want the order that you have them in, ie the way they appear in the tree?

    If you just leave it blank, should work;

    var news =Model.Descendants("NewsItem")

    Loop on that and it will give by sort order - just to make sure move a couple and check, but should be ok.

    Regards G

     

     

     

  • Peter Doyle 10 posts 31 karma points
    Jul 23, 2014 @ 17:18
    Peter Doyle
    0

    I have come across this issue too. I am using a pager so just using the below code will not work.

    var news =Model.Descendants("NewsItem")

    It seems that the SortOrder of the nodes is baised on the parent node.

    The real sort order is as follows.

    -Content
         
    -News
             
    -2012
                   
    -November
                         
    -Newsitem1
                         
    -Newsitem2
                   
    -December
                         
    -Newsitem 1
                         
    -Newsitem2

               
    -2013
                   
    -January
                         
    -Newsitem 1
                         
    -Newsitem2
                   
    -February
                         
    -Newsitem1
                         
    -Newsitem2

    This means theu will be listed incorrectly.

  • gary 385 posts 916 karma points
    Jul 23, 2014 @ 21:05
    gary
    0

    Hi Peter

    What are you wanting to achieve? Do you want them to be in date order?

    I'm a little confused so can you post what it is you want and we should be able to work a solution

    Cheers

    gary

  • Peter Doyle 10 posts 31 karma points
    Aug 22, 2014 @ 16:45
    Peter Doyle
    0

    Hi Gary,

    Sorry for very delayed reply.

    I found a work around to this issue.

    to explain fully I was having the same issue as Bo but the pages in question were people profiles.

    Within umbraco the nodes were ordered like so:

    People
    - Management Team
    - - Person 1
    - - Person 2
    - - Person 3
    - Training Team
    - - Person 4
    - - Person 5
    - - Person 6
    - Admin Team
    - - Person 7
    - - Person 8
    - - Person 9

    When listed on the page using SortOrder they listed like so:

    Person 1
    Person 4
    Person 7
    Person 2
    Person 5
    Person 8
    Person 3
    Person 6
    Person 9

    This is not how I was expecing them to layout. The SortOrder is a local value for the current folder and the values work out as follows:

    People  : SortOrder = 1
    - Management Team  : SortOrder = 1
    - - Person 1  : SortOrder = 1
    - - Person 2  : SortOrder = 2
    - - Person 3  : SortOrder = 3
    - Training Team  : SortOrder = 2
    - - Person 4  : SortOrder = 1
    - - Person 5  : SortOrder = 2
    - - Person 6  : SortOrder = 3
    - Admin Team: SortOrder = 3
    - - Person 7  : SortOrder = 1
    - - Person 8  : SortOrder = 2
    - - Person 9  : SortOrder = 3

    I had to use a sort as I was using a pre-built C# pager that required a sort to be passed and it would default to SortOrder if no sort had been passed.
    To get around this I used the SortOrder of the parents first and then as a second sort I used the SortOrder of the people nodes.

    That resolved the issue I was having.

    Thanks

  • AvihayBit 149 posts 303 karma points
    Sep 03, 2014 @ 21:10
    AvihayBit
    0

    Hi Peter,

    Just expirienced the same problem.

    May I ask for your code for the workaround? because I cant figure out how should I relate their parent sortOrder?

    This is my code:

    var productsFolderDescendants = tempNode.Descendants("ProductItem").Where("Visible").OrderBy("sortOrder desc");

    How would you would make them sort by their parent sortOrder?

  • gary 385 posts 916 karma points
    Sep 03, 2014 @ 21:22
    gary
    0

    Hi AvihayBit

    You can use .GroupBy(), so using Peters example above

    var blob = Model.Content.AncestorsOrSelf(1).Descendants("teamNode").GroupBy("TeamNode");

    then @foreach (var item in blob.OrderBy("Person"))

    { @item.Person }

    To expalain, use GroupBy on your parent node, then foreach on the children and you should get your result.

    There is info in the wiki on groupBy which I have used so know it is ok.

    Hope this helps

    Gary

    If you get stuck I have some working code that I can post.

  • AvihayBit 149 posts 303 karma points
    Sep 03, 2014 @ 21:59
    AvihayBit
    0

    Hi Gary,

    Thank you for you answer, I asume its a good workaround for others, but I still having difficalt with this because Im using a paging for this big list of Descendants which I want to sort, so I cant group it and loop every group apart.

    my tree looks a little different:

    Folder

    -Folder

    --children 1

    --children 2

    --children 3

    -children 4

    -children 5

    ...

     

    I  want all childrens to sort like the logic sort order, so I have liste the by Descendants("DocumentType") and sorted them. And then get the sort issue. 

     

    Any new Idea but groups?

     

  • gary 385 posts 916 karma points
    Sep 03, 2014 @ 22:09
    gary
    0

    Hi

    That paging issue again, ok.

    If you go direct to the level you should get the order from the front end,

    var blob = Model.Content.AncestorsOrSelf(1).Descendants(3).Where("Visible");

    then @foreach (var item in blob.OrderBy("Person or whatever you need - if you do not add orderBy it will give you tree order"))

    { @item.Person }

    This will give all children on the level you require, you may have to play with it as I cannot see your whole tree, if you have other descendants elsewhere on that level you can add a blob.Where("DocTypeAlias ==("the one you want")") or something very similar

    Hope this helps more

    Gary

  • AvihayBit 149 posts 303 karma points
    Sep 03, 2014 @ 22:24
    AvihayBit
    0

    Hi

    All the problem started because Im trying to sort a list from two different levels. Like all the previous posts here.

    What you suggests sorting only one level...

    lets say its the whole tree:

    Catalog

    - Category

    - - SubCategory

    - - - Product 1

    - - - Product 2

    - - - Product 3

    - - Product 4

    - - Product 5

     

    I want the products in one list (for paging) that sorts like the above tree...

    BUT sortOrder cat give me this wish because Products 1-3 is in a different level of 4-5...

  • gary 385 posts 916 karma points
    Sep 04, 2014 @ 00:02
    gary
    0

    ok

    var category = Model.Content.AncestorsOrSelf("category");

    var products = category.Descendants();

    var subProduct = products("subCategory").Children();

    @{

    foreach var product in products

    { if category.Down(1).IsdocTypeAlias("subCategory")

    { foreach var subCategoryProduct in subProduct

    @subCategoryProduct.Url

    }

    else{

    @product.Url

    } }

    this is the logic that should get you that list and will not include the parent node in the subcategory - this is all of course version dependent, so best to run through it with intellisense, or just use straight == for docTypeAlias or whichever way you are more comfortable.

    or you could use if product.docTypeAlias == subCategory loop children either way this will take each descendant node in turn, then if it has children list them, if not, will just list that node, this should give you the logical order.

    Regards

    Gary

  • AvihayBit 149 posts 303 karma points
    Sep 04, 2014 @ 08:02
    AvihayBit
    0

    Hi Gary,

    Thank you, but its not the solution I'm after. 

    Your solution doesnt sorts any list, it just looping the childrens of each level. As i mentioned I'm trying to sort 1 list of items from two different levels.

     

    Thanks again for trying :)

    Avihay

  • Peter Doyle 10 posts 31 karma points
    Sep 04, 2014 @ 17:14
    Peter Doyle
    1

    Hi Avihay,

    I am not using Dynamic Razor and I am not very well versed with Dynamic Razor either.

    You can see how I am getting the parent sort order form my example bellow. The OrderBy Lambada statment is selecting the parent of the current item.I know this is not what you are looking for but I belive it might be of use to others that have the same issue.

     

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @{
            var node = Umbraco.AssignedContentItem;
            var people = node.Descendants("PersonProfile").Where(x => x.IsVisible()).OrderBy(x => x.Parent.SortOrder );
    }      
    @foreach (var person in people) { 

           @person.Name 

    }   

     

    Thanks,
    Pete    

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Sep 04, 2014 @ 17:23
    Nicholas Westby
    0

    If that doesn't work quite right, this may work too:

    var people = node.Descendants("PersonProfile").Where(x => x.IsVisible()).OrderBy(x => x.Parent.SortOrder).ThenBy(x.SortOrder);
    
  • AvihayBit 149 posts 303 karma points
    Sep 04, 2014 @ 18:29
    AvihayBit
    0

    Thanks You Peter and Nicholas,

    Nicholas- your code looks like the exact way for the solution but I cant figure out how to change it to the DynamicNode syntex... 

    If anyone know how to 'translate' that it would be really helpfull...

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Sep 05, 2014 @ 05:16
    Nicholas Westby
    0

    Hi AvihayBit,

    Why do you want to use the DynamicNode syntax? Does the your version of Umbraco not support the syntax Peter showed?

    I can answer your question, but I need to know:

    • Can you use the "normal" syntax rather than the DynamicNode syntax?
      • This is important because the normal syntax supports lambdas, which allow you to order by more complicated expressions.
    • Can you store some of the results in intermediate data structures (e.g., a list or dictionary)?
      • This is important if you can't use lambdas in the normal syntax. The alternative would be to store results and loop over them a couple times.

    By the way, after reading through this thread in more detail, I realized my above solution will not work for you due to the fact that you have products at multiple levels (i.e., some under subcategories and some under categories).

  • AvihayBit 149 posts 303 karma points
    Sep 05, 2014 @ 07:59
    AvihayBit
    0

    Hi Nicholas,

    Actualy I'm not sure why, I just use to use this syntex and have no expirience with the lambada, and when I use the lambada syntex the VS intellisence says:

    "Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type".

    My Code looks like this:

    @inherits umbraco.MacroEngines.DynamicNodeContext
    
    
    @{//that macro gets a ProductsFolder and ProductsPerPage as Parameters, and display that folder items by paging.
    var productsFolder = Parameter.productsFolder; // Chosen folder Id
    var tempNode = Library.NodeById(productsFolder); // Temporary Node of the folder
    int NumberOfItemsPerPage = Convert.ToInt32(Parameter.productsPerPage);  // Number of Items to display in every page
    
    var productsFolderDescendants = tempNode.Descendants("ProductItem").Where("Visible").OrderBy("sortOrder desc");
    ...
    

    If I replace this OrderBy with lambada syntex I get the error...

    Its a webform project if its changes anything.

    Thanks!!

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Sep 05, 2014 @ 08:16
    Nicholas Westby
    1

    I have to sleep, so I can't dig into this right now. But basically I'm thinking you can convert your dynamic node stuff into an IPublishedContent and go from there. Refer to this page: http://our.umbraco.org/projects/starter-kits/ublogsy/ublogsy-razor-blog/46773-Error-on-ToIPublishedContent(true)

    The code from that page I'm thinking you'll need is this:

    UmbracoHelper _helper = new UmbracoHelper(UmbracoContext.Current);
    var newModel = _helper.TypedContent(blogParentNode.Id);
    

    From there, you should be able to use the methods that make use of lambdas (I think). Also note that some of the code at that page is part of uBlogsy, so don't let that confuse you. Also, you may or may not need to import a few namespaces to access UmbracoHelper, UmbracoContext, and the extension methods on IPublishedContent (such as Descendants).

    If you want to learn more about UmbracoHelper, you can start here: http://our.umbraco.org/documentation/Reference/Querying/UmbracoHelper/

    Of particular note is this sentence from that link:

    Whether you are using MVC or WebForms you will be able to use UmbracoHelper to query/traverse Umbraco published data.

    So I guess that means you can use UmbracoHelper even though you are using WebForms.

  • AvihayBit 149 posts 303 karma points
    Sep 06, 2014 @ 19:36
    AvihayBit
    0

    Hi Nicholas,

    Glad to say it done! thanks to your direction. I hade to switch to partial view macro and update a lot of the code, but it was the right way to the solution.

    Thanks again!!

Please Sign in or register to post replies

Write your reply to:

Draft