How to implement a writable modal popup in a Grafana dashboard without leaving the current dashboard?

Hi everyone,

I am developing a Grafana dashboard where users can click an icon to open a modal popup without leaving or closing the current dashboard.

The popup should contain an editable form with fields such as:

  • Issue Name

  • Action Taken

  • Resolved By

  • Remarks

  • Date & Time

  • Status

Users should be able to enter or update the information, click Save, and have the data written to a backend database . After saving, the popup should close, and the user should remain on the same dashboard while it continues displaying live data.

I have explored Business Forms and Business Charts, but I couldn’t find a way to display an editable form as a modal popup on top of the existing dashboard.

Has anyone implemented a similar solution in Grafana? If so, what is the recommended approach?

Thank you!

Hi @rohitrs9255 Welcome to the community
you can get close to this with the native Actions feature no paid plugin needed. working setup →

Table panel + Action column
Build a Table panel querying your data. Add a Field override on any column (status) → Cell type: Actions. This puts a button in that column on every row.


Configure the Action
On the Action, set →
Method: POST (use PUT if your Grafana version supports it — older versions only expose POST/GET)
URL: http://your-api/issues/${__data.fields["id"]} — the ${__data.fields[...]} variable pulls that row’s ID automatically
Headers: whatever auth your API needs (e.g. X-API-Key)
Body: JSON referencing your form fields with $ prefix, e.g. {"issueName": "$issueName", "status": "$status"}


Define the popup’s fields under Variables
Each row you add here (Key + Name + type) becomes an editable input in the popup this is what makes it a “form.” In Grafana the popup opens blank and the user re-enters the row’s values plus their change.

Result
Click the row’s action button → popup opens on top of the dashboard → fill fields → confirm → API call fires → popup closes → dashboard stays open and keeps refreshing live.

Backend: any REST endpoint that accepts the method/body you configured and writes to your DB. A minimal Express + Postgres example, if useful: POST/PUT /api/issues/:id updating a row, protected by a shared API key header.

Actions support text-type fields only, no dropdowns/validation, and no field prefill in most current versions. If you need richer forms, the Volkov Labs Business Forms panel supports that but it renders as a regular panel, not an overlay/modal.

Hi @rohitrs9255 just wanted to check if you got the solution . Happy to help further if you are facing any issues .

Hi @infofcc3,

Thanks for following up! I’m currently building a POC using Grafana’s TestData data source for simulation only, so I don’t have a database yet.

Could you please guide me on how to configure the native Actions feature using the Grafana TestData source? Is there a way to simulate the complete workflow without a backend database?

Thanks in advance!

Hi @rohitrs9255,

You can use the TestData data source to prototype the UI, but it can’t persist changes. It only generates mock data, so any Action you trigger won’t update the table itself.

If your goal is simply to understand how native Actions work, you can still build most of the workflow →

Create a Table panel using the TestData data source.
Add a field override to one column and set its Cell type to Actions.
Configure an Action with your variables (for example, issueName, actionTaken, resolvedBy, remarks, and status).
When you click the action button, Grafana will display the input dialog, allowing you to test the UI and variable substitution.



The only missing piece for persisting changes is the backend. Native Actions send an HTTP request → they don’t store data themselves. Without a REST endpoint, there’s nowhere for the submitted values to go, so the table won’t reflect any changes.

If you want to simulate the request flow without a database, you can point the Action at a simple mock HTTP endpoint (for example, a small Express server that just logs the request and returns 200 OK). Later, you can replace that mock endpoint with your real backend that writes to a database.

Hi @rohitrs9255 if you are having any problem
you can simulate this entire workflow with TestData, no real backend needed.

Simulate the table with TestData

Data source: TestData DB
Scenario: CSV Content
Paste in sample rows matching your schema:

id,issue_name,action_taken,resolved_by,remarks,date_time,status
1,Disk usage alert on node-3,,,,"2026-07-21 07:10:00",Open
2,API latency spike,,,,"2026-07-21 07:10:00",Open
3,Test issue,,,,"2026-07-21 07:12:00",Open

Add the Action column
Field override on status → Cell options → Cell type: Actions

Get a URL to catch the request
Since there’s no backend yet, use webhook.site → go there, it gives you a free unique URL instantly, no signup. Keep that tab open; it shows every request live.

Configure the Action

Method: POST
URL: your webhook.site URL (optionally append /${__data.fields["id"]})
Variables: define issueName, actionTaken, resolvedBy, remarks, status (Key + Name + type string) — these become the popup’s editable fields
Body:

json

{
  "issueName": "$issueName",
  "actionTaken": "$actionTaken",
  "resolvedBy": "$resolvedBy",
  "remarks": "$remarks",
  "status": "$status"
}


5. Test it
Click the row’s “Update Issue” button → modal opens → fill fields → confirm → check your webhook.site tab, you’ll see the POST land instantly with your JSON payload.

Since TestData is static, the table itself won’t visually update after saving → there’s nothing behind it to persist changes. Webhook.site just proves the full click → modal → API call sequence works. When you’re ready to go live, swap the webhook.site URL for your real backend endpoint nothing else changes.