Silverstripe 4-通过getCMSFields添加FormAction
目标: 我有一个叫做“事件”的数据对象。这是在“EventsAdmin”(扩展ModelAdmin)的托管_模型中。编辑事件时,我希望记录上有一个名为“审核”的选项卡,该选项卡有几个字段和两个按钮:“批准”和“拒绝”。这两个按钮分别调用执行相关操作的操作 事件扩展数据对象Silverstripe 4-通过getCMSFields添加FormAction,silverstripe,silverstripe-4,Silverstripe,Silverstripe 4,目标: 我有一个叫做“事件”的数据对象。这是在“EventsAdmin”(扩展ModelAdmin)的托管_模型中。编辑事件时,我希望记录上有一个名为“审核”的选项卡,该选项卡有几个字段和两个按钮:“批准”和“拒绝”。这两个按钮分别调用执行相关操作的操作 事件扩展数据对象 public function getCMSFields() { $fields = parent::getCMSFields(); $eventStatus = $fields->dataFieldB
public function getCMSFields() {
$fields = parent::getCMSFields();
$eventStatus = $fields->dataFieldByName("EventStatus")
->setTitle('Current Status')
->setDisabled(true);
$approveButton = FormAction::create('doApproveEvent', _t('SiteBlockAdmin.Approve', 'Approve'))
->setUseButtonTag(true)
->addExtraClass('btn-outline-success font-icon-check-mark-circle');
$rejectButton = FormAction::create('doRejectEvent', _t('SiteBlockAdmin.Reject', 'Reject'))
->setUseButtonTag(true)
->addExtraClass('btn-outline-danger font-icon-cancel-circled');
$fields->addFieldsToTab('Root.Moderation', [
$eventStatus,
$approveButton,
$rejectButton
]);
return $fields;
}
这显示的按钮很好。但他们什么也不做。因此,我试图找出它们如何插入到操作方法doApproveEvent和doRejectEvent中(以及它们应该放在哪里)
我确实找到了一些文档,这些文档引导我通过updateFormActions()将按钮添加到CMS页面底部的操作栏中。但这不是我想要的,因为我在按钮上方添加的其他字段是批准/拒绝流程的一部分。下面是此方法的代码。除非按钮不在我试图创建的流程的逻辑位置,否则这可以正常工作
class CMSActionButtonExtension extends DataExtension
{
public function updateFormActions(FieldList $actions)
{
$record = $this->owner->getRecord();
if (!$record instanceof Event || !$record->exists()) {
return;
}
$approveButton = FormAction::create('doApproveEvent', _t('SiteBlockAdmin.Approve', 'Approve'))
->setUseButtonTag(true)
->addExtraClass('btn-outline-success font-icon-check-mark-circle');
$rejectButton = FormAction::create('doRejectEvent', _t('SiteBlockAdmin.Reject', 'Reject'))
->setUseButtonTag(true)
->addExtraClass('btn-outline-danger font-icon-cancel-circled');
$actions->push($approveButton);
$actions->push($rejectButton);
}
public function doApproveEvent($data, $form) {
$record = $this->owner->getRecord();
// Approve logic
}
public function doRejectEvent($data, $form) {
$record = $this->owner->getRecord();
// Reject logic
}
}
上述扩展名附加到GridFieldDetailForm_ItemRequest
扩展名.yml
SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest:
extensions:
- My\Namespace\CMSActionButtonExtension
有趣的是,如果我在页面上同时有两组按钮,updateFormActions选项可以工作,而我想要的选项仍然不能工作。尽管按钮具有相同的标记,并且位于完全相同的表单标记中。我假设这与Silverstripe如何加载主内容面板和DOM有关
有没有想过要达到这个目标?有人看到我可以查看的模块中添加到CMS主面板的按钮吗?我找到了5年前的帖子,但它是针对SS3的,答案对我不适用。简短回答:
您必须通过控制表单(或表单本身)的控制器上的扩展添加自定义表单 长答案: 关于SilverStripe是如何生成表单的一些背景信息: 一般来说,表单总是通过控制器/请求处理程序提供(它们需要在某些路由上可访问,通常这是控制器上的一个操作,通常命名为Form、EditForm、ItemEditoForm等等)
在CMS内部,您很少需要创建自己的表单,这是由CMS为管理区域内置的控制器/请求处理程序完成的(
GridFieldDetailForm\u ItemRequest
)
基本上(此处为伪代码),这些控制器所做的是:
public function EditForm() {
$fields = $myCurrentlyEditingDataObject->getCMSFields();
$actions = ...;
$validator = ...;
$this->updateFormActions(&$actions);
$form = new Form('ItemRequestForm', $fields, $actions, $validator);
$this->updateItemEditForm(&$form); // or $this->updateEditForm()
return $form;
}
因此,getCMSFields()
以及在某些情况下getCMSActions()
/getCMSValidator()
(不确定这两个字段是否仍在SilverStripe 4.x中使用),您可以向表单添加内容,而不必查看表单对象
同样,“代码”> GETCMsFieldSDS()/Case>将始终放入窗体的“``”部分,这就是为什么您的按钮位于中间的所有字段而不是其他动作。
提交表单时(例如提交到
/admin/pages/edit/EditForm/265/field/NameOfMyGridField/item/542/ItemEditForm
),它将调用操作GridFieldDetailForm\u ItemRequest->ItemEditForm()
,该操作返回表单
对象,随后表单请求处理程序->httpSubmission()调用
。然后查看提交的数据,找出单击了什么操作(例如$\u REQUEST['action\u doapprovevent']
),并尝试查找该操作。它试图找到它的方法是检查它本身是否有一个名为
doapprovevent
的方法,如果失败,它将尝试Form->getController()->doapprovevent()
或类似的东西。在GridField
的情况下,该控制器是GridFieldDetailForm\u ItemRequest
,这意味着它将尝试调用GridFieldDetailForm\u ItemRequest->doApproveEvent()
因此,这意味着
DataObject->getCMSFields()
可以让您轻松地将FormFields(和FormActions)添加到表单体中。但它没有提供一种添加方法来处理提交的方法 这就是为什么,对于自定义操作,您需要修改控制器(
GridFieldDetailForm\u ItemRequest,在本例中为)。
为此,您可以创建一个扩展名
,并将其附加到GridFieldDetailForm\u ItemRequest
。
扩展中的任何方法都会添加到它所附加的对象中,因此如果添加一个名为updateFormActions
的方法,它将有点像GridFieldDetailForm\u ItemRequest->updateFormActions()
如果您回忆起前面的内容,则在创建表单期间,控制器将调用$this->updateFormActions()
。
此外,正如我前面所解释的,当一个FormAction被命名为doapprovevent
时,它将查找GridFieldDetailForm\u ItemRequest->doapprovevent()
,它现在存在,因为您通过该扩展添加了它
总之,您必须通过控制表单(或表单本身)的控制器上的扩展添加自定义表单
附言:来自中国的旧帖子
您链接到的bummzack在3.x中工作,因为他示例中创建表单的控制器是LeftAndMain
的一个实例,我假设CMSActionButtonExtension连接到表单或gridfield组件?您还可以包括用于该操作的config.yml吗please@Zauberfisch是的,没错。GridFieldDetailForm\u ItemR确切地说,我已经用配置更新了我的帖子。