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.

Data Model Questions /

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

Dynamically add custom field with setField() on DataList Items


Go to End


6 Posts   2296 Views

Avatar
Ironcheese

Community Member, 36 Posts

10 January 2015 at 12:11am

Hi everyone.

In Silverstripe 2.4 I would have done it like that:

$Records = DataObject::get("myRecords", .....);
foreach ($Records as $Record) {
      if (isset($someOtherData[$Record->ID])) {
         $Record->setField("Foo", $someOtherData[$Record->ID]);
      }
}

In the templates I could call it simply with "$Foo".
Due to the lazy loading this does not work anymore. How can I achieve something like that?

cheers.

Avatar
Mo

Community Member, 541 Posts

10 January 2015 at 3:27am

Hi Ironcheese

I guess it depends when you are loading your logic?

You could add a param called Foo to your model object and then inside the if statement use:

$Record->Foo = $someOtherData[$Record->ID];

I have done this a few times from my controller's action and it seems to provide the data to the template in the way you describe.

Cheers,

Mo

Avatar
Ironcheese

Community Member, 36 Posts

10 January 2015 at 5:17am

Edited: 10/01/2015 5:22am

Hi Mo,

I'm having a couple thousand DataObjects in my project. I query those from the Database by various filters.
The Query is passed into a Pagination List.

// Inside PageController, inside a pageAction Funktion like "index"
$Query = MyObject::get()->where($sqlQuery)->sort($Sort);

$PaginationStart = $this->request->getVar('start') ?: 0;
$Records = new PaginatedList($Query, $this->request);
$Records->setPageLength(100);

// Other Information is being pulled from Dropbox
// ....

// Your proposed solution does not work even setting the Variable to a simple string
 foreach ($Records as $Record) {
            $Record->DropboxImage = "FOOBAR"; // $DropboxImages[$Record->ID];
}

I even gave my DataObject:

    public $DropboxImage = NULL;

    public function setDropboxImage($image) {
        $this->DropboxImage = $image;
    }

    public function getDropboxImage() {
        return $this->DropboxImage;
    }

But in my template, when looping over the $Records, I wont get anything.
Do you have another idea? :)

Cheers and thanks

Avatar
mi32dogs

Community Member, 75 Posts

14 April 2015 at 9:51am

Hi Ironcheese,

have you found a solution for this? I'm looking for something similar

Avatar
Ironcheese

Community Member, 36 Posts

14 April 2015 at 7:43pm

Hi mi32dogs,

yes I did find a solution, although its more like a little work around. Since the lazy loading thingy you just can't add fields via "setField". You have to execute the query in order to get to the underlying objects.

What I did was the following:

Query my DataObjects:

$Query = $DataObject::get()->where($sqlQuery)->sort($Sort);
$PaginationStart = $this->request->getVar('start') ?: 0;
$Records = new PaginatedList($Query, $this->request);
$Records->setPageLength(100); // $Records now hold my DataObjects

I then build my Dropbox Images in a simple array. My DataObject has a public property "DropboxImage".

$MyDataObjects= new ArrayList();

        // Loop over $Record Query, this is where it actually gets executed...
        foreach ($Records as $Record) {
           if (isset($DropboxImages[$Record->LosID])) {
               $Record->DropboxImage = count($DropboxImages[$Record->LosID]);
           }
           $MyDataObjects->push($Record);
        }

Later on, I pushed in a array and let customize and renderWith do the rest.

$Data = array(
            'Records' => $Records,
            'MyDataObjects' => $MyDataObjects,
            'DropboxImages' => $DropboxImages,
           // ....
            'PaginationStart' => $PaginationStart
        );

        return $this->customise($Data)->renderWith(array('MyPage_index', 'Page'));

Hope that helps!
:)

Avatar
mi32dogs

Community Member, 75 Posts

16 April 2015 at 6:29am

Thanks Ironcheese, thats a great help and i go it working now