Skip to content

Commit

Permalink
add save all button
Browse files Browse the repository at this point in the history
  • Loading branch information
lekoala committed May 15, 2024
1 parent 8452231 commit f36477b
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 9 deletions.
7 changes: 7 additions & 0 deletions javascript/cms-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@
},
});

$("#Form_EditForm_action_gridfieldsaveall").entwine({
onclick: function (e) {
// .submit() does not work, but trigger("submit", [this]) works somehow...
this.parents("form").trigger("submit", [this]);
},
});

// Allow posting from CmsInlineFormAction
$("button.inline-action[data-action]").entwine({
onclick: function (e) {
Expand Down
14 changes: 10 additions & 4 deletions src/ActionsGridFieldItemRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
use ReflectionObject;
use SilverStripe\Admin\ModelAdmin;

/**
* Decorates GridDetailForm_ItemRequest to use new form actions and buttons.
Expand Down Expand Up @@ -94,7 +95,6 @@ protected function getAvailableActions($actions)
$list[] = $action->getName();
}
}

return $list;
}

Expand Down Expand Up @@ -241,7 +241,8 @@ public function updateFormActions($actions)
$request = $this->owner->getRequest();
$stateManager = $this->owner->getStateManager();
$gridField = $this->owner->getGridField();
$actions->push(new HiddenField($stateManager->getStateKey($gridField), null, $stateManager->getStateFromRequest($gridField, $request)));
$state = $stateManager->getStateFromRequest($gridField, $request);
$actions->push(new HiddenField($stateManager->getStateKey($gridField), null, $state));
}

// Add extension hook
Expand Down Expand Up @@ -592,8 +593,13 @@ protected function forwardActionToRecord($action, $data = [], $form = null)
} elseif (!empty($data['ClassName']) && !empty($data['ID'])) {
$record = DataObject::get_by_id($data['ClassName'], $data['ID']);
} elseif ($controller->hasMethod("getRecord")) {
//@phpstan-ignore-next-line
$record = $controller->getRecord();
// LeftAndMain requires an id
if ($controller instanceof LeftAndMain && !empty($data['ID'])) {
$record = $controller->getRecord($data['ID']);
} elseif ($controller instanceof ModelAdmin) {
// Otherwise fallback to singleton
$record = DataObject::singleton($controller->getModelClass());
}
}

if (!$record) {
Expand Down
16 changes: 16 additions & 0 deletions src/CustomGridField_FormAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,30 @@ class CustomGridField_FormAction extends GridField_FormAction
{
use ProgressiveAction;

public bool $submitData = false;

/**
* @return string
*/
public function Type()
{
// if ($this->submitData) {
// return 'submit-action';
// }
if ($this->progressive) {
return 'progressive-action';
}
return 'action';
}

public function getAttributes()
{
$attrs = parent::getAttributes();

if ($this->submitData) {
$attrs['type'] = 'submit';
}

return $attrs;
}
}
97 changes: 97 additions & 0 deletions src/GridFieldSaveAllButton.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace LeKoala\CmsActions;

use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\ORM\DataObject;

/**
* When using inline editing on a ModelAdmin, there is no save button
* This allows saving the records
* It needs a custom endpoint because somehow, new records are not sent along
*/
class GridFieldSaveAllButton extends GridFieldTableButton
{
protected $fontIcon = 'save';
public bool $submitData = true;
/**
* @var boolean
*/
protected $noAjax = false;
protected ?string $completeMessage = null;

public function __construct($targetFragment = 'buttons-before-left', $buttonLabel = null)
{
parent::__construct($targetFragment, $buttonLabel);
$this->buttonLabel = $buttonLabel ?? _t('GridFieldSaveAllButton.SaveAll', 'Save all');
}

public function handle(GridField $gridField, Controller $controller, $arguments = [], $data = [])
{
$fieldName = $gridField->getName();
$list = $gridField->getList();
$model = $gridField->getModelClass();

// Without this, handleSave does not work
$gridField->setSubmittedValue($data[$fieldName]);

$updatedData = $data[$fieldName]['GridFieldEditableColumns'] ?? [];
foreach ($updatedData as $id => $values) {
/** @var DataObject $record */
$record = $list->byID($id);
if (!$record) {
continue;
}
$component = $gridField->getConfig()->getComponentByType(\Symbiote\GridFieldExtensions\GridFieldEditableColumns::class);
$component->handleSave($gridField, $record);
// foreach ($values as $k => $v) {
// $record->$k = $v;
// }
// $record->write();
}
$newData = $data[$fieldName]['GridFieldAddNewInlineButton'] ?? [];
foreach ($newData as $idx => $values) {
$record = new $model;
foreach ($values as $k => $v) {
$record->$k = $v;
}
$record->write();
}

$response = $controller->getResponse();

if (Director::is_ajax()) {
if (!$this->completeMessage) {
$this->completeMessage = _t('GridFieldSaveAllButton.DONE', 'ALL SAVED!');
}
// Reload for now since we mess up with the PJAX fragment
$url = $controller->getReferer();
$response->addHeader('X-ControllerURL', $url);
$response->addHeader('X-Reload', true);
$response->addHeader('X-Status', rawurlencode($this->completeMessage));
} else {
return $controller->redirectBack();
}
}

/**
* Get the value of completeMessage
*/
public function getCompleteMessage(): string
{
return $this->completeMessage;
}

/**
* Set the value of completeMessage
*
* @param string $completeMessage
*/
public function setCompleteMessage($completeMessage): self
{
$this->completeMessage = $completeMessage;
return $this;
}
}
24 changes: 19 additions & 5 deletions src/GridFieldTableButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use SilverStripe\Forms\GridField\GridField_ActionProvider;
use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridField_URLHandler;
use SilverStripe\Core\Injector\Injectable;

/**
* Provide a simple way to declare buttons that affects a whole GridField
Expand All @@ -18,6 +19,7 @@
abstract class GridFieldTableButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler
{
use ProgressiveAction;
use Injectable;

/**
* Fragment to write the button to
Expand Down Expand Up @@ -70,6 +72,8 @@ abstract class GridFieldTableButton implements GridField_HTMLProvider, GridField
*/
protected $attributes = [];

public bool $submitData = false;

/**
* @param string $targetFragment The HTML fragment to write the button into
* @param string $buttonLabel
Expand All @@ -89,7 +93,7 @@ public function getActionName()
{
$class = (new ReflectionClass(get_called_class()))->getShortName();

// ! without lowercase, in does not work
// ! without lowercase, it does not work
return strtolower(str_replace('Button', '', $class));
}

Expand All @@ -116,6 +120,9 @@ public function getHTMLFragments($gridField)
$action,
[]
);
if ($this->submitData) {
$button->submitData = true;
}
$button->addExtraClass('btn btn-secondary action_' . $action);
if ($this->noAjax) {
$button->addExtraClass('no-ajax');
Expand Down Expand Up @@ -167,11 +174,12 @@ public function getAttribute($name)
}

/**
* @param $gridField
* @param GridField $gridField
* @return array<string>
*/
public function getActions($gridField)
{
// $gridField is not used but required by parent class
return [$this->getActionName()];
}

Expand All @@ -194,7 +202,8 @@ public function handleAction(GridField $gridField, $actionName, $arguments, $dat
}
}

$result = $this->handle($gridField, $controller);
// Data should contain $_POST vars
$result = $this->handle($gridField, $controller, $arguments, $data);
if ((!$result || is_string($result)) && $this->progressive) {
// simply increment counter and let's hope last action will return something
$step = (int)$controller->getRequest()->postVar("progress_step");
Expand Down Expand Up @@ -232,9 +241,11 @@ public function handleAction(GridField $gridField, $actionName, $arguments, $dat
} else {
$response = $controller->getResponse();
$response->setBody($gridField->forTemplate());
$response
->addHeader('X-Status', 'Action completed');

// Add default message if none set
if (!$response->getHeader('X-Status')) {
$response->addHeader('X-Status', 'Action completed');
}
return $response;
}
}
Expand All @@ -250,8 +261,11 @@ public function getURLHandlers($gridField)
}

/**
* TODO: update the actual method with the new arguments
* @param GridField $gridField
* @param Controller $controller
* @param array<mixed> $arguments
* @param array<mixed> $data
* @return mixed
*/
abstract public function handle(GridField $gridField, Controller $controller);
Expand Down

0 comments on commit f36477b

Please sign in to comment.