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.

Data Model Questions

ComplexTableField inside a ComplexTableField




29 December 2010 at 11:43pm (Last edited: 29 December 2010 11:43pm), Community Member, 4 Posts

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