Adding a button to the CMS in SilverStripe
Asked Answered
N

2

5

How do I add a button to the backend of the CMS that fires an action? I can display the button where I want using:

public function getCMSFields()
{
    $fields = parent::getCMSFields();

    $fields->addFieldsToTab("Root.ButtonTest", array(
            FormAction::create('doAction', 'Action button')
        )
    );

    return $fields;
}

public function doAction() 
{
   //Do something
}

However the button added does nothing when clicked.

I've seen one example of how to put a button on the main action bar (next to save/publish) but that's not what I'm trying to do.

Looking at the only page of documentation I can find, do I need to do something within:

public function getCMSActions()
{
    $actions = parent::getCMSActions();
    //Something here?
}

It isn't very clear how to create the action that the button calls.

Nuri answered 29/4, 2014 at 1:33 Comment(3)
what do you want the button to 'do'? would it be an option to render a checkbox and react to it in the 'onBeforeWrite' hook?Proterozoic
Not really, the button will be sending a request to a third party service, checking the response and displaying it to the user. Ideally without reloading the page. Might just be easier to use a bit of js on a blur event or something.Nuri
The document manager system module does this, but I don't really know enough about SS yet to reverse engineer how they have done it.Nuri
V
8

You'll have to extend/decorate LeftAndMain with your own extension and the action you want to call. Here's an example:

<?php
class MyExtension extends LeftAndMainExtension
{
    private static $allowed_actions = array(
        'doAction'  
    );

    public function doAction($data, $form){
        $className = $this->owner->stat('tree_class');
        $SQL_id = Convert::raw2sql($data['ID']);

        $record = DataObject::get_by_id($className, $SQL_id);

        if(!$record || !$record->ID){
            throw new SS_HTTPResponse_Exception(
                "Bad record ID #" . (int)$data['ID'], 404);
        }

        // at this point you have a $record, 
        // which is your page you can work with!

        // this generates a message that will show up in the CMS
        $this->owner->response->addHeader(
            'X-Status',
            rawurlencode('Success message!') 
        );

        return $this->owner->getResponseNegotiator()
               ->respond($this->owner->request);
    }
}

Once you have written an extension like this, you'll have to apply it to LeftAndMain by adding the following to your mysite/_config/config.yml:

LeftAndMain:
  extensions:
    - MyExtension

That's it. Your doAction button should now actually do something!

Valued answered 17/9, 2014 at 6:41 Comment(2)
Makes perfect sense - Thanks!Nuri
doAction does not need to be in $allowed_actions, it is called from Form->httpSubmissionAgrology
A
2

Not sure if this is helpful, but here's how you can add action-buttons to a ModelAdmin.
(does reload the page)

...in the admin class:

public function getEditForm($id = null, $fields = null)
{
    $form = parent::getEditForm($id, $fields);
    $form
        ->Fields()
        ->fieldByName($this->sanitiseClassName($this->modelClass))
        ->getConfig()
        ->getComponentByType('GridFieldDetailForm')
        ->setItemRequestClass('MyGridFieldDetailForm_ItemRequest');

    return $form;
}

MyGridFieldDetailForm_ItemRequest.php

class MyGridFieldDetailForm_ItemRequest extends GridFieldDetailForm_ItemRequest
{
    function ItemEditForm()
    {
        $form = parent::ItemEditForm();
        $formActions = $form->Actions();

        $button = FormAction::create('myAction');
        $button->setTitle('button label');
        $button->addExtraClass('ss-ui-action-constructive');
        $formActions->push($button);


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

    public function myAction(){ //do things } 

}
Ardussi answered 1/5, 2014 at 9:10 Comment(2)
Thanks for taking the time to respond but it doesn't really give me a clear answer. Unfortunately this is all people seem to want to do and Google is covered in examples for this situation but not others.Nuri
if you mean the "Add Documents" button in the DMS module, you might want to take look at this: doc.silverstripe.org/framework/en/reference/… (i think that what it used there...)Ardussi

© 2022 - 2024 — McMap. All rights reserved.