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 /

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

ComplexTableField inside a ComplexTableField

Go to End



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