From fc773c5c2229f8915010dc1446af9610205326ac Mon Sep 17 00:00:00 2001 From: Andrew Short Date: Wed, 13 Nov 2013 16:21:18 +1100 Subject: [PATCH] NEW: Pre-populate and disable foreign key field on has many lists. This is a common use case, and by default a form field is added which has no effect. While this coupling is undesirable, it makes the default behaviour much more sensible. See #2662, #2651, #2637 for more information. --- forms/gridfield/GridFieldDetailForm.php | 18 +++++++++++++ .../gridfield/GridFieldDetailFormTest.php | 25 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/forms/gridfield/GridFieldDetailForm.php b/forms/gridfield/GridFieldDetailForm.php index 1e0b3e37f..108af996d 100644 --- a/forms/gridfield/GridFieldDetailForm.php +++ b/forms/gridfield/GridFieldDetailForm.php @@ -372,8 +372,26 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler { $actions->push(new LiteralField('cancelbutton', $text)); } } + $fields = $this->component->getFields(); if(!$fields) $fields = $this->record->getCMSFields(); + + // If we are creating a new record in a has-many list, then + // pre-populate the record's foreign key. Also disable the form field as + // it has no effect. + if($list instanceof HasManyList) { + $key = $list->getForeignKey(); + $id = $list->getForeignID(); + + if(!$this->record->isInDB()) { + $this->record->$key = $id; + } + + if($field = $fields->dataFieldByName($key)) { + $fields->makeFieldReadonly($field); + } + } + $form = new Form( $this, 'ItemEditForm', diff --git a/tests/forms/gridfield/GridFieldDetailFormTest.php b/tests/forms/gridfield/GridFieldDetailFormTest.php index ee729310d..881b13941 100644 --- a/tests/forms/gridfield/GridFieldDetailFormTest.php +++ b/tests/forms/gridfield/GridFieldDetailFormTest.php @@ -220,6 +220,31 @@ class GridFieldDetailFormTest extends FunctionalTest { $form = $request->ItemEditForm(); $this->assertNotNull($form->Fields()->fieldByName('Callback')); } + + /** + * Tests that a has-many detail form is pre-populated with the parent ID. + */ + public function testHasManyFormPrePopulated() { + $group = $this->objFromFixture( + 'GridFieldDetailFormTest_PeopleGroup', 'group' + ); + + $this->logInWithPermission('ADMIN'); + + $response = $this->get('GridFieldDetailFormTest_Controller'); + $parser = new CSSContentParser($response->getBody()); + $addLink = $parser->getBySelector('.ss-gridfield .new-link'); + $addLink = (string) $addLink[0]['href']; + + $response = $this->get($addLink); + $parser = new CSSContentParser($response->getBody()); + $title = $parser->getBySelector('#GroupID span'); + $id = $parser->getBySelector('#GroupID input'); + + $this->assertEquals($group->Name, (string) $title[0]); + $this->assertEquals($group->ID, (string) $id[0]['value']); + } + } class GridFieldDetailFormTest_Person extends DataObject implements TestOnly {