Skip to content
This repository

Add ability to add custom actions to GridField record #526

Closed
wants to merge 7 commits into from

7 participants

Morven Lewis-Everley Sam Minnée Don't Add Me To Your Organization a.k.a The Travis Bot Ingo Schommer Tim vikas srivastava
Morven Lewis-Everley

Mainly I see this as useful for ModelAdmin, but could be useful elsewhere as well.

Currently GridField only adds Create/Cancel or Save/Delete buttons when editing an object. The record controller now checks if the Model class provides a getCMSActions() method, and if so, uses that.

Also added some extra methods for Publishing and UnPublishing content.

Still rudimentary, but think it would be quite a useful feature.

added some commits June 13, 2012
Add check for getCMSActions() on record. If exists (and object in DB)…
… use that instead of default actions.

Add doPublish() method as well, to provide support for Versioned extension on DataObjects
002049a
Add basic unpublish support c43b854
Add form and data parameters to unpublish method aa7c663
Sam Minnée
Owner

There is too much use-case specific stuff and magic in this approach.

  • Don't rely on getCMSActions(), provide configuration options (constructor arguments or setters) in the Detail form object to specify buttons. It then might appropriate in ModelAdmin rather than GridField to interrogate the values in getCMSActions() and pass the resulting buttons to GridFieldDetailForm. Alternatively, GridFieldDetailForm could be designed so that it can be passed a callback to fetch actions, and this callback could be set to:

    $detailFormComponent->setActions(function($record) {
        return $record->getCMSActions();
    });
    
  • Don't hard-code the publish and unpublish action handlers into GridFieldDetailForm. There are a few ways you could do this:

    • Provide a configuration option that let you add more action handlers (perhaps as anonymous functions).
    • Provide an additional GridField component that provided the additional actions.
    • Create a subclass of GridFieldDetailForm specifically for versioned objects.

Once again, the ModelAdmin could be configured to interrogate the managed object to identify which actions were necessary.

and others added some commits June 23, 2012
Morven Lewis-Everley Merge upstream changes from 3.0.0-rc1 9c9898d
Merge commit '3.0.0' into MLE-3.0.0-ModelAdmin 7056681
Update gridfield to use Getters and Setters for form actions
Remove publish and unpublish methods, as these can be added via an extension or subclass
Add getters and setters that can be manipulated after creating a new GridFieldDetailFrom()
646fb99
Morven Lewis-Everley

Ok, I have done a lot of reverse engineering of GridField. Hopefully I am getting closer to your comments.

I have removed the Publish and UnPublish methods, and successfully SubClassed GridFieldDetailForm_ItemRequest, adding these methods to that.

I have also removed the getCMSActions check and instead added a getFormActions() and setFormActions() method to GridFieldDetailForm that is passed to GridFieldDetailForm_ItemRequest.

I haven't done anything with ModelAdmin however, so far I have managed to make use of these methods and subclasses in my ModelAdmin subclass (which is currently not ideal, as I have to copy the getEditForm() method from ModelAdmin intio my subclass.

Not sure if ModelAdmin should have some sort of setter to allow overwriting of these actions more easily?

Mo

Morven Lewis-Everley mlewis-everley closed this July 06, 2012
Morven Lewis-Everley

As far as I can tell, the cleanest way of using the setFormActions() method is to overwrite getEditForm() in your ModelAdmin subclass and add both the new actions and a new ItemRequest subclass (with methods called by your new actions).

So something like this:

function getEditForm($id = null, $fields = null) {
    $form = parent::getEditForm($id = null, $fields = null);    
    $listfield = $form->Fields()->fieldByName([MODELCLASS]);

    $listfield->getConfig()->getComponentByType('GridFieldDetailForm')
        ->setItemRequestClass('[CLASSNAME]_ItemRequest')
        ->setFormActions(singleton($this->modelClass)->getCMSActions());

    return $form;
}
Morven Lewis-Everley mlewis-everley reopened this July 06, 2012
Sam Minnée sminnee closed this August 16, 2012
Sam Minnée sminnee reopened this August 16, 2012
Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 4ac4b23 into 64357a4).

Morven Lewis-Everley

I am going to close this, as I have found that you can edit the Item Form actions in ModelAdmin quite easily by:

  1. Extending GridFieldDetailFrom_ItemRequest.
  2. Adding an ItemEditForm() method to your extension.
  3. Within ItemEditForm() call parent::ItemEditForm()->actions()
  4. Edit actions via the FieldList API.

Not really sure these changes need to be merged into core, so as I said am closing this request.

Morven Lewis-Everley mlewis-everley closed this September 28, 2012
Ingo Schommer
Owner

Thanks anyway, Morven :)

Sorry I didn't quite get it. What is the final general solution to this?
Thanks, xini

Tim

extend GridFieldDetailForm & GridFieldDetailForm_ItemRequest
eg.

class VersionedGridFieldDetailForm extends GridFieldDetailForm {    
}

class VersionedGridFieldDetailForm_ItemRequest extends GridFieldDetailForm_ItemRequest {
}

then in VersionedGridFieldDetailForm_ItemRequest

function ItemEditForm() {
        $form = parent::ItemEditForm();
        $actions = $this->record->getCMSActions();

        $form->setActions($actions);
        return $form;
}

or in my case

function ItemEditForm() {
        $form = parent::ItemEditForm();
        $actions = FieldList::create(...actions...);

        $form->setActions($actions);
        return $form;
}

Hope this helps.

Cheers

I got it working. Thanks!

vikas srivastava

I am having a problem with this method. My action buttons are only appearing in Model Admin but not in Relation Editor, So when I am editing my dataobject from Model Admin they are working fine, but I have a relation of this dataobject with HomePage and when I try to edit this from HomePage, buttons are not appearing.

