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.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

Change an object property from the controller


Go to End
Reply


9 Posts   1470 Views

Avatar
mschiefmaker

Community Member, 187 Posts

22 September 2009 at 10:58pm

Edited: 22/09/2009 11:00pm

I orginally wanted to use $Top.squarecolor($ID) from a template to call a function that calculated what colour to use from the $ID but I understand this is not possible and that I should be 'pushing this into the model' Question is how.

I have added an additional coloumn to the model to hold the information
public static $db = array(
   "sqcolor" => "enum('yellow, orange, grey, blue','blue')",
)
and then added a function to the appropriate controller

   function Squares() {
    $SquaresDetails = DataObject::get("SquaresPage");
    foreach($SquaresDetails as $SquareDetail){
       if ($ID%4==1){
      $SquareDetail->sqcolor = "blue";}
      elseif ($ID%4==2){
      $SquareDetail->sqcolor = "yellow";}
      elseif ($ID%4==3){
      $SquareDetail->sqcolor = "orange";}
      else {$SquareDetail->sqcolor = "grey";}}

    return DataObject::get("SquaresPage");
   }

and then within the template I call that function

   <% control Squares %>
    <div class ="square $sqcolor">
       $Content
    </div>
   <% end_control %>

but the Squares function does not update the sqcolor field as I expected.

What am I doing wrong?

Thanks

MM

Avatar
banal

Community Member, 901 Posts

22 September 2009 at 11:43pm

Edited: 23/09/2009 12:05am

Setting the member to a value doesn't alter the value stored in the DB. And if you do another DataObject::get, you'll get the values from the DB which are not modified.

I wonder why you even need the sqcolor DB field, since apparently the value of sqcolor is being set at runtime, depending on the item ID (I wonder why you're using the ID here? You are aware, that the ID isn't necessarily contiguous?).

If you really want to use the ID to determine the color, you can stick with the DB field and write the color value in the onAfterWrite method. This will be sufficient, because the ID will never change and therefore the color will never change. Or you could simply create a method on the DataObject like this:

public function getSqColor(){
   switch($this->ID % 4){
      case 1: return 'blue';
      case 2: return 'yellow';
      case 3: return 'orange';
      case 0: return 'grey';
   }
}

This will render the sqcolor field of the table obsolete.

If you want to change the color according to the position in the DataObjectSet (eg. color sequence is always blue, yellow, orange, grey), then you must first get the DataObjectSet, augment it and return the augmented set (not a new one like you did with return DataObject::get("SquaresPage"); )

Edit fixed code..

Avatar
mschiefmaker

Community Member, 187 Posts

23 September 2009 at 6:57am

Hi Banal

No I should not be testing the ID - I mistakenly thought it was going to give me sequential numbers.

I would prefer to use the runtime solution to me it makes more sense. This was where I started but on reading other threads I thought I couldn’t pass a variable to a function within a control. I am afraid I don’t know what you mean when you say “create the method on the dataobject” By this I assume you mean

class SquaresHolder extends Page {
   
   public static $db = array(
      
   );
   
   
public function getSqColor(){
switch($this->ID % 4){
case 1: return 'blue';
case 2: return 'yellow';
case 3: return 'orange';
case 0: return 'grey';
}
}

<% control Squares %>
         <div class ="square $Squares.SqColor">
            $Content
         </div>
      <% end_control %>
Returns nothing

Sorry, I know my I am asking simple questions. Can you tell me where this sort of thing if explained and I will go and work it out? Otherwise, ho should I be setting this up?

Thanks as always

MM

Avatar
banal

Community Member, 901 Posts

23 September 2009 at 7:42am

Well, yes the ID is usually sequential, but the sequence will be interrupted as soon as an entry in-between is being deleted. Obviously, that's a problem and therefore you can't use the ID to get the color. That's why you can't get the color from the DataObject itself, because it doesn't know which position it will have in the result DataSet. Or to put it otherwise: The color of the object depends on its position in a set and therefore changes with the amount of objects in the same set.

Luckily, you can get the current iterator position, when a DataObject is being iterated over.
Here's how you would do this:

// this method belongs to the Square DataObject,
// not the SquaresHolder
public function getSqColor(){
   switch($this->iteratorPos % 4){
      case 1: return 'blue';
      case 2: return 'yellow';
      case 3: return 'orange';
      case 0: return 'grey';
   }
}

Yeah, it looks like my previous function, but instead of the ID, we're using the current iterator position. The template part would look like this:

<% control Squares %>
   <div class ="square $SqColor">
      $Content
   </div>
<% end_control %>

Avatar
mschiefmaker

Community Member, 187 Posts

23 September 2009 at 7:31pm

Thanks Banal

I am afraid I am going to have to keep asking simple questions. I just can’t get clear about how I append this result to the dataobject and its limiting everything I do.

When you say “this method belongs to the Square DataObject” I added it to

class Square extends DataObject {
       
      public function getSqColor(){
         switch($this->iteratorPos % 4){
         case 1: return 'blue';
         case 2: return 'yellow';
         case 3: return 'orange';
         case 0: return 'grey';
            }
   }
but I still get nothing returned, also changed Square to Squares but that didn't help. Am I putting this in the right place/way?

Thanks

MM

Avatar
banal

Community Member, 901 Posts

23 September 2009 at 9:00pm

I don't understand what you mean with: 'and its limiting everything I do'.
It's really simple actually, unless I completely misunderstood what you're trying to do. I did a quick try here, and it works fine...
Could you post the code of your classes/templates (the SquaresHolder.php, SquaresHolder.ss and the DataObject class) to a site like http://pastebin.com/ and then post the links here so that I can have a look at it?

Avatar
mschiefmaker

Community Member, 187 Posts

23 September 2009 at 9:13pm

Hi Banal

the limit everything I do comment was me having a bit of a rant. I have another couple of issues which I think will be solved using a function which gives me virtual additions to the the dataobject and I am frustrated by my own lack of knowledge. I appreciate your time.

I have pasted the code on at http://pastebin.com/m5d2e82db

thanks

MM

Avatar
banal

Community Member, 901 Posts

23 September 2009 at 9:34pm

Oh, ok, now I see the problem.
You have a SquaresHolder that holds SquaresPages. I thought the Squares where DataObjects, attached to the SquaresHolder (using a has_many relation).

This doesn't change much though, do the following:
1) Remove the Squares Class from the SquaresHolder.php
2) Add the getSqColor method to the SquarePage Class

It should work after these changes.

Go to Top