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: