Write a row in PostgreSQL with Business Forms Plugin

Hello
I am trying to write a row in my postgreSQL database from Grafana with “business forms plugin” but there is no simple example explained

  • What Grafana version and what operating system are you using? 10 / 11

  • What are you trying to achieve? I want to write a row in PostGreSQL from grafana

  • How are you trying to achieve it? With the business forms plugin, I want to declare :

  • The line
  • The start Time
  • The end time
  • the status of the line for this time (open/close/maintenance…)
    and write them in my PostgreSQL database

Problem
It is not writing in the SQL database the 4/5 parameters I wanted

  • Can you copy/paste the configuration(s) that you are having problems with?
  • my json panel code :
{
  "datasource": {
    "type": "grafana-postgresql-datasource",
    "uid": "ddonkd2fx7h8ga"
  },
  "gridPos": {
    "h": 8,
    "w": 12,
    "x": 12,
    "y": 8
  },
  "id": 7,
  "options": {
    "layout": {
      "variant": "single",
      "padding": 10,
      "orientation": "horizontal",
      "sectionVariant": "default"
    },
    "elementValueChanged": "let elements = context.panel.elements;\r\n\r\n// Trouver les éléments 'Debut' et 'Fin'\r\nconst Debut = context.panel.elements.find(\r\n  (element) => element.id === \"Start\"\r\n);\r\nconst Fin = context.panel.elements.find(\r\n  (element) => element.id === \"End\"\r\n);\r\n//const Ligne = context.panel.elements.find(\r\n//  (element) => element.id === \"Line\"\r\n//);\r\n// Vérifiez si 'Debut' et 'Fin' ont des valeurs\r\nconst isFormValid = Debut && Debut.value && Fin && Fin.value;\r\n\r\n// Activer ou désactiver le bouton de soumission en fonction de la validité du formulaire\r\nif (isFormValid) {\r\n  context.panel.enableSubmit();\r\n} else {\r\n  context.panel.disableSubmit();\r\n}\r\n",
    "sync": true,
    "initial": {
      "method": "datasource",
      "contentType": "application/json",
      "code": "console.log(context.panel.data, context.panel.response, context.panel.initial, context.panel.elements);\n\nreturn;\n\n/**\n * Data Source\n * Requires form elements to be defined\n */\nconst dataQuery = context.utils.toDataQueryResponse(context.panel.response);\nconsole.log(dataQuery);",
      "getPayload": "return {}",
      "payload": {},
      "highlight": false,
      "highlightColor": "red",
      "datasource": "Postgresql"
    },
    "updateEnabled": "manual",
    "update": {
      "method": "datasource",
      "contentType": "application/json",
      "code": "if (context.panel.response) {\n  context.grafana.notifySuccess(['Update', 'Values updated successfully.']);\n  context.grafana.locationService.reload();\n} else {\n  context.grafana.notifyError(['Update', 'An error occurred updating values.']);\n}",
      "payloadMode": "custom",
      "getPayload": "const payload = {};\n\ncontext.panel.elements.forEach((element) => {\n  if (!element.value) {\n    return;\n  }\n\n  payload[element.id] = element.value;\n})\n\n// Créer la requête SQL brute en utilisant un template string\nconst sqlQuery = `\n    INSERT INTO \"DATA_SCHEMA\".\"LINE\" (\"id\", \"LINE\", \"start_time\", \"end_time\", \"planifie\")\n    VALUES ('${payload.id}', '${payload.Ligne}', '${payload.Start}', '${payload.End}', '${payload.planification}');\n`;\n\n// Retourner l'objet avec la requête SQL brute\nreturn { rawsql: sqlQuery };\n\n\n\n\n",
      "payload": {
        "editorMode": "code",
        "format": "table",
        "rawQuery": true,
        "rawSql": "INSERT INTO \"DATA_SCHEMA\".\"LINE\" (\"id\", \"LINE\", \"start_time\", \"end_time\", \"planifie\")\r\n    VALUES ('${payload.id}', '${payload.Ligne}', '${payload.Start}', '${payload.End}', '${payload.planification}');\r\n",
        "refId": "A",
        "sql": {
          "columns": [
            {
              "parameters": [],
              "type": "function"
            }
          ],
          "groupBy": [
            {
              "property": {
                "type": "string"
              },
              "type": "groupBy"
            }
          ],
          "limit": 50
        }
      },
      "confirm": true,
      "datasource": "Postgresql"
    },
    "confirmModal": {
      "title": "Confirm update request",
      "elementDisplayMode": "all",
      "body": "Confirmation",
      "columns": {
        "include": [
          "name",
          "oldValue",
          "newValue"
        ],
        "name": "Label",
        "oldValue": "Old Value",
        "newValue": "New Value"
      },
      "confirm": "Confirm",
      "cancel": "Cancel"
    },
    "buttonGroup": {
      "orientation": "center",
      "size": "md"
    },
    "submit": {
      "variant": "primary",
      "foregroundColor": "yellow",
      "backgroundColor": "purple",
      "icon": "cloud-upload",
      "text": "Submit"
    },
    "reset": {
      "variant": "hidden",
      "foregroundColor": "yellow",
      "backgroundColor": "purple",
      "icon": "process",
      "text": "Reset"
    },
    "resetAction": {
      "mode": "initial",
      "code": "if (context.panel.response) {\n  context.grafana.notifySuccess(['Update', 'Values updated successfully.']);\n  context.grafana.locationService.reload();\n} else {\n  context.grafana.notifyError(['Update', 'An error occurred updating values.']);\n}",
      "confirm": false,
      "getPayload": "return {}",
      "payload": {}
    },
    "saveDefault": {
      "variant": "hidden",
      "icon": "save",
      "text": "Save Default"
    },
    "elements": [
      {
        "id": "Line",
        "labelWidth": 10,
        "options": [
          {
            "id": "10",
            "label": "10",
            "type": "string",
            "value": "10"
          },
          {
            "id": "11",
            "label": "11",
            "type": "string",
            "value": "11"
          },
          {
            "id": "12",
            "label": "12",
            "type": "string",
            "value": "12"
          },
          {
            "id": "_",
            "label": "",
            "type": "string",
            "value": ""
          }
        ],
        "optionsSource": "Custom",
        "section": "",
        "title": "Line",
        "tooltip": "",
        "type": "select",
        "uid": "04570bb6-642b-4e00-aba2-45cc9235674a",
        "unit": "",
        "value": []
      },
      {
        "id": "Start",
        "isUseLocalTime": false,
        "labelWidth": 10,
        "section": "",
        "title": "Start",
        "tooltip": "",
        "type": "datetime",
        "uid": "9a3ef965-bb71-4d6d-8f7b-69100a2bed0e",
        "unit": "",
        "value": ""
      },
      {
        "id": "End",
        "isUseLocalTime": false,
        "labelWidth": 10,
        "section": "",
        "title": "End",
        "tooltip": "",
        "type": "datetime",
        "uid": "77cc154c-1dc2-46e4-a7de-ed0a36a91dcc",
        "unit": "",
        "value": ""
      },
      {
        "id": "Planification",
        "labelWidth": 10,
        "options": [
          {
            "id": "0",
            "label": "0",
            "type": "number",
            "value": 0
          },
          {
            "id": "1",
            "label": "1",
            "type": "number",
            "value": 1
          }
        ],
        "optionsSource": "Custom",
        "section": "",
        "title": "Planification",
        "tooltip": "",
        "type": "multiselect",
        "uid": "1bb83d12-d2ea-46cd-a1d7-793879b579cd",
        "unit": "",
        "value": []
      },
      {
        "id": "id",
        "labelWidth": 10,
        "section": "",
        "title": "id",
        "tooltip": "",
        "type": "number",
        "uid": "c5db338f-0396-4b2a-93e7-a3727a80cfcd",
        "unit": "",
        "value": 0
      }
    ]
  },
  "pluginVersion": "4.1.0",
  "targets": [
    {
      "datasource": {
        "type": "grafana-postgresql-datasource",
        "uid": "ddonkd2fx7h8ga"
      },
      "editorMode": "code",
      "format": "table",
      "rawQuery": true,
      "rawSql": "SELECT * \r\nFROM \"DATA_SCHEMA\".\"LINE\";\r\n---//VALUES ('$(payload.id)','$(payload.Ligne)', '$(payload.Start)', '$(payload.End)', '$(payload.planification)');\r\n",
      "refId": "A",
      "sql": {
        "columns": [
          {
            "parameters": [],
            "type": "function"
          }
        ],
        "groupBy": [
          {
            "property": {
              "type": "string"
            },
            "type": "groupBy"
          }
        ],
        "limit": 50
      }
    }
  ],
  "title": "test 3",
  "type": "volkovlabs-form-panel"
}



