Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Template Questions /

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

Is there a control to detect every nth list item


Go to End


23 Posts   11063 Views

Avatar
reekrd

Community Member, 9 Posts

26 June 2009 at 8:23pm

Aaah. I actually tried that. However I didn't make the function public....

As always. Thanks for your quick reply!

Cheers
.r

Avatar
MarcusDalgren

Community Member, 288 Posts

2 July 2009 at 4:31am

Hey Uncle Cheese.

I tried out your function but it doesn't work for me.
It returns 1 on the first iteration and then 0 for every other iteration.
I checked that iteratorPos was correct and it increments as one would expect.

If I remove the ! so the function reads return $this->iteratorPos % 3; then it returns 0, 1, 2 and then starts over.

Any idea about what could be wrong?

Avatar
UncleCheese

Forum Moderator, 4102 Posts

2 July 2009 at 4:39am

$this->iteratorPos % 3 will return 0 when 3 divides evenly into the value of iteratorPos, therefore, when that function returns false, or 0, you are on a Third increment of the loop, so that's why you need the !. You're looking for a false return.

Avatar
MarcusDalgren

Community Member, 288 Posts

2 July 2009 at 4:48am

Edited: 02/07/2009 4:55am

I get that but I wasn't getting anything else back every third iteration with your function.

I tried
public function Third()
{
return !$this->iteratorPos % 3;
}

And it fired on the first iteration but never again. I rewrote it a bit and got it to work the way I wanted it to but the shortness of your function is very appealing. I had to write it like this

	public function Nth($val)
	{
		//if ($this->iteratorPos != 0)
	    if(!($this->iteratorPos%$val)) {
	        return true;
	    }
		else {
			return false;		
		}
	} 

but that works and I can pass in any number I want instead of having it locked on one. This should open alot of doors when it comes to making more complicated markup or doing rows :D.

Also one should really add ($this->iteratorPos+1)%$val) if you want it to correspond to the nth item since iteratorPos starts at 0. If someone wants to do something with the first item $First is already available.

Avatar
NickJacobs

Community Member, 148 Posts

2 July 2009 at 10:49am

Hi, worked my way through some of those examples and couldn't any working as I needed, so thought I'd post my final solution (based on those above)...it might be useful to someone :)

What I needed to do was break nav menus if they were more than 5 list items, as in the image

so, in my Page class:

public function SplitList($val=5) { 
      return ($this->iteratorPos + 1) % $val == 0; 
   } 

and in the template (navigation include)


 <ul class="navlist">
 	<% control Menu(4) %>
    	  
  		<li class="$LinkingMode"><a href="$Link" title="Go to the $Title.XML page" class="$LinkingMode">$MenuTitle.XML</a></li>
        
      	<% if SplitList(5) %> 
		</ul><ul class="navlist">
        <% end_if %>
        
   	<% end_control %>
 </ul>
 

Avatar
DigoART

Community Member, 13 Posts

14 July 2009 at 11:39pm

Edited: 14/07/2009 11:42pm

Hi All,

Could you help me with my code, as it doesn't work for me. It works for basic controls, however With my custom control it won't do anything.

So I've got the Page class with Both custom control and Third() function to check for the number of element:

Page.php:

	
        function LatestCase($num=6) {
  	$news = DataObject::get_one("CaseStudyHolder");
  	return ($news) ? DataObject::get("CaseStudy", "ParentID = $news->ID", "Featured DESC, Date DESC", "", $num) : false;
	}

        ...

        public function Third()
	{
	return !$this->iteratorPos % 3;
	}

Then I've got a CaseStudyHolder class as well as CaseStudy class, both extend Page class

In the CaseStudyHolder.ss I call a LatestCase(12) from Page Class, and need to get Nth elements inside this control.

So,

CaseStudyHolder.ss:

...

 <% control LatestCase(12) %>
      <div class="CaseBox">

         $Photo.SetSizeFixed(130x95)

         <div class="infoFrame">         
             <% if Third %> $Title.XML <% end_if %>
         </div>
      
       </div>
      
     
      <% end_control %>

However - it doesn't return anything at all, so basically the Title is not displayed :(

Hopefully UncleCheese could help me solving this problem, as no one on the IRC couldn't .

Cheers.

PS: This is just an example, in real app Title would be on every item, however after each 3rd item there should be
<div class="CleanAll">&nbps</div>

Avatar
socks

Community Member, 191 Posts

3 January 2011 at 8:17pm

Edited: 03/01/2011 8:19pm

There's an easy way now in 2.4… MultipleOf() : http://doc.silverstripe.org/templates

<ul>
	<% if MultipleOf(4) %>
	        <li class="fourth">bla</li>
	<% else %>
		<li>bla</li>
	<% end_if %>
</ul>

Go to Top