使用 JSON 生成的多欄位表單

你好,

我有一個工作流程,想根據表單觸發節點的提交來構建一個包含某些日期的下拉選單。我還想根據表單觸發節點中選定的單選按鈕添加條件。我已建立 JSON 代碼節點,如附件所示。不過,我在正確構建下一個表單時遇到了問題(附件工作流程中的「添加日期」節點)。我希望它顯示兩個欄位:標記為「表單欄位」的下拉選單和標記為「NIP」的文字輸入。遺憾的是,它要麼只顯示一個欄位(如附件工作流程所示),要麼在進行某些修改後,會拋出「不是有效的 json」錯誤。有人知道如何構建此節點來實現我的目標嗎?

{
  "name": "[2.9] Zadanie domowe - formularz szkolenia",
  "nodes": [
    {
      "parameters": {
        "formTitle": "Formularz zapisu na szkolenie",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Imię i nazwisko:",
              "placeholder": "Jan Kowalski",
              "requiredField": true
            },
            {
              "fieldLabel": "e-mail:",
              "fieldType": "email",
              "placeholder": "a@b.cd",
              "requiredField": true
            },
            {
              "fieldLabel": "Telefon:",
              "placeholder": "+48 123 456 789",
              "requiredField": true
            },
            {
              "fieldLabel": "Bierzesz udział jako:",
              "fieldType": "radio",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Firma"
                  },
                  {
                    "option": "Osoba prywatna"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.5,
      "position": [
        0,
        0
      ],
      "id": "28e29a54-80a4-4197-af04-2389d4a3221e",
      "name": "On form submission",
      "webhookId": "67fa2c56-27e9-470d-968e-a352bef94e20"
    },
    {
      "parameters": {
        "operation": "completion",
        "completionTitle": "={{ $if($json != null, \"Sukces!\", \"Oj, coś poszło nie tak...\") }}",
        "completionMessage": "={{ $json.summary[0].fieldLabel }}",
        "options": {}
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 2.5,
      "position": [
        768,
        0
      ],
      "id": "c9cb7630-fdf6-4d2e-8c74-45f660e4c518",
      "name": "Form",
      "webhookId": "3ae63389-41aa-41c6-ae51-5b8cba10bb13"
    },
    {
      "parameters": {
        "defineForm": "json",
        "jsonOutput": "={{ $json.formFields, $json.NIP }}",
        "options": {}
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 2.5,
      "position": [
        416,
        0
      ],
      "id": "6f462d5f-f41b-4f5b-afc1-333de809002f",
      "name": "Add Dates",
      "webhookId": "f58ff39c-4aeb-49b9-a448-5f843494f823"
    },
    {
      "parameters": {
        "jsCode": "const label = \"Droga/Drogi \" + $(\"Calculate dates and NIP\").first().json[\"Imię i nazwisko:\"] + \".\\nZostałaś/zostałeś pomyślnie zarejestrowana/zarejestrowany na szkolenie w dniu:\\n\" + $input.first().json[\"Wybierz termin\"];\n\nconst formFields = [\n  {\n    fieldLabel: label\n  }\n];\n\nreturn [{\n  json: {\n    summary: formFields\n  }\n}]"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        592,
        0
      ],
      "id": "b31b8584-6b17-4411-84b9-9f28378389f4",
      "name": "Success Summary Text"
    },
    {
      "parameters": {
        "jsCode": "const availableDates = Array.from({ length: 6 }, (_, offset) =\
  const dayOffset = (today) =\
    let off = 2 - today;\n    return off;\n  }\n  \n  const date = $now.plus({ weeks: offset + 1, days: dayOffset(DateTime.local().weekday) });\n\n  \n  return {\n    option: date.toFormat('dd.MM.yyyy')\n  };\n});\n\nconst formFields = [\n  {\n    fieldLabel: \"Wybierz termin\",\n    fieldType: \"dropdown\",\n    requiredField: true,\n    fieldOptions: {\n      values: availableDates\n    }\n  }\n];\n\nconst nipInput = ($input.first().json[\"Bierzesz udział jako:\"] === \"Firma\" ? [\n  {\n    fieldLabel: \"Podaj NIP\",\n    fieldType: \"text\",\n    requiredField: true\n  }\n] : null );\n\nreturn [{\n  json: {\n    ...$input.first().json,\n    formFields: formFields,\n    NIP: nipInput,\n    //availableDates: availableDates.map(d =\
  }\n}]"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        208,
        0
      ],
      "id": "57f1ca26-2ddb-4b49-b670-e83845632a8f",
      "name": "Calculate dates and NIP"
    }
  ],
  "pinData": {},
  "connections": {
    "On form submission": {
      "main": [
        [
          {
            "node": "Calculate dates and NIP",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Dates": {
      "main": [
        [
          {
            "node": "Success Summary Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Success Summary Text": {
      "main": [
        [
          {
            "node": "Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate dates and NIP": {
      "main": [
        [
          {
            "node": "Add Dates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "b4b36e4b-ee4d-4192-bf1d-c271d725b0b0",
  "meta": {
    "instanceId": "6bf048c6d4d3d2ea0ff37f1fadbd0c376cd8e3dfc89fd11ea9adc8fc9affaad7"
  },
  "id": "DmjAWBhbgcnJsCAo",
  "tags": []
}
1個讚

@Michal_Moraszczyk

你可以試試這個嗎?

2個讚

嗨 Michal,

問題很可能是你的 Code 節點輸出 JSON 的方式。Form 節點期望在輸出的最上層得到一個 JSON 陣列 — 而不是嵌套在物件內或包裝成字串。

以下是你的「Add dates」Form 節點的有效結構(設定為「Define form using JSON」):

[
  {
    "fieldLabel": "Select Date",
    "fieldType": "dropdown",
    "fieldOptions": {
      "values": [
        { "option": "your_dynamic_date_1" },
        { "option": "your_dynamic_date_2" }
      ]
    },
    "requiredField": true
  },
  {
    "fieldLabel": "NIP",
    "fieldType": "text",
    "placeholder": "Enter NIP",
    "requiredField": true
  }
]

導致「not valid json」或只顯示一個欄位的常見陷阱:

  1. 包裝在物件中 — 不要回傳 { "fields": [...] }。Form 節點期望直接得到陣列。只回傳陣列。

  2. 以字串形式回傳 — 如果你的 Code 節點執行 JSON.stringify(),Form 節點會收到字串而不是已解析的物件。將陣列作為實際物件回傳。

  3. 多個項目而不是一個 — 你的 Code 節點應該回傳一個項目,其中包含完整陣列。在你的 Code 節點中使用這個模式:

const fields = [
  {
    fieldLabel: "Select Date",
    fieldType: "dropdown",
    fieldOptions: {
      values: dates.map(d => ({ option: d }))
    },
    requiredField: true
  },
  {
    fieldLabel: "NIP",
    fieldType: "text",
    placeholder: "Enter NIP",
    requiredField: true
  }
];

return [{ json: fields }];

關鍵部分是 return [{ json: fields }] — 單一項目,陣列放入 json 中。這是大多數人會遺漏的地方。

對於單選按鈕條件 — 在 Form Trigger 後面使用一個 IF 節點來分支,並將正確的分支連接到「Add dates」Form 節點。每個分支都可以有自己的 Form 節點,具有不同的欄位定義。

希望這對你有幫助!

1個讚

嗨,

你的解決方案對我來說完美地有效。謝謝你!

1個讚

嗨,

您的說明很詳盡且很有幫助。我會牢記您的建議——它們對我未來的工作流程也會很有幫助。謝謝!