Skip to content

Commit 4bc1c1a

Browse files
authored
fix(n8n Form Node): Remove field requirement and do not inherit description (#14254)
1 parent 87bc38d commit 4bc1c1a

File tree

11 files changed

+117
-157
lines changed

11 files changed

+117
-157
lines changed

cypress/e2e/16-form-trigger-node.cy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ describe('n8n Form Trigger', () => {
1414
workflowPage.getters.nodeCreatorNodeItems().contains('On form submission').click();
1515
ndv.getters.parameterInput('formTitle').type('Test Form');
1616
ndv.getters.parameterInput('formDescription').type('Test Form Description');
17-
ndv.getters.parameterInput('fieldLabel').type('Test Field 1');
1817
ndv.getters.backToCanvas().click();
1918
workflowPage.getters.nodeIssuesByName('On form submission').should('not.exist');
2019
});
@@ -26,9 +25,10 @@ describe('n8n Form Trigger', () => {
2625
});
2726
ndv.getters.parameterInput('formTitle').type('Test Form');
2827
ndv.getters.parameterInput('formDescription').type('Test Form Description');
29-
//fill up first field of type number
28+
cy.get('[data-test-id="fixed-collection-add"]').click();
3029
ndv.getters.parameterInput('fieldLabel').type('Test Field 1');
3130
ndv.getters.parameterInput('fieldType').click();
31+
//fill up first field of type number
3232
getVisibleSelect().contains('Number').click();
3333
cy.get(
3434
'[data-test-id="parameter-input-requiredField"] > .parameter-input > .el-switch > .el-switch__core',

packages/cli/templates/form-trigger.handlebars

Lines changed: 113 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -437,141 +437,125 @@
437437
<hr>
438438
{{/if}}
439439

440-
{{#if validForm}}
441-
<form class='card' action='#' method='POST' name='n8n-form' id='n8n-form' novalidate>
442-
<div class='form-header'>
443-
<h1>{{formTitle}}</h1>
444-
<p style="white-space: pre-line">{{{formDescription}}} </p>
445-
</div>
446-
447-
<div class='inputs-wrapper'>
448-
{{#each formFields}}
449-
{{#if isMultiSelect}}
450-
<div>
451-
<label class='form-label {{inputRequired}}'>{{label}}</label>
452-
<div class='multiselect {{inputRequired}}' id='{{id}}'>
453-
{{#each multiSelectOptions}}
454-
<div class='multiselect-option'>
455-
<input type='checkbox' class='multiselect-checkbox' id='{{id}}' />
456-
<label for='{{id}}'>{{label}}</label>
457-
</div>
458-
{{/each}}
459-
</div>
460-
<p class='{{errorId}} error-hidden'>
461-
This field is required
462-
</p>
463-
</div>
464-
{{/if}}
465-
466-
{{#if isSelect}}
467-
<div class='form-group'>
468-
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
469-
<div class='select-input'>
470-
<select id='{{id}}' name='{{id}}' class='{{inputRequired}}'>
471-
<option value='' disabled selected>Select an option ...</option>
472-
{{#each selectOptions}}
473-
<option value='{{this}}'>{{this}}</option>
474-
{{/each}}
475-
</select>
476-
</div>
477-
<p class='{{errorId}} error-hidden'>
478-
This field is required
479-
</p>
480-
</div>
481-
{{/if}}
440+
<form class='card' action='#' method='POST' name='n8n-form' id='n8n-form' novalidate>
441+
<div class='form-header'>
442+
<h1>{{formTitle}}</h1>
443+
<p style="white-space: pre-line">{{{formDescription}}} </p>
444+
</div>
482445

483-
{{#if isHtml}}
484-
<div class="form-group html">
485-
{{{html}}}
486-
<input type="hidden" id="{{id}}" name="{{id}}" value="{{html}}" />
487-
</div>
488-
{{/if}}
489-
490-
{{#if isHidden}}
491-
<input type="hidden" id="{{id}}" name="{{id}}" value="{{hiddenValue}}" />
492-
{{/if}}
493-
494-
{{#if isTextarea}}
495-
<div class='form-group'>
496-
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
497-
<textarea
498-
class='form-input {{inputRequired}}'
499-
id='{{id}}'
500-
name='{{id}}'
501-
placeholder="{{placeholder}}"
502-
>{{defaultValue}}</textarea>
503-
<p class='{{errorId}} error-hidden'>
504-
This field is required
505-
</p>
506-
</div>
507-
{{/if}}
508-
509-
{{#if isFileInput}}
510-
<div class='form-group file-input-wrapper'>
511-
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
512-
<input
513-
class='form-input {{inputRequired}}'
514-
type='file'
515-
id='{{id}}'
516-
name='{{id}}'
517-
accept='{{acceptFileTypes}}'
518-
{{multipleFiles}}
519-
placeholder="{{placeholder}}"
520-
/>
521-
<button class="clear-button">&times;</button>
522-
<p class='{{errorId}} error-hidden'>
523-
This field is required
524-
</p>
446+
<div class='inputs-wrapper'>
447+
{{#each formFields}}
448+
{{#if isMultiSelect}}
449+
<div>
450+
<label class='form-label {{inputRequired}}'>{{label}}</label>
451+
<div class='multiselect {{inputRequired}}' id='{{id}}'>
452+
{{#each multiSelectOptions}}
453+
<div class='multiselect-option'>
454+
<input type='checkbox' class='multiselect-checkbox' id='{{id}}' />
455+
<label for='{{id}}'>{{label}}</label>
456+
</div>
457+
{{/each}}
525458
</div>
526-
{{/if}}
527-
528-
{{#if isInput}}
529-
<div class='form-group'>
530-
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
531-
<input
532-
class='form-input {{inputRequired}}'
533-
type='{{type}}'
534-
id='{{id}}'
535-
name='{{id}}'
536-
value="{{defaultValue}}"
537-
placeholder="{{placeholder}}"
538-
/>
539-
<p class='{{errorId}} error-hidden'>
540-
This field is required
541-
</p>
459+
<p class='{{errorId}} error-hidden'>
460+
This field is required
461+
</p>
462+
</div>
463+
{{/if}}
464+
465+
{{#if isSelect}}
466+
<div class='form-group'>
467+
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
468+
<div class='select-input'>
469+
<select id='{{id}}' name='{{id}}' class='{{inputRequired}}'>
470+
<option value='' disabled selected>Select an option ...</option>
471+
{{#each selectOptions}}
472+
<option value='{{this}}'>{{this}}</option>
473+
{{/each}}
474+
</select>
542475
</div>
543-
{{/if}}
544-
{{/each}}
545-
</div>
546-
547-
<button id='submit-btn' type='submit'>
548-
<span><svg
549-
xmlns='http://www.w3.org/2000/svg'
550-
height='18px'
551-
viewBox='0 0 512 512'
552-
>
553-
<path
554-
d='M304 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm0 416a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM48 304a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm464-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM142.9 437A48 48 0 1 0 75 369.1 48 48 0 1 0 142.9 437zm0-294.2A48 48 0 1 0 75 75a48 48 0 1 0 67.9 67.9zM369.1 437A48 48 0 1 0 437 369.1 48 48 0 1 0 369.1 437z'
476+
<p class='{{errorId}} error-hidden'>
477+
This field is required
478+
</p>
479+
</div>
480+
{{/if}}
481+
482+
{{#if isHtml}}
483+
<div class="form-group html">
484+
{{{html}}}
485+
<input type="hidden" id="{{id}}" name="{{id}}" value="{{html}}" />
486+
</div>
487+
{{/if}}
488+
489+
{{#if isHidden}}
490+
<input type="hidden" id="{{id}}" name="{{id}}" value="{{hiddenValue}}" />
491+
{{/if}}
492+
493+
{{#if isTextarea}}
494+
<div class='form-group'>
495+
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
496+
<textarea
497+
class='form-input {{inputRequired}}'
498+
id='{{id}}'
499+
name='{{id}}'
500+
placeholder="{{placeholder}}"
501+
>{{defaultValue}}</textarea>
502+
<p class='{{errorId}} error-hidden'>
503+
This field is required
504+
</p>
505+
</div>
506+
{{/if}}
507+
508+
{{#if isFileInput}}
509+
<div class='form-group file-input-wrapper'>
510+
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
511+
<input
512+
class='form-input {{inputRequired}}'
513+
type='file'
514+
id='{{id}}'
515+
name='{{id}}'
516+
accept='{{acceptFileTypes}}'
517+
{{multipleFiles}}
518+
placeholder="{{placeholder}}"
519+
/>
520+
<button class="clear-button">&times;</button>
521+
<p class='{{errorId}} error-hidden'>
522+
This field is required
523+
</p>
524+
</div>
525+
{{/if}}
526+
527+
{{#if isInput}}
528+
<div class='form-group'>
529+
<label class='form-label {{inputRequired}}' for='{{id}}'>{{label}}</label>
530+
<input
531+
class='form-input {{inputRequired}}'
532+
type='{{type}}'
533+
id='{{id}}'
534+
name='{{id}}'
535+
value="{{defaultValue}}"
536+
placeholder="{{placeholder}}"
555537
/>
556-
</svg></span>
557-
{{ buttonLabel }}
558-
</button>
559-
</form>
560-
{{else}}
561-
<div class='card'>
562-
<div class='form-header'>
563-
{{#if testRun}}
564-
<h1>Please add at least one field to your form</h1>
565-
{{else}}
566-
<h1>Problem loading form</h1>
567-
<p>
568-
This usually occurs if the n8n workflow serving this form is deactivated or no
569-
longer exist
570-
</p>
538+
<p class='{{errorId}} error-hidden'>
539+
This field is required
540+
</p>
541+
</div>
571542
{{/if}}
572-
</div>
543+
{{/each}}
573544
</div>
574-
{{/if}}
545+
546+
<button id='submit-btn' type='submit'>
547+
<span><svg
548+
xmlns='http://www.w3.org/2000/svg'
549+
height='18px'
550+
viewBox='0 0 512 512'
551+
>
552+
<path
553+
d='M304 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm0 416a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM48 304a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm464-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM142.9 437A48 48 0 1 0 75 369.1 48 48 0 1 0 142.9 437zm0-294.2A48 48 0 1 0 75 75a48 48 0 1 0 67.9 67.9zM369.1 437A48 48 0 1 0 437 369.1 48 48 0 1 0 369.1 437z'
554+
/>
555+
</svg></span>
556+
{{ buttonLabel }}
557+
</button>
558+
</form>
575559

576560
<div class='card' id='submitted-form' style='display: none;'>
577561
<div class='form-header'>

packages/nodes-base/nodes/Form/common.descriptions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const formFields: INodeProperties = {
4646
name: 'formFields',
4747
placeholder: 'Add Form Element',
4848
type: 'fixedCollection',
49-
default: { values: [{ label: '', fieldType: 'text' }] },
49+
default: {},
5050
typeOptions: {
5151
multipleValues: true,
5252
sortable: true,

packages/nodes-base/nodes/Form/formNodeUtils.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ export const renderFormNode = async (
2727
title = context.evaluateExpression(`{{ $('${trigger?.name}').params.formTitle }}`) as string;
2828
}
2929

30-
let description = options.formDescription;
31-
if (!description) {
32-
description = context.evaluateExpression(
33-
`{{ $('${trigger?.name}').params.formDescription }}`,
34-
) as string;
35-
}
36-
3730
let buttonLabel = options.buttonLabel;
3831
if (!buttonLabel) {
3932
buttonLabel =
@@ -50,7 +43,7 @@ export const renderFormNode = async (
5043
context,
5144
res,
5245
formTitle: title,
53-
formDescription: description,
46+
formDescription: options.formDescription,
5447
formFields: fields,
5548
responseMode: 'responseNode',
5649
mode,

packages/nodes-base/nodes/Form/interfaces.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export type FormTriggerInput = {
1919

2020
export type FormTriggerData = {
2121
testRun: boolean;
22-
validForm: boolean;
2322
formTitle: string;
2423
formDescription?: string;
2524
formDescriptionMetadata?: string;

packages/nodes-base/nodes/Form/test/Form.node.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ describe('Form Node', () => {
167167
n8nWebsiteLink: 'https://n8n.io/?utm_source=n8n-internal&utm_medium=form-trigger',
168168
testRun: true,
169169
useResponseData: true,
170-
validForm: true,
171170
formSubmittedHeader: undefined,
172171
});
173172
});

packages/nodes-base/nodes/Form/test/FormTriggerV2.node.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ describe('FormTrigger', () => {
109109
'https://n8n.io/?utm_source=n8n-internal&utm_medium=form-trigger&utm_campaign=instanceId',
110110
testRun: true,
111111
useResponseData: false,
112-
validForm: true,
113112
});
114113

115114
expect(responseData).toEqual({ noWebhookResponse: true });

packages/nodes-base/nodes/Form/test/formNodeUtils.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ describe('formNodeUtils', () => {
117117
n8nWebsiteLink: 'https://n8n.io/?utm_source=n8n-internal&utm_medium=form-trigger',
118118
testRun: true,
119119
useResponseData: true,
120-
validForm: true,
121120
});
122121
});
123122
});

packages/nodes-base/nodes/Form/test/utils.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ describe('FormTrigger, formWebhook', () => {
203203
'https://n8n.io/?utm_source=n8n-internal&utm_medium=form-trigger&utm_campaign=instanceId',
204204
testRun: true,
205205
useResponseData: false,
206-
validForm: true,
207206
});
208207
});
209208

@@ -250,7 +249,6 @@ describe('FormTrigger, formWebhook', () => {
250249
'https://n8n.io/?utm_source=n8n-internal&utm_medium=form-trigger&utm_campaign=instanceId',
251250
testRun: true,
252251
useResponseData: false,
253-
validForm: true,
254252
});
255253
}
256254
});
@@ -353,7 +351,6 @@ describe('FormTrigger, prepareFormData', () => {
353351

354352
expect(result).toEqual({
355353
testRun: false,
356-
validForm: true,
357354
formTitle: 'Test Form',
358355
formDescription: 'This is a test form',
359356
formDescriptionMetadata: 'This is a test form',
@@ -455,7 +452,6 @@ describe('FormTrigger, prepareFormData', () => {
455452

456453
expect(result).toEqual({
457454
testRun: true,
458-
validForm: true,
459455
formTitle: 'Test Form',
460456
formDescription: 'This is a test form',
461457
formDescriptionMetadata: 'This is a test form',
@@ -515,7 +511,6 @@ describe('FormTrigger, prepareFormData', () => {
515511
query: {},
516512
});
517513

518-
expect(result.validForm).toBe(false);
519514
expect(result.formFields).toEqual([]);
520515
});
521516

0 commit comments

Comments
 (0)