Jump to:

3460 Posts in 1064 Topics by 739 members

Data Model Questions

SilverStripe Forums » Data Model Questions » ComplexTableField inside a ComplexTableField

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

Page: 1
Go to End
Author Topic: 768 Views
  • simonwade
    Community Member
    4 Posts

    ComplexTableField inside a ComplexTableField Link to this post

    I need to have the following scenario:

    Members have_many Pets
    Pets have a number of Treatments, which are common to all pets (ie. many_many relation)

    I have a ModelAdmin subclass (MyMemberAdmin) with $managed_models = array('Member', 'Treatment'). The Member class has a DataObjectDecorator that adds a ComplexTableField for managing Pets. Finally, the Pet model has a ManyManyComplexTableField that allows adding and removing Treatments.

    This all works fine, until the Pet form is submitted, and the selected Treatments are not stored. I think it's because the ManyManyComplexTableField isn't putting the correct hidden fields into the form because it thinks that the parentClass is "Member", not "Pet"

    If I change things around so that the ManyManyComplexTableField is not accessed through a popup then the problem doesn't occur.

    I've attached the code I'm using to this post. All you need to do to get this running is add "Object::add_extension('Member', 'MyMember');" to mysite/_config.php and run a dev/build. You can then go to "admin/members" and create a Treatment, then edit a Member, add a Pet and select the Treatment. When you click submit you'll see that the Treatments don't get stored.

    I would really appreciate some help with this. Also I think that this would be a very cool feature if it were possible to do this


    Object::add_extension('Member', 'MyMember');


    class MyMember extends DataObjectDecorator {

       function extraStatics() {
          return array(
             'has_many' => array(
                'Pets' => 'Pet'

       public function updateCMSFields(FieldSet $fields) {
          $owner = $this->getOwner();
          $pets = new ComplexTableField(
             $controller = $owner,
             $name = 'Pets',
             $sourceClass = 'Pet',
             $fieldList = array('Name' => 'Name', 'DateOfBirth' => 'DOB'),
             $detailFormFields = 'getCMSFields',
             $sourceFilter = "`OwnerID` = '{$owner->ID}'"
          $fields->addFieldToTab("Root.Pets", $pets);



    class MyMemberAdmin extends ModelAdmin {

       public static $managed_models = array(

       static $url_segment = 'members';
       static $menu_title = 'Members';

       function __construct() {
          $this->showImportForm = false;



    class Pet extends DataObject {

       public static $db = array(
          'Name' => 'Text',
          'DateOfBirth' => 'Date'

       public static $has_one = array(
           'Owner' => 'Member'

       public static $many_many = array(
          'Treatments' => 'Treatment'

       function getCMSFields() {
          $fields = parent::getCMSFields(array('include_relations' => false));
          $dateOfBirth = new DateField('DateOfBirth', 'Birth Date');
          $dateOfBirth->setConfig('showcalendar', true);
          $fields->addFieldsToTab('Root.Main', array(
             new TextField('Name'),
          $treatments = new ManyManyComplexTableField(
             $controller = $this,
             $name = 'Treatments',
             $sourceClass = 'Treatment',
             $fieldList = array('Name' => 'Name')
          $fields->addFieldsToTab('Root.Treatments', array(
          return $fields;



    class Treatment extends DataObject {

       public static $db = array(
          'Name' => 'Text'

       public static $many_many = array(
           'Pets' => 'Pet'

       function getCMSFields() {
          $fields = new FieldSet(
             new TextField('Name')
          return $fields;


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