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.

Customising the CMS /

Finding the middle of a data set


Reply


5 Posts   953 Views

Avatar
misterac

Community Member, 7 Posts

4 April 2011 at 6:15pm

Hi community

I'm struggling with how to find the middle of a dataset for templating purposes. I'm rendering a series of data objects loaded through a has_many relation, and I want to split a column when I've passed the middle of the set.

Since the templating language has basically no support for comparison or evaluation I've had to hack core by adding this to ViewableData:

public function PastMiddle() {
   return $this->MultipleOf(ceil($this->TotalItems() / 2)) && !$this->Last();
}

Needless to say this feels wholly inappropriate, but I can't seem to find another way - I've probably missed something obvious.

Does anybody have any suggestions for how this sort of problem might be solved?

Avatar
Carbon Crayon

Community Member, 598 Posts

4 April 2011 at 8:55pm

Hi Misterac,

I would do something similar but not in the core, add this to your Page_Controller, then call it from another function passing it a DataObjectSet:

function getMiddleItem($MyDOS)
{
   $Middle = ceil($MyDOS->TotalItems / 2);
   
   return $MyDOS->getRange($Middle,1);
}

Then you could have a function like this:

function getMiddleNewsItem($MyDOS)
{
   $Items = DataObject::get('NewsArticle');
   
   return $this->getMiddleItem($Items);
}

Not sure if that covers your use case?

Aram

www.SSbits.com - Your one stop SilverStripe learning resource.

Avatar
misterac

Community Member, 7 Posts

14 April 2011 at 4:04am

Hi Aram

Thank you for your suggestion. However, I just figured out what seems to be a pretty easy approach, and it allows me to check if a loop has passed the middle when dealing with any sort of DataObject.

I simply put the function into a class that extends DataObjectDecorator, and then I attached the Decorator to the DataObject class. It didn't work with attaching an extension to ViewableData, but attaching it to DataObject works just fine.

So, in closing, and if anyone should ever need something like this:

class AS_DataObject extends DataObjectDecorator {
   /**
    * Determines if the middle has been passed in a DataObjectSet.
    * @return Bool True if we've just passed the middle, false otherwise
    */
   public function PastMiddle() {
      return $this->owner->MultipleOf(ceil($this->owner->TotalItems() / 2)) && !$this->owner->Last();
   }
}

Avatar
misterac

Community Member, 7 Posts

14 April 2011 at 4:07am

To expand a bit on the above, the problem was that I for some reason thought the TotalItems(), Pos() etc methods were attached to DataObjectSet. Shows up they're available on any DataObject. That strikes me as a sort of structural oddity (after all, what would "TotalItems" refer to in the context of a single DataObject?), but it's extremely useful for a DataObject to be aware of its own position in a set.

Avatar
merrick_sd

Community Member, 97 Posts

6 December 2011 at 2:01am

I have a similar thing i want to know what every third item is. so i can add a class to that item in my template.

<li class="productItem third-$pos" means i have to add css for every 3 item.

I want a way to check. so i can do

<li class=" productItem third"

class CategoryPage_Controller extends Page_Controller
{

function ProductList() {
   if(!isset($_GET['start']) || !is_numeric($_GET['start']) || (int)$_GET['start'] < 1) $_GET['start'] = 0;
   $SQL_start = (int)$_GET['start'];
   $doSet = DataObject::get(
   $callerClass = "Product",
   //$filter = "Product.ID = CategoryPage_Products.ProductID",
   $filter ="`CatID` = '".$this->ID."'",
   $sort = "SortOrder ASC",
   $join = "",
   $limit = "{$SQL_start},6"
   );

return $doSet ? $doSet : false;
}

public function AreYouAThird() {

//somehow
return "third";
}

}// end controller

---template -->

<% control ProductList %>

<li class="productItem $AreYouAThird" > whatever

</li>

<% end_control %>