Copied to clipboard

Flag this post as spam?

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


  • Charly 5 posts 26 karma points
    Oct 28, 2011 @ 12:44
    Charly
    0

    Start new div tag after 4th Item

    Hi, how would I go about starting a new list in a new div tag once the previous list has reached 4 items?

    So far I have :

    @{var param Parameter.dataType;}  
    <div class="row">
        @foreach (var item in @Model.AncestorOrSelf().Descendants(param))
        {  

        <div class="item"><href="@item.Url">@item.Name</a>
        </div>
         
        }
    </div>

    this currently lists all my items in one big div class row.

    I want to start the div tag row, fill it with 4 items, close the tag and then start a new div tag and fill it with another 4 items and repeat etc..

    I'd imagine I would have to write the first 4 items to a HTML string and then wrap that in the div tags or something ??

    Any help would be appreciated, Thank You!

  • Tony McBeth 8 posts 29 karma points
    Oct 28, 2011 @ 13:06
    Tony McBeth
    0

    Hi Charly

    You can use a for loop and use the index to write out the opening and closing tags i.e.

    for (int i = 0; i < @Model.AncestorOrSelf().Descendants(param).Count; i++)
        {
            bool renderRow = i % 4 == 0 ? true : false;
    
            if (renderRow)
            {
                <div class="row">
            }
    
            <div class="item">
                <a href="@item.Url">@item.Name</a>
            </div>
    
            @if (renderRow)
            {
                </div>
            }
        }
    

    This has not been tested so use as a guide only. Hope this helps,

    Tony

  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Oct 28, 2011 @ 14:54
    Dan Diplo
    0

    Check out http://umbraco.com/follow-us/blog-archive/2011/9/18/umbraco-razor-feature-walkthrough%E2%80%93part-7.aspx on how to use the Is helpers:

    IsHelper

    I like elegant code, especially in my Razor templates, and I found myself repeatedly having to write @foreach loops with a counter variable (e.g. int i = 0; i++) in order to track what node I was iterating over. In part 6, I introduced a new method called Index (aliased as position) which lets you get the current position.

    This index property has been combined with the parent and children methods on DynamicNode to solve a lot of your standard requirements when iterating over nodes and generating HTML. Since generating HTML is the primary job of Razor, so we want it to be as concise and as quick as possible.

    IsHelper (this is the internal name) methods all work the same, and have 3 overloads. They're basically ternary operators, but work a little nicer in that they're easy to embed in properties and quicker to write as you don't need so many brackets to make Razor understand them.
    The general idea behind IsHelper is to allow you to dynamically inject class names and style attributes onto your nodes, based on their position within the list you're iterating. You can use this for a variety of things such as alternating row colours or fixing the margin/padding on the first/last item etc.

    All DynamicNodes (except for the top most node) belong to a set, whether that's their parents list, or a special set created in context such as the result from Ancestors
    This means that when you're iterating over a set, the node will belong to that set, no matter where the original node was sourced from in the tree.
    What this means is that each node as you iterate has a concept of the list that contains it (that you are iterating) so a method call to that node can determine it's position in the iteration.

    Here are the overloads:
    IsHelper() => bool
    IsHelper(string valueIfTrue) => valueIfTrue || emptyString
    IsHelper(string valueIfTrue, string valueIfFalse) => valueIfTrue || valueIfFalse

    IsHelper is just an internal name though, so when calling them, you use the name of the specific IsHelper you want.
    These are:
    IsFirst
    If this is the first node in a set
    IsNotFirst
    If this is not the first node in a set
    IsLast
    If this is the last node in a set
    IsNotLast
    You guessed it! If this is not the last node in a set
    IsPosition, IsNotPosition
    Is the current node at index? Example: @item.IsPosition(3)
    IsModZero, IsNotModZero
    Is the current node position evenly dividable (modulus) by a given number? Will be true for every 3rd node: @item.IsModZero(3)
    IsEven, IsOdd
    Shorthand versions for IsModZero(2) and IsNotModZero(2)

     


  • Charly 5 posts 26 karma points
    Oct 28, 2011 @ 15:34
    Charly
    0

    Ok so far I've got :

    @{var param Parameter.dataType;}

        @foreach (var item in @Model.AncestorOrSelf().Descendants(param))
        {
         

           if(@item.IsFirst(|@item.IsModZero(4)){
          <div class="row">
          }
     
         
          
          <div class="item"><href="@item.Url">@item.Name</a></div>
         
         
          if(@item.IsLast(|@item.IsModZero(4)){
          </div>
          }
         
        
         }

     

    Thanks to Tony and Dan! But my second if statement is not being picked up as Razor, it's being rendered as HTML.

    I tried wrapping it in @{} but I get an error "The foreach block is missing a closing "}" character."

    I tried using just @ but still no luck. What am I missing?

  • Sara Coutinho 4 posts 24 karma points
    Feb 05, 2012 @ 17:12
    Sara Coutinho
    0

    Hi Charly,

    Here's my solution - not the most elegant for sure, would like to see how to use the helpers for this:

    @{
    int childrenNumber = item.Children.Count();
                       
    foreach (var itemChild in item.Children)
    {
        if (itemChild.Position() % 4 == 0)
        {
            @Html.Raw("<div>");
        }
                                              
        <a href="@itemChild.Url">@itemChild.Name</a>

        if (itemChild.Position() % 4 == 3 || itemChild.Position() == childrenNumber - 1)
        {
            @Html.Raw("</div>");
        }
    }
    }

    Cheers,
    Sara

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Feb 05, 2012 @ 18:36
    Jeroen Breuer
    5

    This might be easier :) https://gist.github.com/1067257

    Jeroen

  • Jez Reel R. Maghuyop 20 posts 62 karma points
    Jun 16, 2016 @ 08:11
    Jez Reel R. Maghuyop
    0

    Thanks Jeroen for the answer, saved me a lot of time.

  • Sara Coutinho 4 posts 24 karma points
    Feb 06, 2012 @ 11:15
    Sara Coutinho
    0

    Aha! Thanks =)

  • Greg McMullen 49 posts 195 karma points
    Jan 28, 2013 @ 19:47
    Greg McMullen
    0

    @Jeroen - Thanks for your code. Helped me group a large number of items together to form columns.

    @{
    var listings = Model.Descendants().Where("Visible");
    var listGroup = listings.Count()/2;
    <div>
    <p class="title">Foo</p>
        <div>
        @foreach ( var group in listings.InGroupsOf(@listGroup) )
        {
            <ul class="column">
                @foreach (var item in group){
                    <li><a href="@item.Url">@item.Name</a></li>
                }
            </ul>
        }
        </div>
    </div>
    }
  • MrFlo 159 posts 403 karma points
    Mar 27, 2016 @ 11:46
    MrFlo
    0

    I would add an extra number in case your division is returning a reminder.

    var listGroup = listings.Count()/3+(listings.Count()%3);
    
Please Sign in or register to post replies

Write your reply to:

Draft