http://www.sspaste.com/paste/show/518e3dc335c85 . (See first comment for relation between my DataObject and HomePage).

Thanks

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

Showing 7 unique commits by 2 authors.

Jun 13, 2012
Add check for getCMSActions() on record. If exists (and object in DB)…
… use that instead of default actions.

Add doPublish() method as well, to provide support for Versioned extension on DataObjects
002049a
Add basic unpublish support c43b854
Add form and data parameters to unpublish method aa7c663
Jun 23, 2012
Morven Lewis-Everley Merge upstream changes from 3.0.0-rc1 9c9898d
Jul 02, 2012
Merge commit '3.0.0' into MLE-3.0.0-ModelAdmin 7056681
Update gridfield to use Getters and Setters for form actions
Remove publish and unpublish methods, as these can be added via an extension or subclass
Add getters and setters that can be manipulated after creating a new GridFieldDetailFrom()
646fb99
Jul 06, 2012
Morven Lewis-Everley Fix bug causing form actions to be loaded on create forms 4ac4b23
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 62 additions and 5 deletions. Show diff stats Hide diff stats

  1. 67  forms/gridfield/GridFieldDetailForm.php
67  forms/gridfield/GridFieldDetailForm.php
@@ -27,6 +27,11 @@ class GridFieldDetailForm implements GridField_URLHandler {
27 27
 	 * @var Validator The form validator used for both add and edit fields.
28 28
 	 */
29 29
 	protected $validator;
  30
+        
  31
+        /**
  32
+         * @var FieldList
  33
+         */
  34
+        protected $formActions;
30 35
 
31 36
 	/**
32 37
 	 * @var String
@@ -57,6 +62,7 @@ function getURLHandlers($gridField) {
57 62
 	 */
58 63
 	public function __construct($name = 'DetailForm') {
59 64
 		$this->name = $name;
  65
+                $this->formActions = new FieldList();
60 66
 	}
61 67
 	
62 68
 	/**
@@ -78,10 +84,29 @@ public function handleItem($gridField, $request) {
78 84
 
79 85
 		$handler = Object::create($class, $gridField, $this, $record, $controller, $this->name);
80 86
 		$handler->setTemplate($this->template);
  87
+                $handler->setFormActions($this->getFormActions());
81 88
 
82 89
 		return $handler->handleRequest($request, DataModel::inst());
83 90
 	}
84 91
 
  92
+        /**
  93
+         * Set the actions to be used in ItemEditForm
  94
+         * 
  95
+         * @param FieldList $actions
  96
+         * @return FieldList 
  97
+         */
  98
+        function setFormActions(FieldList $actions) {
  99
+                $this->formActions = $actions;
  100
+                return $this;
  101
+        }
  102
+        
  103
+        /**
  104
+         * @return FieldList 
  105
+         */
  106
+        function getFormActions() {
  107
+                return $this->formActions;
  108
+        }
  109
+        
85 110
 	/**
86 111
 	 * @param String
87 112
 	 */
@@ -138,7 +163,7 @@ public function setItemRequestClass($class) {
138 163
 	/**
139 164
 	 * @return String
140 165
 	 */
141  
-	public function getItemRequestClass() {
  166
+	public function getItemRequestClass() {            
142 167
 		if($this->itemRequestClass) {
143 168
 			return $this->itemRequestClass;
144 169
 		} else if(ClassInfo::exists(get_class($this) . "_ItemRequest")) {
@@ -200,6 +225,12 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler {
200 225
 	 */
201 226
 	protected $template = 'GridFieldItemEditView';
202 227
 
  228
+        /**
  229
+         *
  230
+         * @var FieldList
  231
+         */
  232
+        protected $formActions;
  233
+        
203 234
 	static $url_handlers = array(
204 235
 		'$Action!' => '$Action',
205 236
 		'' => 'edit',
@@ -289,10 +320,18 @@ function ItemEditForm() {
289 320
 
290 321
 		$actions = new FieldList();
291 322
 		if($this->record->ID !== 0) {
292  
-			$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
293  
-				->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept'));
294  
-			$actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))
295  
-				->addExtraClass('ss-ui-action-destructive'));
  323
+                    // Add check to see if record is providing its own actions.
  324
+                    // If not, fall back to default.
  325
+                    // Currently custom methods for manipulating data need to be
  326
+                    // added to this class via Object::add_extension();
  327
+                    if(!$this->getFormActions()->exists()) {
  328
+                        $actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
  329
+                                ->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept'));
  330
+                        $actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))
  331
+                                ->addExtraClass('ss-ui-action-destructive'));
  332
+                    } else {
  333
+                        $actions->merge($this->getFormActions());
  334
+                    }
296 335
 		}else{ // adding new record
297 336
 			//Change the Save label to 'Create'
298 337
 			$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Create', 'Create'))
@@ -409,6 +448,24 @@ function doDelete($data, $form) {
409 448
 
410 449
 		return $controller->redirect($noActionURL, 302); //redirect back to admin section
411 450
 	}
  451
+        
  452
+        /**
  453
+         * Set the actions to be used in ItemEditForm
  454
+         * 
  455
+         * @param FieldList $actions
  456
+         * @return FieldList 
  457
+         */
  458
+        function setFormActions(FieldList $actions) {
  459
+                $this->formActions = $actions;
  460
+                return $this;
  461
+        }
  462
+        
  463
+        /**
  464
+         * @return FieldList 
  465
+         */
  466
+        function getFormActions() {
  467
+                return $this->formActions;
  468
+        }
412 469
 
413 470
 	/**
414 471
 	 * @param String
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.