Jump to:

23575 Posts in 19403 Topics by 2893 members

General Questions

SilverStripe Forums » General Questions » Change an object property from the controller

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

Page: 1 2
Go to End
Author Topic: 1368 Views
  • mschiefmaker
    Avatar
    Community Member
    187 Posts

    Change an object property from the controller Link to this post

    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

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Change an object property from the controller Link to this post

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

  • mschiefmaker
    Avatar
    Community Member
    187 Posts

    Re: Change an object property from the controller Link to this post

    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

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Change an object property from the controller Link to this post

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

  • mschiefmaker
    Avatar
    Community Member
    187 Posts

    Re: Change an object property from the controller Link to this post

    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

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Change an object property from the controller Link to this post

    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?

  • mschiefmaker
    Avatar
    Community Member
    187 Posts

    Re: Change an object property from the controller Link to this post

    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

  • banal
    Avatar
    Community Member
    901 Posts

    Re: Change an object property from the controller Link to this post

    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.

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