greg_808
  1. public function getEditForm($id = null, $fields = null): Form
  2. {
  3. $form = parent::getEditForm($id, $fields);
  4. $gridField = $form->Fields()->fieldByName($this->getGridFieldName());
  5. if (class_exists(GridFieldCalculateOrder::class) && $this->getGridFieldName()) {
  6. $gridField = $form->Fields()->fieldByName($this->getGridFieldName());
  7. $gridField->getConfig()
  8. ->addComponent(new GridFieldCalculateOrder());
  9. }
  10. return $form;
  11. }

this is how i add it to the gridfield

greg_808

How would i add a custom gridfield action to the GridField action menu I used this Basic GridFieldCustomAction boilerplate implementing GridField_ActionMenuItem from the docs. When i add them to the girdfield in model admin i get this

jkersu

I think your custom action needs to implement GridField_ColumnProvider and GridField_ActionProvider

jkersu
  1. Have a class similar to the following:
    1. class CustomGridFieldAction implements GridField_ColumnProvider, GridField_ActionProvider
    2. {
    3. public function augmentColumns($gridField, &$columns)
    4. {
    5. if (!in_array('Actions', $columns)) {
    6. $columns[] = 'Actions';
    7. }
    8. }
    9.  
    10. public function getColumnAttributes($gridField, $record, $columnName)
    11. {
    12. return ['class' => 'grid-field__col-compact'];
    13. }
    14.  
    15. public function getColumnMetadata($gridField, $columnName)
    16. {
    17. if ($columnName == 'Actions') {
    18. return ['title' => ''];
    19. }
    20. }
    21.  
    22. public function getColumnsHandled($gridField)
    23. {
    24. return ['Actions'];
    25. }
    26.  
    27. public function getColumnContent($gridField, $record, $columnName)
    28. {
    29. if (!$record->canEdit()) {
    30. return;
    31. }
    32.  
    33. $field = GridField_FormAction::create(
    34. $gridField,
    35. 'CustomAction' . $record->ID,
    36. 'Finish Order',
    37. "dofinishorder",
    38. ['RecordID' => $record->ID]
    39. );
    40.  
    41. return $field->Field();
    42. }
    43.  
    44. public function getActions($gridField)
    45. {
    46. return ['dofinishorder'];
    47. }
    48.  
    49. public function handleAction(GridField $gridField, $actionName, $arguments, $data)
    50. {
    51. if ($actionName == 'dofinishorder') {
    52. // do some stuff
    53. }
    54. }
jkersu

Then add it by:

  1. $config->addComponent(new CustomGridFieldAction());
jkersu

Do you have a getColumnAttributes function in your custom action class?

jkersu

Can you show me your custom class for the gridfield action?

greg_808
  1. class GridFieldCalculateOrder implements GridField_ColumnProvider, GridField_ActionMenuItem
  2. {
  3. public function getTitle($gridField, $record, $columnName)
  4. {
  5. return 'Finish Order';
  6. }
  7.  
  8. public function getCustomAction($gridField, $record)
  9. {
  10. if (!$record->canEdit()) {
  11. return;
  12. }
  13.  
  14. return GridField_FormAction::create(
  15. $gridField,
  16. 'FinishOrder' . $record->ID,
  17. 'Finish Order',
  18. 'finishorder',
  19. ['RecordID' => $record->ID]
  20. );
  21. }
  22.  
  23. /**
  24.   * @inheritDoc
  25.   */
  26. public function getExtraData($gridField, $record, $columnName)
  27. {
  28. $field = $this->getCustomAction($gridField, $record);
  29.  
  30. if (!$field) {
  31. return;
  32. }
  33.  
  34. return $field->getAttributes();
  35. }
  36.  
  37. /**
  38.   * @inheritDoc
  39.   */
  40. public function getGroup($gridField, $record, $columnName)
  41. {
  42. return GridField_ActionMenuItem::DEFAULT_GROUP;
  43. }
  44.  
  45. /**
  46.   * @inheritDoc
  47.   */
  48. public function getActions($gridField)
  49. {
  50. return ['finishorder'];
  51. }
  52.  
  53. /**
  54.   * @inheritDoc
  55.   */
  56. public function handleAction(GridField $gridField, $actionName, $arguments, $data)
  57. {
  58. if ($actionName !== 'finishorder') {
  59. return;
  60. }
  61.  
  62. if (array_key_exists('RecordID', $arguments)) {
  63. $OrderID = $arguments['RecordID'];
  64. }
  65.  
  66. if ($OrderID) {
  67. $currentOrder = BackendOrder::get()->byID($OrderID);
  68. $currentOrder->calculateOrder();
  69. $currentOrder->Placed = $this->getDateTimeKnow();
  70. $currentOrder->isFinished = true;
  71. try {
  72. $currentOrder->write();
  73. } catch (Exception $e) {
  74. return Controller::curr()->getResponse()->setStatusCode(
  75. '500',
  76. $e->getMessage()
  77. );
  78. }
  79.  
  80. Controller::curr()->getResponse()->setStatusCode(
  81. 200,
  82. 'Do Custom Action Done.'
  83. );
  84. }
  85.  
  86. }
  87.  
  88. /**
  89.   * @inheritDoc
  90.   */
  91. public function augmentColumns($gridField, &$columns)
  92. {
  93. if (!in_array('Actions', $columns)) {
  94. $columns[] = 'Actions';
  95. }
  96. }
  97.  
  98. /**
  99.   * @inheritDoc
  100.   */
  101. public function getColumnsHandled($gridField)
  102. {
  103. return ['Actions'];
  104. }
  105.  
  106. /**
  107.   * @inheritDoc
  108.   */
  109. public function getColumnContent($gridField, $record, $columnName)
  110. {
  111. $field = $this->getCustomAction($gridField, $record);
  112.  
  113. if (!$field) {
  114. return;
  115. }
  116.  
  117. return $field->Field();
  118. }
  119.  
  120. /**
  121.   * @inheritDoc
  122.   */
  123. public function getColumnAttributes($gridField, $record, $columnName)
  124. {
  125. return ['class' => 'grid-field__col-compact'];
  126. }
  127.  
  128. /**
  129.   * @inheritDoc
  130.   */
  131. public function getColumnMetadata($gridField, $columnName)
  132. {
  133. if ($columnName === 'Actions') {
  134. return ['title' => ''];
  135. }
  136. }
  137.  
  138. public function getDateTimeKnow()
  139. {
  140. $now = new DateTime();
  141. $now->setTimezone(new DateTimeZone('Europe/Vienna'));
  142. return $now->format('d.m.Y H:i:s');
  143. }
  144. }
greg_808

sorry but the real problem is that the action apers twice in the grid field.

jkersu

In your getCustomAction() try adding the following:

  1. public function getCustomAction($gridField, $record)
  2. {
  3. if (!$record->canEdit()) {
  4. return;
  5. }
  6. return GridField_FormAction::create(
  7. $gridField,
  8. 'FinishOrder' . $record->ID,
  9. 'Finish Order',
  10. 'finishorder',
  11. ['RecordID' => $record->ID]
  12. )
  13. ->addExtraClass(implode(' ', [
  14. 'btn',
  15. 'btn-secondary',
  16. 'action-menu--handled',
  17. ]))
  18. ;
  19. }
jkersu

I had the same issue earlier when I was first implementing it as well

jkersu

But I think adding the above should make it appear only in the menu like so:

greg_808

Maybe, i should make an PR for the docs to reflect that?

jkersu

literally was thinking of the same thing haha

jkersu

No worries, go ahead 🙂 I think you only need to add the following extra class actually:

  1. ->addExtraClass(
  2. 'action-menu--handled'
  3. );

Show less replies
Admonish

I was hoping that it could be done directly using the updateFormActions method

Admonish

https://github.com/silverstripe/silverstripe-admin/blob/553cffe5ddf5bfbf7ebbe0dd03e3afd423b4f6bf/templates/SilverStripe/Admin/Includes/LeftAndMain_ViewModeSelector.ss

Show 1 attachment(s)
templates/SilverStripe/Admin/Includes/LeftAndMain_ViewModeSelector.ss

<span id="$SelectID" class="preview-mode-selector preview-selector field dropdown">
    <select title="<%t SilverStripe\\Admin\\LeftAndMain_ViewModeSelector.ChangeViewMode 'Change view mode' %>" id="$SelectID-select" class="preview-dropdown dropdown form-group--no-label no-change-track" autocomplete="off" name="Action">

        <option data-icon="font-icon-columns" class="font-icon-columns icon-view first" value="split"><%t SilverStripe\\Admin\\LeftAndMain_ViewModeSelector.SplitView 'Split mode' %></option>
        <option data-icon="font-icon-eye" class="font-icon-eye icon-view" value="preview"><%t SilverStripe\\Admin\\LeftAndMain_ViewModeSelector.PreviewView 'Preview mode' %></option>
        <option data-icon="font-icon-edit-write" class="font-icon-edit-write icon-view last" value="content"><%t SilverStripe\\Admin\\LeftAndMain_ViewModeSelector.EditView 'Edit mode' %></option>
        <!-- Dual window not implemented yet -->
        <!--
            <option data-icon="icon-window" class="icon-window icon-view last" value="window"><%t SilverStripe\\Admin\\LeftAndMain_ViewModeSelector.DualWindowView 'Dual Window' %></option>
        -->
    </select>
</span>
Hide attachment content