Jump to:

3435 Posts in 1026 Topics by 866 members

Template Questions

SilverStripe Forums » Template Questions » Dividing menu items into groups

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1 2
Go to End
Author Topic: 3641 Views
  • sca123
    Avatar
    Community Member
    61 Posts

    Dividing menu items into groups Link to this post

    I need help splitting menu items up into four groups, so for example:

    If X is the number of menu items (we'll place a value of X as 20)
    So X / 4 (20/4) is 5
    and then every 5 menu items, close and open div (to split the menu on the front end)

    The problem comes when X is say 21, which would need to result in 6 menu items in the first column and 5 menu items in the remaining 3 columns.

    Hopes this makes sense. Thanks in advance for any help.

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Dividing menu items into groups Link to this post

    The "modulo" operator (%) will give you the remaining value when doing integer division. Example: 21 % 4 results in 1, since 1 will remain when 21 is divided by 4 (integer division). In your case, using modulo, you'll only get 4 different cases:
    Modulo returns 0: X can be divided by 4, no problems.
    Modulo returns 1: one item has to be added to the first row
    Modulo returns 2: one item has to be added to row 1 and 2
    Modulo returns 3: one item has to be added to rows 1 - 3

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Dividing menu items into groups Link to this post

    Just wanted to test this and wrote a function that does what you want:

    // place this in your Page_Controller
    public function GridMenu($level, $numLines){
       $items = $this->Menu($level);
       $numItems = $items->Count();
       $remaining = $numItems % $numLines;
       $itemsPerLine = floor($numItems / $numLines);
       $rows = array();
       $it = $items->getIterator();
       
       for($i = 0; $i < $numLines; ++$i){
          $row = new DataObjectSet();
          $t = $itemsPerLine + ($i < $remaining ? 1 : 0);
          for($k = 0; $k < $t; ++$k){
             $row->push($it->current(), $it->key());
             $it->next();
          }
          $rows[] = array('Row' => $row);
       }
       return new DataObjectSet($rows);
    }

    The method works in the same way as Menu(x), but takes two parameters GridMenu($level, $numLines) where $level is the menu level and $numLines is the amount of lines or rows to output.

    In the template you would use this like shown below:

    <% control GridMenu(1, 4) %>
       <div>
       <% control Row %>
          <span>$Title</span>
       <% end_control %>
       </div>
    <% end_control %>

    This would output your pages of level 1 and split them into 4 rows. As you can see there's an inner loop (<% control Row %>) that outputs the items of a row.

  • sca123
    Avatar
    Community Member
    61 Posts

    Re: Dividing menu items into groups Link to this post

    Thank you - this most definately looks like the control required. How would this be modified to include the control <% if ChildrenOf() %> as my first level menu is made up of fixed images so I would need to have this control to show the second level menu (in groups of 4) just for that parent.

    Thanks in advance

  • sca123
    Avatar
    Community Member
    61 Posts

    Re: Dividing menu items into groups Link to this post

    Also would $numlines not need to be dynamic in the template?

  • sca123
    Avatar
    Community Member
    61 Posts

    Re: Dividing menu items into groups Link to this post

    Just to help you help me a little more - here is the code that needs to be dynamically created for a level2 menu grouping:

    <div id="appdiv3" onmouseover="MM_showHideLayers('appdiv3','','show')" onmouseout="MM_showHideLayers('appdiv3','','hide')">
       <div class="god_div">
       <div class="red_drop_top"><img src="themes/blackcandy/images/festival_top_round.png" alt="empty"/></div>
    <div class="red_drop_down">
       <div class="red_info_link">
       <ul>
       <li><a href="#" id="act">About us</a></li>
    <li><a href="#">Camping Village</a></li>
    <li><a href="#">Car Parking</a></li>
    <li><a href="#">Charities</a></li>
    <li><a href="#">Directions</a></li>
    </ul>
    </div>

    <div class="red_info_link">
       <ul>
       <li><a href="#">Facebook</a></li>
    <li><a href="#">FAQ</a></li>
    <li><a href="#">Feedback Form</a></li>
    <li><a href="#">Hotels</a></li>
    <li><a href="#">Merchandise</a></li>
    </ul>
    </div>

    <div class="red_info_link">
       <ul>
       <li><a href="#">News</a></li>
    <li><a href="#">Shuttle Bus</a></li>
    <li><a href="#">Venue Map</a></li>
    <li><a href="#">What is 7s</a></li>
    <li><a href="#">World Tournaments</a></li>
    </ul>
    </div>

    <div class="red_info_link">
       <ul>
       <li><a href="#">2012 Olympics</a></li>
    <li><a href="#">Contact Us</a></li>
    </ul>
    </div>
    </div>
    <div class="red_drop_top"><img src="themes/blackcandy/images/festival_bottom_round.png" alt="empty"/></div>
    </div>
    </div>

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Dividing menu items into groups Link to this post

    Well. You could simply rewrite the code to use ChildrenOf instead of Menu.

    // remove this line:
    // $items = $this->Menu($level);
    // add this line:
    $items = $this->ChildrenOf($level);

    Then instead of calling GridMenu(1,4) you would use GridMenu(page-url, 4)

    Why does $numLines have to be dynamic? In your first post you wrote that you need 4 lines of items. I wrote it more generically to allow arbitrary number of lines using the second parameter.

  • sca123
    Avatar
    Community Member
    61 Posts

    Re: Dividing menu items into groups Link to this post

    They need to be in columns rather than rows.

    3641 Views
Page: 1 2
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.