Jump to:

5540 Posts in 1738 Topics by 1224 members

Customising the CMS

SilverStripe Forums » Customising the CMS » Finding the middle of a data set

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

Page: 1
Go to End
Author Topic: 895 Views
  • misterac
    Avatar
    Community Member
    7 Posts

    Finding the middle of a data set Link to this post

    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?

  • Aram
    Avatar
    Community Member
    598 Posts

    Re: Finding the middle of a data set Link to this post

    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.

  • misterac
    Avatar
    Community Member
    7 Posts

    Re: Finding the middle of a data set Link to this post

    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();
       }
    }

  • misterac
    Avatar
    Community Member
    7 Posts

    Re: Finding the middle of a data set Link to this post

    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.

  • merrick_sd
    Avatar
    Community Member
    95 Posts

    Re: Finding the middle of a data set Link to this post

    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 %>

    895 Views
Page: 1
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.