6

How to add Custom button and its functionality in Admin Silverstripe?

Please tell me solution.

Custom Button add only in one menu.

user3111011
  • 145
  • 1
  • 9
  • basically the print button in your screenshot is a good example: See https://github.com/silverstripe/silverstripe-framework/blob/6a45f4a1e125b1a75d042e59b38824b24fd3cd0f/forms/gridfield/GridFieldPrintButton.php – wmk Aug 21 '15 at 13:19
  • thanks for your reply. @wmk can you please tell me that i have to make New file or just have to edit same file to make New button.? – user3111011 Aug 24 '15 at 04:54

1 Answers1

7

Like @wmk mentioned in the comments, you can just take the framework code for GridFieldPrintButton as a base and go from there. SilverStripe also have a basic tutorial for creating a custom ActionProvider.

Rather than rehash the tutorial here, I will provide you a very basic custom action provider that you can copy and extend to do what you need. While you don't note the exact result you are wanting from the button, I will provide just a very generic class.

This code is a stripped down version of the GridFieldPrintButton that @wmk mentioned. It supports both the button itself invoking the custom code as well as the URL.

I've noted in the code a reference that I have kept to "grid-print-button", this is to make your button sit nicely next to the print rather than likely sitting on another line (as it did in my testing on an older 3.1 site I built).

class GridFieldCustomButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {

    protected $targetFragment;
    protected $someCustomConstructData;

    //TargetFragment is just for positioning control of the HTML fragment
    //SomeCustomConstructData is just an example of providing some default options into your butotn
    public function __construct($targetFragment = "after", $someCustomConstructData = null) {
        $this->targetFragment = $targetFragment;
        $this->someCustomConstructData = $someCustomConstructData;
    }

    //Generate the HTML fragment for the GridField
    public function getHTMLFragments($gridField) {
        $button = new GridField_FormAction(
            $gridField,
            'custom',
            'Custom Action',
            'custom',
            null
        );
        return array(
            //Note: "grid-print-button" is used here to match the styling of the buttons in ModelAdmin
            $this->targetFragment => '<p class="grid-print-button">' . $button->Field() . '</p>',
        );
    }

    public function getActions($gridField) {
        return array('myCustomAction');
    }

    public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
        if($actionName == 'myCustomAction') {
            return $this->handleMyCustomAction();
        }
    }

    //For accessing the custom action from the URL
    public function getURLHandlers($gridField) {
        return array(
            'myCustomAction' => 'handleMyCustomAction',
        );
    }

    //Handle the custom action, for both the action button and the URL
    public function handleMyCustomAction($gridField, $request = null) {
        //Do your stuff here!
    }
}

Continuing on from the discussion in the comments, you will need to modify your custom ModelAdmin to add new components to its GridField.

class MyCustomAdmin extends ModelAdmin
{
    private static $managed_models = array(
        'MyCustomObject' 
    );

    private static $url_segment = 'custom-admin';
    private static $menu_title = 'All Custom Objects';

    public function getEditForm($ID = null, $Fields = null)
    {
        $form = parent::getEditForm($ID, $Fields);
        $fields = $form->Fields();

        $gridField = $fields->fieldByName('MyCustomObject');
        $gridFieldConfig = $gridField->getConfig();
        $gridFieldConfig->addComponent(new GridFieldCustomButton());

        return $form;
    }
}

Specifically, the line $gridFieldConfig->addComponent(new GridFieldCustomButton()) does the work, taking your custom button as I have shown above and added it to the ModelAdmin. You can also specify where it should go in the GridField too by providing "buttons-before-left" as the first argument in the GridFieldCustomButton constructor.

eg. $gridFieldConfig->addComponent(new GridFieldCustomButton("buttons-before-left"))

More information regarding GridField fragments can be found in the SilverStripe developer documentation.

Turnerj
  • 4,258
  • 5
  • 35
  • 52
  • Thanks for your reply. But i asking same question the way i asking him as wynk can you please tell me that i have to make New file or just have to edit same file to make New button.? – user3111011 Aug 24 '15 at 05:00
  • 1
    you have to create a new file and name it like your php class (so the autoloader finds it) – wmk Aug 24 '15 at 05:54
  • I make a new button only in one Menu i.e shows only in Company see screenshot. And make a new file in gridfield folder? – user3111011 Aug 24 '15 at 06:17
  • This new file can exist anywhere, doesnt (and shouldnt exist in the Framework folder). To display for one ModelAdmin, you just need to add it as a component. I will add to my answer later with details. – Turnerj Aug 24 '15 at 11:55