Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
GridField Detail form with relation ID populated
class GridFieldConfig_HasManyRelationEditor extends GridFieldConfig {
* @param int $itemsPerPage - How many items per page should show up
public function __construct($itemsPerPage=null) {
$this->addComponent(new GridFieldButtonRow('before'));
$this->addComponent(new GridFieldAddNewButton('buttons-before-left'));
$this->addComponent(new GridFieldAddExistingAutocompleter('buttons-before-left'));
$this->addComponent(new GridFieldToolbarHeader());
$this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader());
$this->addComponent(new GridFieldDataColumns());
$this->addComponent(new GridFieldEditButton());
$this->addComponent(new GridFieldDeleteAction());
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$detailForm = new GridFieldDetailForm();
class GridFieldDetailForm_HasManyItemRequest extends GridFieldDetailForm_ItemRequest {
* Builds an item edit form. The arguments to getCMSFields() are the popupController and
* popupFormName, however this is an experimental API and may change.
* @todo In the future, we will probably need to come up with a tigher object representing a partially
* complete controller with gaps for extra functionality. This, for example, would be a better way
* of letting Security/login put its log-in form inside a UI specified elsewhere.
* @return Form
function ItemEditForm() {
if (empty($this->record)) {
$controller = Controller::curr();
$noActionURL = $controller->removeAction($_REQUEST['url']);
$controller->getResponse()->removeHeader('Location'); //clear the existing redirect
return $controller->redirect($noActionURL, 302);
$actions = new FieldList();
if($this->record->ID !== 0) {
$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept'));
$actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))
}else{ // adding new record
//Change the Save label to 'Create'
$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Create', 'Create'))
->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'add'));
// Add a Cancel link which is a button-like link and link back to one level up.
$curmbs = $this->Breadcrumbs();
if($curmbs && $curmbs->count()>=2){
$one_level_up = $curmbs->offsetGet($curmbs->count()-2);
$text = "
<a class=\"crumb ss-ui-button ss-ui-action-destructive cms-panel-link ui-corner-all\" href=\"".$one_level_up->Link."\">
$actions->push(new LiteralField('cancelbutton', $text));
$fk = $this->gridField->getList()->foreignKey;
$this->record->$fk = $this->gridField->getList()->foreignID;
$form = new Form(
// TODO Coupling with CMS
$toplevelController = $this->getToplevelController();
if($toplevelController && $toplevelController instanceof LeftAndMain) {
// Always show with base template (full width, no other panels),
// regardless of overloaded CMS controller templates.
// TODO Allow customization, e.g. to display an edit form alongside a search form from the CMS controller
$form->addExtraClass('cms-content cms-edit-form center ss-tabset');
$form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
if($form->Fields()->hasTabset()) $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
if($toplevelController->hasMethod('Backlink')) {
$form->Backlink = $toplevelController->Backlink();
} elseif($this->popupController->hasMethod('Breadcrumbs')) {
$parents = $this->popupController->Breadcrumbs(false)->items;
$form->Backlink = array_pop($parents)->Link;
} else {
$form->Backlink = $toplevelController->Link();
$cb = $this->component->getItemEditFormCallback();
if($cb) $cb($form, $this);
return $form;
Copy link

frankmullenger commented Sep 13, 2012

Only difference with GridFieldDetailForm_ItemRequest ( is that foreign key is set on record lines 45 and 46, record is always loaded into the form line 55.

This has added benefit that foreign key is available in getCMSFields() and record $defaults are set to the form first time.

Copy link

dospuntocero commented Sep 15, 2012

frank, do you know if this will appear in some silverstripe patch soon?

Copy link

frankmullenger commented Oct 10, 2012

I don't believe it will become part of core..

Copy link

dospuntocero commented Nov 16, 2012


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment