Date Range on n8n form

Describe the problem/error/question

I’m trying to create a conversation analyzer and i want to start with a n8n form where the user can choose the account to analyze, the date range, the type of analisis (all the chats, just one specific).
But i noticed there is not a predefined option for the date range, but only for date (to choose one day only). I would like to know if with customHTML i can do it. i’ve tried as you can see after, but it only displays the text i’ve pasted you down here

Please share your workflow

{“nodes”: [{“parameters”: {“formTitle”: “Conversation Analyzer”,“formDescription”: “This form is needed to analyze a conversation by date”,“formFields”: {“values”: [{“fieldLabel”: “Model”,“fieldType”: “dropdown”,“fieldOptions”: {“values”: [{“option”: “Evie”},{“option”: “Alesya”},{“option”: “Mia”},{“option”: “Jana”},{“option”: “Lisa Goth”},{“option”: “Coco”},{“option”: “Lisa”}]},“requiredField”: true},{“fieldType”: “html”,“html”: “\n    \n      \n        From Date\n      \n      <input \n        type=“date” \n        name=“start_date” \n        id=“start_date”\n        required \n        style="\n          width: 100%; \n          padding: 10px 12px; \n          border: 2px solid #d1d5db; \n          border-radius: 6px; \n          font-size: 14px;\n          background: white;\n          transition: border-color 0.2s;\n        “\n        onchange=“validateDateRange()”\n      />\n    \n    \n    \n    \n      \n        To Date\n      \n      <input \n        type=“date” \n        name=“end_date” \n        id=“end_date”\n        required \n        style=”\n          width: 100%; \n          padding: 10px 12px; \n          border: 2px solid #d1d5db; \n          border-radius: 6px; \n          font-size: 14px;\n          background: white;\n          transition: border-color 0.2s;\n        “\n        onchange=“validateDateRange()”\n      />\n    </div\n  \n  \n  \n  \n    <button \n      type=“button”\n      onclick=“setDateRange(7)”\n      style=”\n        padding: 6px 12px;\n        background: #eff6ff;\n        color: #1e40af;\n        border: 1px solid #bfdbfe;\n        border-radius: 4px;\n        font-size: 12px;\n        cursor: pointer;\n        font-weight: 500;\n      “\n    >\n      Last 7 days\n    \n    <button \n      type=“button”\n      onclick=“setDateRange(30)”\n      style=”\n        padding: 6px 12px;\n        background: #eff6ff;\n        color: #1e40af;\n        border: 1px solid #bfdbfe;\n        border-radius: 4px;\n        font-size: 12px;\n        cursor: pointer;\n        font-weight: 500;\n      “\n    >\n      Last 30 days\n    \n    <button \n      type=“button”\n      onclick=“setDateRange(90)”\n      style=”\n        padding: 6px 12px;\n        background: #eff6ff;\n        color: #1e40af;\n        border: 1px solid #bfdbfe;\n        border-radius: 4px;\n        font-size: 12px;\n        cursor: pointer;\n        font-weight: 500;\n      “\n    >\n      Last 3 months\n    \n    <button \n      type=“button”\n      onclick=“setThisMonth()”\n      style=”\n        padding: 6px 12px;\n        background: #f0fdf4;\n        color: #15803d;\n        border: 1px solid #bbf7d0;\n        border-radius: 4px;\n        font-size: 12px;\n        cursor: pointer;\n        font-weight: 500;\n      "\n    >\n      This month\n    \n  \n  \n  \n  \n    \n  \n  \n  \n  \n    ⚠️ \n  \n\n\n\n// Set max date to today\nconst today = new Date().toISOString().split(‘T’)[0];\ndocument.getElementById(‘start_date’).setAttribute(‘max’, today);\ndocument.getElementById(‘end_date’).setAttribute(‘max’, today);\n\n// Set default to last 7 days\nsetDateRange(7);\n\nfunction setDateRange(days) {\n  const end = new Date();\n  const start = new Date();\n  start.setDate(start.getDate() - days);\n  \n  document.getElementById(‘start_date’).value = start.toISOString().split(‘T’)[0];\n  document.getElementById(‘end_date’).value = end.toISOString().split(‘T’)[0];\n  \n  validateDateRange();\n}\n\nfunction setThisMonth() {\n  const now = new Date();\n  const start = new Date(now.getFullYear(), now.getMonth(), 1);\n  const end = new Date();\n  \n  document.getElementById(‘start_date’).value = start.toISOString().split(‘T’)[0];\n  document.getElementById(‘end_date’).value = end.toISOString().split(‘T’)[0];\n  \n  validateDateRange();\n}\n\nfunction validateDateRange() {\n  const startInput = document.getElementById(‘start_date’);\n  const endInput = document.getElementById(‘end_date’);\n  const infoDiv = document.getElementById(‘date_info’);\n  const errorDiv = document.getElementById(‘date_error’);\n  const errorMessage = document.getElementById(‘error_message’);\n  const daysCount = document.getElementById(‘days_count’);\n  \n  const startDate = new Date(startInput.value);\n  const endDate = new Date(endInput.value);\n  \n  // Hide messages by default\n  infoDiv.style.display = ‘none’;\n  errorDiv.style.display = ‘none’;\n  \n  // Reset border colors\n  startInput.style.borderColor = ‘#d1d5db’;\n  endInput.style.borderColor = ‘#d1d5db’;\n  \n  if (!startInput.value || !endInput.value) {\n    return;\n  }\n  \n  // Check if start is after end\n  if (startDate > endDate) {\n    errorDiv.style.display = ‘block’;\n    errorMessage.textContent = ‘Start date must be before end date’;\n    startInput.style.borderColor = ‘#ef4444’;\n    endInput.style.borderColor = ‘#ef4444’;\n    return;\n  }\n  \n  // Check if dates are in the future\n  const today = new Date();\n  today.setHours(0, 0, 0, 0);\n  \n  if (startDate > today || endDate > today) {\n    errorDiv.style.display = ‘block’;\n    errorMessage.textContent = ‘Cannot select future dates’;\n    if (startDate > today) startInput.style.borderColor = ‘#ef4444’;\n    if (endDate > today) endInput.style.borderColor = ‘#ef4444’;\n    return;\n  }\n  \n  // Calculate days\n  const diffTime = Math.abs(endDate - startDate);\n  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;\n  \n  // Show info\n  startInput.style.borderColor = ‘#10b981’;\n  endInput.style.borderColor = ‘#10b981’;\n  infoDiv.style.display = ‘block’;\n  daysCount.textContent = Selected range: ${diffDays} day${diffDays !== 1 ? 's' : ''} of conversations will be analyzed;\n  \n  // Warn if range is very large\n  if (diffDays > 90) {\n    infoDiv.style.background = ‘#fef3c7’;\n    infoDiv.style.borderColor = ‘#f59e0b’;\n    infoDiv.style.color = ‘#92400e’;\n    daysCount.textContent = ⚠️ Large range (${diffDays} days) - this may take several minutes to process;\n  }\n}\nur custom HTML here —>\n\n\n”},{“fieldLabel”: “Analysis Type”,“fieldType”: “dropdown”,“fieldOptions”: {“values”: [{“option”: “Analyze every single chat”},{“option”: “Analyze a particulat chat (fill the optional field)”}]},“requiredField”: true},{“fieldLabel”: “Chat ID”}]},“options”: {}},“type”: “n8n-nodes-base.formTrigger”,“typeVersion”: 2.3,“position”: [-832,-80],“id”: “e8448c43-a66c-47bb-be3f-85d1b5fecc61”,“name”: “On form submission”,“webhookId”: “6cc517c0-f53e-46a1-9064-15adc0ba4465”}],“connections”: {“On form submission”: {“main”: []}},“pinData”: {},“meta”: {“templateCredsSetupCompleted”: true,“instanceId”: “9a6a1f34a6359a65a4195214db635d2afc6f4fd0f099fedeb19e0a665a8d6e01”}}

{
“nodes”: [
{
“parameters”: {
“formTitle”: “Conversation Analyzer”,
“formDescription”: “This form is needed to analyze a conversation by date”,
“formFields”: {
“values”: [
{
“fieldLabel”: “Model”,
“fieldType”: “dropdown”,
“fieldOptions”: {
“values”: [
{
“option”: “Evie”
},
{
“option”: “Alesya”
},
{
“option”: “Mia”
},
{
“option”: “Jana”
},
{
“option”: “Lisa Goth”
},
{
“option”: “Coco”
},
{
“option”: “Lisa”
}
]
},
“requiredField”: true
},
{
“fieldType”: “html”,
“html”: “\n \n \n From Date\n \n <input \n type=“date” \n name=“start_date” \n id=“start_date”\n required \n style="\n width: 100%; \n padding: 10px 12px; \n border: 2px solid #d1d5db; \n border-radius: 6px; \n font-size: 14px;\n background: white;\n transition: border-color 0.2s;\n “\n onchange=“validateDateRange()”\n />\n \n \n \n \n \n To Date\n \n <input \n type=“date” \n name=“end_date” \n id=“end_date”\n required \n style=”\n width: 100%; \n padding: 10px 12px; \n border: 2px solid #d1d5db; \n border-radius: 6px; \n font-size: 14px;\n background: white;\n transition: border-color 0.2s;\n “\n onchange=“validateDateRange()”\n />\n </div\n \n \n \n \n <button \n type=“button”\n onclick=“setDateRange(7)”\n style=”\n padding: 6px 12px;\n background: #eff6ff;\n color: #1e40af;\n border: 1px solid #bfdbfe;\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n font-weight: 500;\n “\n >\n Last 7 days\n \n <button \n type=“button”\n onclick=“setDateRange(30)”\n style=”\n padding: 6px 12px;\n background: #eff6ff;\n color: #1e40af;\n border: 1px solid #bfdbfe;\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n font-weight: 500;\n “\n >\n Last 30 days\n \n <button \n type=“button”\n onclick=“setDateRange(90)”\n style=”\n padding: 6px 12px;\n background: #eff6ff;\n color: #1e40af;\n border: 1px solid #bfdbfe;\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n font-weight: 500;\n “\n >\n Last 3 months\n \n <button \n type=“button”\n onclick=“setThisMonth()”\n style=”\n padding: 6px 12px;\n background: #f0fdf4;\n color: #15803d;\n border: 1px solid #bbf7d0;\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n font-weight: 500;\n "\n >\n This month\n \n \n \n \n \n \n \n \n \n \n :warning: \n \n\n\n\n// Set max date to today\nconst today = new Date().toISOString().split(‘T’)[0];\ndocument.getElementById(‘start_date’).setAttribute(‘max’, today);\ndocument.getElementById(‘end_date’).setAttribute(‘max’, today);\n\n// Set default to last 7 days\nsetDateRange(7);\n\nfunction setDateRange(days) {\n const end = new Date();\n const start = new Date();\n start.setDate(start.getDate() - days);\n \n document.getElementById(‘start_date’).value = start.toISOString().split(‘T’)[0];\n document.getElementById(‘end_date’).value = end.toISOString().split(‘T’)[0];\n \n validateDateRange();\n}\n\nfunction setThisMonth() {\n const now = new Date();\n const start = new Date(now.getFullYear(), now.getMonth(), 1);\n const end = new Date();\n \n document.getElementById(‘start_date’).value = start.toISOString().split(‘T’)[0];\n document.getElementById(‘end_date’).value = end.toISOString().split(‘T’)[0];\n \n validateDateRange();\n}\n\nfunction validateDateRange() {\n const startInput = document.getElementById(‘start_date’);\n const endInput = document.getElementById(‘end_date’);\n const infoDiv = document.getElementById(‘date_info’);\n const errorDiv = document.getElementById(‘date_error’);\n const errorMessage = document.getElementById(‘error_message’);\n const daysCount = document.getElementById(‘days_count’);\n \n const startDate = new Date(startInput.value);\n const endDate = new Date(endInput.value);\n \n // Hide messages by default\n infoDiv.style.display = ‘none’;\n errorDiv.style.display = ‘none’;\n \n // Reset border colors\n startInput.style.borderColor = ‘#d1d5db’;\n endInput.style.borderColor = ‘#d1d5db’;\n \n if (!startInput.value || !endInput.value) {\n return;\n }\n \n // Check if start is after end\n if (startDate > endDate) {\n errorDiv.style.display = ‘block’;\n errorMessage.textContent = ‘Start date must be before end date’;\n startInput.style.borderColor = ‘#ef4444’;\n endInput.style.borderColor = ‘#ef4444’;\n return;\n }\n \n // Check if dates are in the future\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n \n if (startDate > today || endDate > today) {\n errorDiv.style.display = ‘block’;\n errorMessage.textContent = ‘Cannot select future dates’;\n if (startDate > today) startInput.style.borderColor = ‘#ef4444’;\n if (endDate > today) endInput.style.borderColor = ‘#ef4444’;\n return;\n }\n \n // Calculate days\n const diffTime = Math.abs(endDate - startDate);\n const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;\n \n // Show info\n startInput.style.borderColor = ‘#10b981’;\n endInput.style.borderColor = ‘#10b981’;\n infoDiv.style.display = ‘block’;\n daysCount.textContent = Selected range: ${diffDays} day${diffDays !== 1 ? 's' : ''} of conversations will be analyzed;\n \n // Warn if range is very large\n if (diffDays > 90) {\n infoDiv.style.background = ‘#fef3c7’;\n infoDiv.style.borderColor = ‘#f59e0b’;\n infoDiv.style.color = ‘#92400e’;\n daysCount.textContent = ⚠️ Large range (${diffDays} days) - this may take several minutes to process;\n }\n}\nur custom HTML here —>\n\n\n”
},
{
“fieldLabel”: “Analysis Type”,
“fieldType”: “dropdown”,
“fieldOptions”: {
“values”: [
{
“option”: “Analyze every single chat”
},
{
“option”: “Analyze a particulat chat (fill the optional field)”
}
]
},
“requiredField”: true
},
{
“fieldLabel”: “Chat ID”
}
]
},
“options”: {}
},
“type”: “n8n-nodes-base.formTrigger”,
“typeVersion”: 2.3,
“position”: [
-832,
-80
],
“id”: “e8448c43-a66c-47bb-be3f-85d1b5fecc61”,
“name”: “On form submission”,
“webhookId”: “6cc517c0-f53e-46a1-9064-15adc0ba4465”
}
],
“connections”: {
“On form submission”: {
“main”: [

]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “9a6a1f34a6359a65a4195214db635d2afc6f4fd0f099fedeb19e0a665a8d6e01”
}
}

Share the output returned by the last node

Model
Select an option …
From Date
To Date
Last 7 days Last 30 days Last 3 months This month
:warning:
ur custom HTML here —>
Analysis Type
Select an option …

Information on your n8n setup

  • n8n version:2.0.2
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app): docker
  • Operating system: ios

Unfortunately, this is not supported by the forms node yet. The custom html field is for static information and you can’t utilize it to add more complex input fields.

For a date range selector, you could use two date fields (start and end date).

Alternatively you can use services like typeform to create more advanced forms and connect it with the typeform trigger node.

3 Likes

ok, thank you very much