PageRenderTime 43ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/docs/en/02_Developer_Guides/03_Forms/How_Tos/04_Create_a_GridField_ActionProvider.md

http://github.com/silverstripe/sapphire
Markdown | 286 lines | 224 code | 62 blank | 0 comment | 0 complexity | c2b5e781479549de2798ba1f5a4824d2 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, CC-BY-3.0, GPL-2.0, AGPL-1.0, LGPL-2.1
  1. ---
  2. title: Create a GridField action provider
  3. summary: Handle custom actions on your GridField
  4. ---
  5. # How to add a custom action to a GridField row
  6. You can add an action to the row(s) of a [GridField](/developer_guides/forms/field_types/gridfield), such as the built in edit or delete actions.
  7. In a [GridField](/developer_guides/forms/field_types/gridfield) instance each table row can have a
  8. number of actions located the end of the row.
  9. Each action is represented as a instance of a specific class
  10. (e.g [GridFieldEditButton](api:SilverStripe\Forms\GridField\GridFieldEditButton)) which has been added to the `GridFieldConfig`
  11. for that `GridField`
  12. As a developer, you can create your own custom actions to be located alongside
  13. the built in buttons.
  14. For example let's create a custom action on the GridField to allow the user to
  15. perform custom operations on a row:
  16. 1. Create a custom action
  17. 2. [Add your custom action to the current GridFieldConfig](#add-the-gridfieldcustomaction-to-the-current-gridfieldconfig)
  18. _To create a custom action follow the [Basic GridFieldCustomAction boilerplate](#basic-gridfieldcustomaction-boilerplate)
  19. below, and if you would like to create a custom action in the **GridField action menu** follow the
  20. [Basic GridFieldCustomAction boilerplate implementing GridField_ActionMenuItem](#basic-gridfieldcustomaction-boilerplate-implementing-gridfield_actionmenuitem)_
  21. ## Basic GridFieldCustomAction boilerplate
  22. A basic outline of our new `GridFieldCustomAction.php` will look like something
  23. below:
  24. ```php
  25. use SilverStripe\Forms\GridField\GridField_ColumnProvider;
  26. use SilverStripe\Forms\GridField\GridField_ActionProvider;
  27. use SilverStripe\Forms\GridField\GridField_FormAction;
  28. use SilverStripe\Forms\GridField\GridField;
  29. use SilverStripe\Control\Controller;
  30. class GridFieldCustomAction implements GridField_ColumnProvider, GridField_ActionProvider
  31. {
  32. public function augmentColumns($gridField, &$columns)
  33. {
  34. if (!in_array('Actions', $columns)) {
  35. $columns[] = 'Actions';
  36. }
  37. }
  38. public function getColumnAttributes($gridField, $record, $columnName)
  39. {
  40. return ['class' => 'grid-field__col-compact'];
  41. }
  42. public function getColumnMetadata($gridField, $columnName)
  43. {
  44. if ($columnName === 'Actions') {
  45. return ['title' => ''];
  46. }
  47. }
  48. public function getColumnsHandled($gridField)
  49. {
  50. return ['Actions'];
  51. }
  52. public function getColumnContent($gridField, $record, $columnName)
  53. {
  54. if (!$record->canEdit()) {
  55. return;
  56. }
  57. $field = GridField_FormAction::create(
  58. $gridField,
  59. 'CustomAction'.$record->ID,
  60. 'Do Action',
  61. "docustomaction",
  62. ['RecordID' => $record->ID]
  63. );
  64. return $field->Field();
  65. }
  66. public function getActions($gridField)
  67. {
  68. return ['docustomaction'];
  69. }
  70. public function handleAction(GridField $gridField, $actionName, $arguments, $data)
  71. {
  72. if ($actionName !== 'docustomaction') {
  73. return;
  74. }
  75. // perform your action here
  76. // output a success message to the user
  77. Controller::curr()->getResponse()->setStatusCode(
  78. 200,
  79. 'Do Custom Action Done.'
  80. );
  81. }
  82. }
  83. ```
  84. ## Add the GridFieldCustomAction to the current `GridFieldConfig`
  85. While we're working on the code, to add this new action to the `GridField`, add
  86. a new instance of the class to the [GridFieldConfig](api:SilverStripe\Forms\GridField\GridFieldConfig) object. The `GridField`
  87. [Reference](/developer_guides/forms/field_types/gridfield) documentation has more information about
  88. manipulating the `GridFieldConfig` instance if required.
  89. ```php
  90. // option 1: creating a new GridField with the CustomAction
  91. $config = GridFieldConfig::create();
  92. $config->addComponent(new GridFieldCustomAction());
  93. $gridField = new GridField('Teams', 'Teams', $this->Teams(), $config);
  94. // option 2: adding the CustomAction to an exisitng GridField
  95. $gridField->getConfig()->addComponent(new GridFieldCustomAction());
  96. ```
  97. For documentation on adding a Component to a `GridField` created by `ModelAdmin`
  98. please view the [GridField Customization](/developer_guides/forms/how_tos/create_a_gridfield_actionprovider) section.
  99. Now let's go back and dive through the `GridFieldCustomAction` class in more
  100. detail.
  101. First thing to note is that our new class implements two interfaces,
  102. [GridField_ColumnProvider](api:SilverStripe\Forms\GridField\GridField_ColumnProvider) and [GridField_ActionProvider](api:SilverStripe\Forms\GridField\GridField_ActionProvider).
  103. Each interface allows our class to define particular behaviors and is a core
  104. concept of the modular `GridFieldConfig` system.
  105. The `GridField_ColumnProvider` implementation tells SilverStripe that this class
  106. will provide the `GridField` with an additional column of information. By
  107. implementing this interface we're required to define several methods to explain
  108. where we want the column to exist and how we need it to be formatted. This is
  109. done via the following methods:
  110. * `augmentColumns`
  111. * `getColumnAttributes`
  112. * `getColumnMetadata`
  113. * `getColumnsHandled`
  114. * `getColumnContent`
  115. In this example, we simply add the new column to the existing `Actions` column
  116. located at the end of the table. Our `getColumnContent` implementation produces
  117. a custom button for the user to click on the page.
  118. The second interface we add is `GridField_ActionProvider`. This interface is
  119. used as we're providing a custom action for the user to take (`docustomaction`).
  120. This action is triggered when a user clicks on the button defined in
  121. `getColumnContent`. As with the `GridField_ColumnProvider` interface, by adding
  122. this interface we have to define two methods to describe the behavior of the
  123. action:
  124. * `getActions` returns an array of all the custom actions we want this class to
  125. handle (i.e `docustomaction`) .
  126. * `handleAction` method which will contain the logic for performing the
  127. specific action (e.g publishing the row to a thirdparty service).
  128. Inside `handleAction` we have access to the current GridField and GridField row
  129. through the `$arguments`. If your column provides more than one action (e.g two
  130. links) both actions will be handled through the one `handleAction` method. The
  131. called method is available as a parameter.
  132. To finish off our basic example, the `handleAction` method simply returns a
  133. message to the user interface indicating a successful message.
  134. ## Add the GridFieldCustomAction to the `GridField_ActionMenu`
  135. For an action to be included in the action menu dropdown, which appears on each row if `GridField_ActionMenu` is included in the `GridFieldConfig`, it must implement `GridField_ActionMenuItem` and relevant `get` functions to provide information to the frontend react action menu component.
  136. ## Basic GridFieldCustomAction boilerplate implementing GridField_ActionMenuItem
  137. ```php
  138. use SilverStripe\Forms\GridField\GridField_ColumnProvider;
  139. use SilverStripe\Forms\GridField\GridField_ActionProvider;
  140. use SilverStripe\Forms\GridField\GridField_ActionMenuItem;
  141. use SilverStripe\Forms\GridField\GridField_FormAction;
  142. use SilverStripe\Control\Controller;
  143. class GridFieldCustomAction implements GridField_ColumnProvider, GridField_ActionProvider, GridField_ActionMenuItem
  144. {
  145. public function getTitle($gridField, $record, $columnName)
  146. {
  147. return 'Custom action';
  148. }
  149. public function getCustomAction($gridField, $record)
  150. {
  151. if (!$record->canEdit()) {
  152. return;
  153. }
  154. return GridField_FormAction::create(
  155. $gridField,
  156. 'CustomAction'.$record->ID,
  157. 'Custom action',
  158. "docustomaction",
  159. ['RecordID' => $record->ID]
  160. )->addExtraClass(
  161. 'action-menu--handled'
  162. );
  163. }
  164. public function getExtraData($gridField, $record, $columnName)
  165. {
  166. $field = $this->getCustomAction($gridField, $record);
  167. if (!$field) {
  168. return;
  169. }
  170. return $field->getAttributes();
  171. }
  172. public function getGroup($gridField, $record, $columnName)
  173. {
  174. return GridField_ActionMenuItem::DEFAULT_GROUP;
  175. }
  176. public function augmentColumns($gridField, &$columns)
  177. {
  178. if (!in_array('Actions', $columns)) {
  179. $columns[] = 'Actions';
  180. }
  181. }
  182. public function getColumnAttributes($gridField, $record, $columnName)
  183. {
  184. return ['class' => 'grid-field__col-compact'];
  185. }
  186. public function getColumnMetadata($gridField, $columnName)
  187. {
  188. if ($columnName === 'Actions') {
  189. return ['title' => ''];
  190. }
  191. }
  192. public function getColumnsHandled($gridField)
  193. {
  194. return ['Actions'];
  195. }
  196. public function getColumnContent($gridField, $record, $columnName)
  197. {
  198. $field = $this->getCustomAction($gridField, $record);
  199. if (!$field) {
  200. return;
  201. }
  202. return $field->Field();
  203. }
  204. public function getActions($gridField)
  205. {
  206. return ['docustomaction'];
  207. }
  208. public function handleAction(GridField $gridField, $actionName, $arguments, $data)
  209. {
  210. if ($actionName !== 'docustomaction') {
  211. return;
  212. }
  213. // perform your action here
  214. // output a success message to the user
  215. Controller::curr()->getResponse()->setStatusCode(
  216. 200,
  217. 'Do Custom Action Done.'
  218. );
  219. }
  220. }
  221. ```
  222. ## Related
  223. * [GridField Reference](/developer_guides/forms/field_types/gridfield)
  224. * [ModelAdmin: A UI driven by GridField](/developer_guides/customising_the_admin_interface/modeladmin)