You haven’t included all of the relevant code here and it’s not clear how /api/update_items
is routed… so I’ve given my hand at reproducing what your code might look like. I’ve got this ModelAdmin
:
<?php
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Security\Group;
class MyModelAdmin extends ModelAdmin
{
private static $managed_models = [
Group::class,
];
private static $allowed_actions = [
'update_items',
];
private static $url_segment = 'mangy-groups';
public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields);
// ...
$url = $this->Link(Controller::join_links($this->sanitiseClassName($this->getModelClass()), 'update_items'));
$field = LiteralField::create(
'Docblock',
'<div class="alert alert-info text-center mb-4">' .
'<p>Some description here.</p>' .
'<hr>' .
'<a href="'.$url.'" class="btn btn-primary btn-lg data-pjax="Content">Update items</a>' .
'</div>'
);
$form->Fields()->insertBefore('Gridfield', $field);
// ...
return $form;
}
public function update_items($request)
{
$response = $this->getResponse();
$response->addHeader('X-Status', 'Done!');
return $response;
}
}
This works - though it updates the location bar, which means that:
- The button only works once
- Refreshing the pages actually tries to load the action URL instead of the modeladmin itself
You probably should just add the action as an action. The simplest way being:
<?php
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Forms\FormAction;
use SilverStripe\Security\Group;
class MyModelAdmin extends ModelAdmin
{
private static $managed_models = [
Group::class,
];
private static $allowed_actions = [
'update_items',
];
private static $url_segment = 'mangy-groups';
public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields);
// ...
$action = FormAction::create('update_items', 'Update items')->addExtraClass('btn-primary btn-lg');
$form->Actions()->add($action);
// ...
return $form;
}
public function update_items($request)
{
$response = $this->getResponse();
$response->addHeader('X-Status', 'Done!');
return $response;
}
}
However I acknowledge that doesn’t give you the fancy background and description text, so you can do something like this for the best of both worlds:
<?php
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Security\Group;
class MyModelAdmin extends ModelAdmin
{
private static $managed_models = [
Group::class,
];
private static $allowed_actions = [
'update_items',
];
private static $url_segment = 'mangy-groups';
public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields);
// ...
$action = FormAction::create('update_items', 'Update items')->addExtraClass('btn-primary btn-lg');
$field = LiteralField::create(
'Docblock',
'<div class="btn-toolbar alert alert-info text-center mb-4">' .
'<p>Some description here.</p>' .
'<hr>' .
$action->FieldHolder() .
'</div>'
);
$form->Fields()->insertBefore('Gridfield', $field);
// ...
return $form;
}
public function update_items($request)
{
$response = $this->getResponse();
$response->addHeader('X-Status', 'Done!');
return $response;
}
}
Note that the btn-toolbar
css class is necessary for the button to actually do anything - but it also messes up the styling you had a little so you may need some custom css to tidy things up a bit.
Note also that there’s no field called Gridfield
currently, so the action is rendered at the bottom of the modeladmin. If you want it to be above the default gridfield, you can use this:
$form->Fields()->insertBefore($this->sanitiseClassName($this->modelTab), $field);
About the pjax stuff
It’s not clear if you actually wanted to use pjax or not - you said “That action has just to trigger the execution of some PHP code and notify the results”, and depending on what you mean by “notify”, pjax may or may not be suitable.
If you just wanted a toast that says what happened, no pjax required! If you want some HTML content to be returned and injected into the DOM, then either pjax or some custom javascript will be necessary.
I’m happy to help give further guidance on how to use pjax for that if that’s what you want, but for now I’m assuming that when you said “notify” you meant you just meant you want some toast message.