Copied to clipboard

Flag this post as spam?

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


  • dominik 711 posts 733 karma points
    Jul 30, 2012 @ 12:31
    dominik
    0

    Count Items issue (mark last item)

    Hello,

    I try to count items inside the embedded content datatypes by using the following script:

    Model.AncestorOrSelf().footerBottomLinks.Count();

    It always shows an error:

    'umbraco.MacroEngines.DynamicXml' does not contain a definition for 'Count'


    Any idea?

    What i try to do is to loop through the items and mark the last item with a different css class.
    I also tried it by using .IsLast in the foreach loop but this also does not work

    Thanks


  • Barry Fogarty 493 posts 1129 karma points
    Jul 30, 2012 @ 14:24
    Barry Fogarty
    0

    If you look at the XML in umbraco.config you should spot the issue with your above code - the "footerBottomLinks" actually contains a 'data' child node which itself contains an 'item' child node for each link you have defined in your footer.

    You could try using xPath:

    Model.XPath("//footerBottomLinks/data/item").Count();

    or you could count in a loop

     

    var count = 0;
    foreach (dynamic item in Model.AncestorOrSelf().footerBottomLinks)
    {
      count++;

    }

    Another solution, if you are using jQuery, is to use the last() method.  So say your items are all <li>'s inside a <ul> of class 'footerlinks':

     

    $('.footerlinks li').last().addClass('last-item-class');

     

     

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Jul 30, 2012 @ 14:25
    Sebastiaan Janssen
    0

    Which version of Umbraco are you using? I've just tested this on 4.8.0 and it works perfectly for me.

  • dominik 711 posts 733 karma points
    Jul 30, 2012 @ 14:31
    dominik
    0

    Hello 

    I am using version 4.7.0

    I also tried the count in the loop but how can i use the "IsLast" helper method? I still cant get it working

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Jul 30, 2012 @ 14:38
    Sebastiaan Janssen
    0

    I would like to reproduce, which datatype are you using for your footerBottomLinks property?

  • dominik 711 posts 733 karma points
    Jul 30, 2012 @ 14:50
    dominik
    0

    Hi Sebastian i am using EmbeddedContent Datatype

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Jul 30, 2012 @ 16:03
    Sebastiaan Janssen
    0

    Alright, I just did a quick proof of concept in v4.8.0. I do recall that the DynamicXML problem you're having was fixed in 4.7.2 so I recommend upgrading to at least that version (but why stop there, 4.8.0 is great as well).

    I installed embedded content and configured it as such, note the "link" alias here:

    Then, I wrote the following Razor script for it. Note that I am assuming that you want to check if the current page has any footer links, if not you want to look at the parent for footer links, then the parent's parent etc. The "link" alias returns in the line that gets the nodeId  (footerBottomLink.link.InnerText):

    @{
      var node = Model;
      while (node.Level >= 1 && node.footerBottomLinks.Count() == 0)
          {
             node = node.Parent;
          }
    }
    @node.footerBottomLinks.Count()
    <br />
    @foreach(var footerBottomLink in @node.footerBottomLinks) {
     @Model.NodeById(footerBottomLink.link.InnerText).Name
     <br />
     @footerBottomLink.IsLast()
     <br />
    }
  • dominik 711 posts 733 karma points
    Jul 30, 2012 @ 16:14
    dominik
    0

    Hi Sebastian,

    FOr me its hard to update to a newer version because everything must be checked again by our QA. Is there any workarround to get this running with umbraco 4.7.0?

     

    It seems like @node.footerBottomLinks.Count() is not working in version 4.7.0?

  • Barry Fogarty 493 posts 1129 karma points
    Jul 30, 2012 @ 16:21
    Barry Fogarty
    0

    Dominik, did you try using the simple foreach loop method?  If you are not able to upgrade and the helper methods are unavailable, this may be the best workaround.

    var count =0;
    foreach(dynamic item inModel.AncestorOrSelf().footerBottomLinks)
    {
      count
    ++;

    }
  • dominik 711 posts 733 karma points
    Jul 30, 2012 @ 16:59
    dominik
    0

    Hi Barry,

    How can i get the last item with your foreach loop?

    I can loop through all items - that works but how can i now apply a specific cssClass for the last item?

    THanks

  • Barry Fogarty 493 posts 1129 karma points
    Jul 30, 2012 @ 17:11
    Barry Fogarty
    0

    Its a bit of a kludge but I would do one loop to make the count (as above) and then a second loop

     

    var i = 0;
    foreach
    (dynamic item in Model.AncestorOrSelf().footerBottomLinks)
    {
      i++;
    var cssClass = (i == count) ? "last" : "normal";
    <li class="@cssClass">@item.Name</li>
    }

     To be quite honest I would solve this problem with jQuery usually, as I pointed out above, but this option may not be viable for you:

    $('.footerlinks li').last().removeClass('normal').addClass('last');
  • Ravi Motha 290 posts 500 karma points MVP 8x c-trib
    Jul 30, 2012 @ 18:36
    Ravi Motha
    0

    Sorry if I am misinterpreting what you want, but do you want to do ?

    which is effecxtively what barry and Sebaastian have suggedsted I've just combined it to a bit of pseudo code to understand what you want? or are you also getting issues using the IsLast?

    Ravi

     

    var count =0;
    foreach(dynamic item inModel.AncestorOrSelf().footerBottomLinks)
    {
    if @footerBottomLinks.IsLast() {
    Do your stuff here
    }
    count++;

     

  • Barry Fogarty 493 posts 1129 karma points
    Jul 30, 2012 @ 18:39
    Barry Fogarty
    0

    Hi Ravi the IsLast() method does not work on 4.7.0 apparently so we wre offering some workarounds..

  • Ravi Motha 290 posts 500 karma points MVP 8x c-trib
    Jul 30, 2012 @ 18:49
    Ravi Motha
    0

    that was what i was double checking and making sure we hadn't missed the obvious.

     

     

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Jul 31, 2012 @ 08:48
    Sebastiaan Janssen
    0

    So, I installed 4.7.0 and combined the solutions by Barrry and Ravi here, this works for me now (remember that in the embedded content datatype definition the links are aliassed as "link" which I'm using in @Model.NodeById(item.link) 

    @{
      var count = 0;
      foreach(dynamic item in Model.AncestorOrSelf().footerBottomLinks)
      {
        count++;
      }
    
      var count2 = 0;
      foreach(dynamic item in Model.AncestorOrSelf().footerBottomLinks) 
      {
        count2++;
        var IsLast = count == count2;
        <p>@Model.NodeById(item.link).Name - IsLast: @IsLast</p>
      }
    }
  • dominik 711 posts 733 karma points
    Jul 31, 2012 @ 10:38
    dominik
    0

    HI Sebastian,

    This works - thanks a lot

  • dominik 711 posts 733 karma points
    Jul 31, 2012 @ 12:27
    dominik
    0

    Now i got another issue

    I want to create two divs. one for the first 5 items and the other for the second 5 items of the embedded content

    If i try to use Where statement:

    foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Where(@i < 6)

    i always get:

    'umbraco.MacroEngines.DynamicXml' does not contain a definition for 'Where'

    It looks like i am not allowed to use filters. 

    Thanks


  • Barry Fogarty 493 posts 1129 karma points
    Jul 31, 2012 @ 12:58
    Barry Fogarty
    0

    Try 

    foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Take(5)

    and

    foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Skip(5).Take(5)

    Not sure if this will work on your version as it seems a lot of the Razor stuff in 4.7.0 is buggy.  Sebastiaan will test I'm sure!

    By the way, please mark the post that best answered your original issue as the solution, and then create a new topic for this new issue.  That will help others when searching for answers in the future.  Thanks.

  • dominik 711 posts 733 karma points
    Jul 31, 2012 @ 13:02
    dominik
    0

    Its really hard if most of the code described in the razor cheat sheet is not working on version 4.7.0

    I am not able to update to a newer version without a lot of effort but i want to change my xslt macros to razor

    Any suggestions how to proceed here?

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Jul 31, 2012 @ 13:28
    Sebastiaan Janssen
    0

    Skip and Take don't work, you will have to do the same trick with a counter and then inside the foreach do if (count <= 5) { // do something }

    I have no other suggestion than to upgrade to 4.7.2 where all these things have been ironed out. Other than that you'll just have to be creative I'm afraid.

  • dominik 711 posts 733 karma points
    Jul 31, 2012 @ 13:43
    dominik
    0

    Hi Sebastian 

    As i am not able to update to version 4.7.2 I tried to use this if statement but the problem is that if have to place a div outside of the foreach loop

    As an example

    <div class="column1">should include <ul><li>item1 - 5</li></ul></div>
    <div class="column2">should include <ul><li>item6 - 10</li></ul></div>

    If i try to use the if statement it just checks if there are more than 5 and applies always the column2 class 

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Jul 31, 2012 @ 15:31
    Sebastiaan Janssen
    1

    Well, as said, be creative, but you're soon getting code explosion (as you can see below), hardcoded values and triple enumeration, which will start to hurt performance. 

    How hard would it be to sneak in ONLY 4.7.2's umbraco.MacroEngines.dll? So you would ONLY upgrade the razor implementation and nothing else, everything else will be plain old 4.7.0. If that's still impossible, you might want to keep using XSLT and start using Razor in the next site you're doing.

       var IsLast = false;
        var count2 = 0;
        <div class="column1">
            <ul>
            foreach(dynamic item in Model.AncestorOrSelf().footerBottomLinks) 
            {
                count2++;
                if(count2 <= 5) 
                {
                    IsLast = count2 == 5;
                    <li>@Model.NodeById(item.link).Name - IsLast: @IsLast</li>
                }
            }
            </ul>
        </div>    
    
        @{ count2 = 0; }
    
        <div class="column2">
            <ul>
            foreach(dynamic item in Model.AncestorOrSelf().footerBottomLinks) 
            {
                count2++;
                if(count2 > 5 && count2 <= 10) 
                {
                    IsLast = count == count2;
                    <li>@Model.NodeById(item.link).Name - IsLast: @IsLast</li>
                }
            }
            </ul>
        </div>
    
  • dominik 711 posts 733 karma points
    Jul 31, 2012 @ 15:45
    dominik
    0

    Thanks a lot Sebastian,

    Will XSLT scripts work in Umbraco 5 or have i to replace all of my xslt scripts (about 40) ?

    I think before i have to change all the scripts to razor we are forced to update our umbraco version otherwise I will not be able to use razor in the correct way.

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Jul 31, 2012 @ 15:54
    Sebastiaan Janssen
    0

    In case you hadn't noticed, Umbraco v5 got pulled. There are currently no plans in the roadmap to remove XSLT from v4, so it will still keep working for a long time to come.

Please Sign in or register to post replies

Write your reply to:

Draft