I set value by hand, but nothing is write by grafana in my database

I tryied to follow this but I don’t understand how to achieve what I want, and they don’t explain how to just write a simple row in a database which would be a good start for a tutorial

Have you checked Update Request Payload section?

Hello thanks for your reply,
I made some modification with the new syntax but nothing in my SQL database, even If I create a row and try to ‘update’, like in there example ?

I see that my syntax is not pink… ? when I submit, it tells me the notifySuccess :rofl: this is not clear for me If someone handle the plugin

here the json if someone see what is wrong :

{
  "datasource": {
    "type": "grafana-postgresql-datasource",
    "uid": "ddonkd2fx7h8ga"
  },
  "gridPos": {
    "h": 8,
    "w": 12,
    "x": 12,
    "y": 0
  },
  "id": 7,
  "options": {
    "layout": {
      "variant": "single",
      "padding": 10,
      "orientation": "horizontal",
      "sectionVariant": "default"
    },
    "elementValueChanged": "let elements = context.panel.elements;\r\n\r\n// Trouver les éléments 'Debut' et 'Fin'\r\nconst Debut = context.panel.elements.find(\r\n  (element) => element.id === \"Start\"\r\n);\r\nconst Fin = context.panel.elements.find(\r\n  (element) => element.id === \"End\"\r\n);\r\n//const Ligne = context.panel.elements.find(\r\n//  (element) => element.id === \"Line\"\r\n//);\r\n// Vérifiez si 'Debut' et 'Fin' ont des valeurs\r\nconst isFormValid = Debut && Debut.value && Fin && Fin.value;\r\n\r\n// Activer ou désactiver le bouton de soumission en fonction de la validité du formulaire\r\nif (isFormValid) {\r\n  context.panel.enableSubmit();\r\n} else {\r\n  context.panel.disableSubmit();\r\n}\r\n",
    "sync": true,
    "initial": {
      "method": "datasource",
      "contentType": "application/json",
      "code": "console.log(context.panel.data, context.panel.response, context.panel.initial, context.panel.elements);\n\nreturn;\n\n/**\n * Data Source\n * Requires form elements to be defined\n */\nconst dataQuery = context.utils.toDataQueryResponse(context.panel.response);\nconsole.log(dataQuery);",
      "getPayload": "return {}",
      "payload": {
        "editorMode": "code",
        "format": "table",
        "rawQuery": true,
        "rawSql": "SELECT * from \"DATA_SCHEMA\".\"LINE\"",
        "refId": "A",
        "sql": {
          "columns": [
            {
              "parameters": [],
              "type": "function"
            }
          ],
          "groupBy": [
            {
              "property": {
                "type": "string"
              },
              "type": "groupBy"
            }
          ],
          "limit": 50
        }
      },
      "highlight": false,
      "highlightColor": "red",
      "datasource": "Postgresql"
    },
    "updateEnabled": "auto",
    "update": {
      "method": "datasource",
      "contentType": "application/json",
      "code": "if (context.panel.response) {\n  context.grafana.notifySuccess(['Update', 'Values updated successfully.']);\n  context.grafana.locationService.reload();\n} else {\n  context.grafana.notifyError(['Update', 'An error occurred updating values.']);\n}",
      "payloadMode": "custom",
      "getPayload": "const payload = {};\n\ncontext.panel.elements.forEach((element) => {\n  if (!element.value) {\n    return;\n  }\n\n  payload[element.id] = element.value;\n})\n\n\n// Retourner l'objet avec la requête SQL brute\nreturn payload;\n\n\n\n\n",
      "payload": {
        "editorMode": "code",
        "format": "table",
        "rawQuery": true,
        "rawSql": "INSERT\r\n    \"DATA_SCHEMA\".\"LINE\"\r\nset\r\n    id = ${payload.id}, \r\n    LINE = ${payload.Ligne},\r\n    start_time = ${payload.Start},\r\n    end_time = ${payload.End},\r\n    planifie = ${payload.planification}\r\n\r\n",
        "refId": "A",
        "sql": {
          "columns": [
            {
              "parameters": [],
              "type": "function"
            }
          ],
          "groupBy": [
            {
              "property": {
                "type": "string"
              },
              "type": "groupBy"
            }
          ],
          "limit": 50
        }
      },
      "confirm": true,
      "datasource": "Postgresql"
    },
    "confirmModal": {
      "title": "Confirm update request",
      "elementDisplayMode": "all",
      "body": "Confirmation",
      "columns": {
        "include": [
          "name",
          "oldValue",
          "newValue"
        ],
        "name": "Label",
        "oldValue": "Old Value",
        "newValue": "New Value"
      },
      "confirm": "Confirm",
      "cancel": "Cancel"
    },
    "buttonGroup": {
      "orientation": "center",
      "size": "md"
    },
    "submit": {
      "variant": "primary",
      "foregroundColor": "yellow",
      "backgroundColor": "purple",
      "icon": "cloud-upload",
      "text": "Submit"
    },
    "reset": {
      "variant": "hidden",
      "foregroundColor": "yellow",
      "backgroundColor": "purple",
      "icon": "process",
      "text": "Reset"
    },
    "resetAction": {
      "mode": "initial",
      "code": "if (context.panel.response) {\n  context.grafana.notifySuccess(['Update', 'Values updated successfully.']);\n  context.grafana.locationService.reload();\n} else {\n  context.grafana.notifyError(['Update', 'An error occurred updating values.']);\n}",
      "confirm": false,
      "getPayload": "return {}",
      "payload": {}
    },
    "saveDefault": {
      "variant": "hidden",
      "icon": "save",
      "text": "Save Default"
    },
    "elements": [
      {
        "id": "Line",
        "labelWidth": 10,
        "options": [
          {
            "id": "10",
            "label": "10",
            "type": "string",
            "value": "10"
          },
          {
            "id": "11",
            "label": "11",
            "type": "string",
            "value": "11"
          },
          {
            "id": "12",
            "label": "12",
            "type": "string",
            "value": "12"
          },
          {
            "id": "_",
            "label": "",
            "type": "string",
            "value": ""
          }
        ],
        "optionsSource": "Custom",
        "section": "",
        "title": "Line",
        "tooltip": "",
        "type": "select",
        "uid": "04570bb6-642b-4e00-aba2-45cc9235674a",
        "unit": "",
        "value": []
      },
      {
        "id": "Start",
        "isUseLocalTime": false,
        "labelWidth": 10,
        "section": "",
        "title": "Start",
        "tooltip": "",
        "type": "datetime",
        "uid": "9a3ef965-bb71-4d6d-8f7b-69100a2bed0e",
        "unit": "",
        "value": ""
      },
      {
        "id": "End",
        "isUseLocalTime": false,
        "labelWidth": 10,
        "section": "",
        "title": "End",
        "tooltip": "",
        "type": "datetime",
        "uid": "77cc154c-1dc2-46e4-a7de-ed0a36a91dcc",
        "unit": "",
        "value": ""
      },
      {
        "id": "Planification",
        "labelWidth": 10,
        "options": [
          {
            "id": "0",
            "label": "0",
            "type": "number",
            "value": 0
          },
          {
            "id": "1",
            "label": "1",
            "type": "number",
            "value": 1
          }
        ],
        "optionsSource": "Custom",
        "section": "",
        "title": "Planification",
        "tooltip": "",
        "type": "multiselect",
        "uid": "1bb83d12-d2ea-46cd-a1d7-793879b579cd",
        "unit": "",
        "value": []
      },
      {
        "id": "id",
        "labelWidth": 10,
        "section": "",
        "title": "id",
        "tooltip": "",
        "type": "number",
        "uid": "c5db338f-0396-4b2a-93e7-a3727a80cfcd",
        "unit": "",
        "value": 0
      }
    ]
  },
  "pluginVersion": "4.1.0",
  "targets": [
    {
      "datasource": {
        "type": "grafana-postgresql-datasource",
        "uid": "ddonkd2fx7h8ga"
      },
      "editorMode": "code",
      "format": "table",
      "rawQuery": true,
      "rawSql": "---SELECT * \r\n---FROM \"DATA_SCHEMA\".\"LINE\";\r\n---//VALUES ('$(payload.id)','$(payload.Ligne)', '$(payload.Start)', '$(payload.End)', '$(payload.planification)');\r\n",
      "refId": "A",
      "sql": {
        "columns": [
          {
            "parameters": [],
            "type": "function"
          }
        ],
        "groupBy": [
          {
            "property": {
              "type": "string"
            },
            "type": "groupBy"
          }
        ],
        "limit": 50
      }
    }
  ],
  "title": "test 3",
  "type": "volkovlabs-form-panel"
}```

Apparently I need a REST API, I don’t know how to set it, but all links I found :

I use nodered but It is thin to understand what to do with this :

I want some explains, last video is with datamanipulation plugin in V2.3 ?
And how to run all this github files ?

What are the step to just handle the plugin and do real basics things with my SQL table without a headache :face_with_head_bandage:?

I finally did it by with plugin text and not their plugin(business form) , impossible to have clear information about how to use/configure it… got an error everytime with their plugin

but with in html you can write in database passing through the REST API easily.

Am I the only one completely lost with their tutorials ? I was looking to hide all navbar
with this : https://www.youtube.com/watch?v=ChI78v4UZc0

but I will look for other ways, volkov is too complicated for some 5 min touched on video

So Solution : don’t use Volkov :sweat_smile:

Hi SunrakuBzh.

I’m having the same struggle with an MQTT panel we use to have with “MQTT pluging”. Could you please share your HTML code?

It would be very useful for an starting point.
Thanks a lot in advance. :grin: