Reload "Content" or "CurrentForm" after Custom GridField Row Action

I was wondering whether there is a possibility to reload “Content” or “CurrentForm” instead of “CurrentField” (in PJAX terms) when executing a Custom GridField Row Action?

To illustrate the situation a little bit further I have marked the hosting ItemEditForm of my DataObject green and the hosted GridField (with the Custom Row Actions) red.

I followed the official tutorial for creating the Custom GridField Row Action.

When I execute the action, an async request is being sent to the GridField (which we know is just a “fancy” type of RequestHandler) with the header X-Pjax: CurrentField. The re-rendered version of the GridField is being returned.

I was playing around with the X-Pjax header as per documentation but regardless of the value, the only thing returned and reloaded was the GridField.

The thing is, I need the whole form to reload since the GridField Action causes a data state change of the hosting DataObject. I cannot expect my users to F5 the page :smirk:

Is there a best practice way of achieving this or do I have to have “fun” with Entwine?

I had a similar issue in my module cms-actions and the best i could find is to either reload nothing, just the field or the whole page. for actions that require a “page reload” I send a X-Reload header

Seems like a legit solution for your scenario. Unluckily it does not do the trick for me, since the hosting ItemEditForm still won’t re-render. Maybe because I am not dealing with GridDetailForm_ItemRequest but with GridField_ActionProvider. I did not find a way to overwrite X-Pjax: CurrentField so far.

I have a (somewhat hackish) workaround now: Adding the no-ajax CSS class to GridField_FormAction and 302-redirecting to the current ItemEditForm (which is simply a weird way of refreshing in this case).

public function getColumnContent($gridField, $record, $columnName) 
{
    if (!$record->canEdit()) {
        return;
    }

    $field = GridField_FormAction::create(
        $gridField,
        'CustomAction'.$record->ID,
        'Do Action',
        "docustomaction",
        ['RecordID' => $record->ID]
    )->addExtraClass('no-ajax'); // <--- Disables AJAX

    return $field->Field();
}

...

public function handleAction(GridField $gridField, $actionName, $arguments, $data)
{
    if ($actionName !== 'docustomaction') {
        return;
    }
    // perform your action here

    // Return to current form / refresh
    return Controller::curr()->redirect($this->myDataObject->getCMSEditLink());
}

(snippets partially taken from official docs)

Works but does not feel like best practice.