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




Community Member, 4 Posts

29 December 2010 at 11:43pm

Edited: 29/12/2010 11:43pm

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