justindantzer's avatar

Altering an action query

I'm running into a roadblock in trialing some resource list tooling. Looking into user-selectable fields, I came across this column-toggler package. While it does update the visible columns, it does not affect the result when using the ExportAsCsv action.

I've dug into the repo a bit to see how the resource query gets updated, which is apparently done by overriding the resourceRequestQueryString to include the column selection. Nifty.

const originalResourceRequestQueryString = component.computed.resourceRequestQueryString

component.computed.resourceRequestQueryString = function () {
    return {
        ...originalResourceRequestQueryString.call(this),
        columnToggler: this.columnTogglerEncodedColumns,
    }
}

Naively thinking I could simply alter a similar property for an action, I played around with altering the actionQueryString seen in a few releavant Nova resource files -- js/mixins/IndexConcerns.js and js/views/Lens.vue -- but I was unsuccessful.

Initial attempt

const originalActionQueryString = component.computed.actionQueryString

component.computed.actionQueryString = function () {
    return {
        ...originalActionQueryString.call(this),
        columnToggler: this.columnTogglerEncodedColumns,
    }
}

I then came across the actionRequestQueryString in js/composables/useActions.js, referenced in the executeAction called in the js/components/ActionSelector.vue component.

I may have been staring at this too long, but this doesn't appear to be something I can simply override in the same way as the aforementioned request query. Are there any other tricks that wouldn't require completely overriding core Nova components?

OR perhaps there's a better Nova plugin that allows toggling columns in a similar way, that I haven't found yet.

0 likes
1 reply
LaryAI's avatar
Level 58

Certainly! The core of your issue is that while the column-toggler package updates the visible columns in the UI, it does not affect the data sent to actions like ExportAsCsv. This is because Nova actions (such as export) do not automatically receive the toggled columns as part of their request payload—they only get the selected resources.

Why your approach didn't work:
Overriding actionQueryString or similar computed properties on the client side does not affect how the backend action (like ExportAsCsv) determines which columns to include. The action only knows about the selected resources, not the UI state.

Solution: Pass Column Selection to the Action

You need to ensure that the selected columns are sent to the action request, and then update your export logic to use those columns.

1. Modify the Action Request to Include Selected Columns

You can do this by extending the action modal or selector to include the column toggler state in the payload. This might require a small Vue override or Nova field customization.

Example:

If you can hook into the action request, append the selected columns:

// Pseudo-code: in your Nova custom JS
Nova.$on('action-executing', (payload) => {
    payload.payload.columnToggler = window.columnTogglerEncodedColumns
})

Or, if you're customizing the action modal/component directly, ensure you add the column state to the action request body.

2. Update the Export Action to Use the Selected Columns

On the backend, update your ExportAsCsv action to check for the columnToggler parameter and use it to determine which columns to export.

public function handle(ActionFields $fields, Collection $models)
{
    $selectedColumns = json_decode(request('columnToggler'), true);

    // Fallback to default columns if none selected
    if (!$selectedColumns) {
        $selectedColumns = ['id', 'name', 'email']; // example defaults
    }

    // Build CSV using only selected columns
    $csv = '';
    $csv .= implode(',', $selectedColumns) . "\n";

    foreach ($models as $model) {
        $row = [];
        foreach ($selectedColumns as $column) {
            $row[] = $model->{$column};
        }
        $csv .= implode(',', $row) . "\n";
    }

    // Return CSV as download or however your action responds
    return Action::download($csv, 'export.csv');
}

3. Alternative: Use a Package That Supports This

As of now, there is no widely-used Nova package that tightly integrates column toggling with export actions out of the box. The approach above is the most direct way to bridge the gap.


Summary

  • Client-side: Ensure the selected columns are sent as part of the action request payload.
  • Server-side: Update your export action to use the columns from the request.

This approach avoids overriding core Nova components and keeps your customization minimal and maintainable.

If you need more specific code for Nova custom JS or action customization, let me know your Nova version and setup, and I can provide a more tailored example!

Please or to participate in this conversation.