@reldens/cms 0.21.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +413 -2
- package/admin/reldens-admin-client.css +10 -128
- package/admin/templates/fields/view/audio.html +7 -0
- package/admin/templates/fields/view/audios.html +8 -0
- package/install/index.html +4 -0
- package/lib/admin-manager/router-contents.js +18 -7
- package/lib/cache/add-cache-button-subscriber.js +1 -1
- package/lib/cache/cache-routes-handler.js +1 -1
- package/lib/dynamic-form-renderer.js +228 -0
- package/lib/dynamic-form-request-handler.js +135 -0
- package/lib/dynamic-form.js +310 -0
- package/lib/frontend.js +35 -1
- package/lib/installer.js +2 -1
- package/lib/template-engine/forms-transformer.js +187 -0
- package/lib/template-engine.js +17 -0
- package/lib/templates-list.js +2 -0
- package/migrations/default-forms.sql +22 -0
- package/package.json +5 -5
- package/templates/cms_forms/field_email.html +14 -0
- package/templates/cms_forms/field_number.html +17 -0
- package/templates/cms_forms/field_select.html +15 -0
- package/templates/cms_forms/field_text.html +16 -0
- package/templates/cms_forms/field_textarea.html +13 -0
- package/templates/cms_forms/form.html +22 -0
- package/templates/css/styles.css +4 -0
package/install/index.html
CHANGED
|
@@ -101,6 +101,10 @@
|
|
|
101
101
|
<input type="checkbox" name="install-entity-access" id="install-entity-access" checked/>
|
|
102
102
|
<label for="install-entity-access">Install entity access control rules</label>
|
|
103
103
|
</div>
|
|
104
|
+
<div class="input-box input-checkbox install-dynamic-forms">
|
|
105
|
+
<input type="checkbox" name="install-dynamic-forms" id="install-dynamic-forms" checked/>
|
|
106
|
+
<label for="install-dynamic-forms">Install dynamic forms system</label>
|
|
107
|
+
</div>
|
|
104
108
|
<div class="input-box submit-container">
|
|
105
109
|
<input id="install-submit-button" type="submit" value="Install"/>
|
|
106
110
|
<img class="install-loading hidden" src="/install-assets/img/loading.gif"/>
|
|
@@ -132,6 +132,10 @@ class RouterContents
|
|
|
132
132
|
return '';
|
|
133
133
|
}
|
|
134
134
|
let loadedEntity = await this.loadEntityById(driverResource, id);
|
|
135
|
+
if(!loadedEntity){
|
|
136
|
+
Logger.critical('Entity not found on view route.', entityPath, id, idProperty);
|
|
137
|
+
return '';
|
|
138
|
+
}
|
|
135
139
|
let renderedViewProperties = {
|
|
136
140
|
entityEditRoute: this.generateEntityRoute('editPath', driverResource, idProperty, loadedEntity),
|
|
137
141
|
entityNewRoute: this.rootPath+'/'+driverResource.entityPath+this.editPath,
|
|
@@ -461,7 +465,7 @@ class RouterContents
|
|
|
461
465
|
}
|
|
462
466
|
}
|
|
463
467
|
return await this.adminContentsRender(
|
|
464
|
-
this.adminFilesContents.fields.view[this.propertyType(resourceProperty, templateType)],
|
|
468
|
+
this.adminFilesContents.fields.view[this.propertyType(resourceProperty, templateType, fieldValue)],
|
|
465
469
|
{fieldName, fieldValue, fieldOriginalValue, target: ' target="_blank"'}
|
|
466
470
|
);
|
|
467
471
|
}
|
|
@@ -469,7 +473,7 @@ class RouterContents
|
|
|
469
473
|
generatePropertyRenderedValueWithLabel(entity, propertyKey, resourceProperty)
|
|
470
474
|
{
|
|
471
475
|
let fieldValue = (0 === entity[propertyKey] ? '0' : entity[propertyKey] || '');
|
|
472
|
-
if(sc.isObject(fieldValue) && 'json' === resourceProperty.dbType){
|
|
476
|
+
if((sc.isObject(fieldValue) || sc.isArray(fieldValue)) && 'json' === resourceProperty.dbType){
|
|
473
477
|
fieldValue = sc.toJsonString(fieldValue);
|
|
474
478
|
}
|
|
475
479
|
let fieldName = propertyKey;
|
|
@@ -512,7 +516,7 @@ class RouterContents
|
|
|
512
516
|
if('null' === fieldValue){
|
|
513
517
|
fieldValue = '';
|
|
514
518
|
}
|
|
515
|
-
if(sc.isObject(fieldValue) && 'json' === resourceProperty.dbType){
|
|
519
|
+
if((sc.isObject(fieldValue) || sc.isArray(fieldValue)) && 'json' === resourceProperty.dbType){
|
|
516
520
|
fieldValue = sc.toJsonString(fieldValue);
|
|
517
521
|
}
|
|
518
522
|
if('boolean' === resourceProperty.type){
|
|
@@ -562,7 +566,7 @@ class RouterContents
|
|
|
562
566
|
return await relationEntityRepository.loadAll();
|
|
563
567
|
}
|
|
564
568
|
|
|
565
|
-
propertyType(resourceProperty, templateType)
|
|
569
|
+
propertyType(resourceProperty, templateType, fieldValue)
|
|
566
570
|
{
|
|
567
571
|
let propertyType = sc.get(resourceProperty, 'type', 'text');
|
|
568
572
|
if('reference' === propertyType && 'edit' === templateType){
|
|
@@ -573,11 +577,18 @@ class RouterContents
|
|
|
573
577
|
return 'file';
|
|
574
578
|
}
|
|
575
579
|
if('view' === templateType){
|
|
580
|
+
if(!fieldValue || '' === fieldValue){
|
|
581
|
+
return 'text';
|
|
582
|
+
}
|
|
576
583
|
let multiple = resourceProperty.isArray ? 's' : '';
|
|
577
|
-
|
|
578
|
-
|
|
584
|
+
let allowedTypes = sc.get(resourceProperty, 'allowedTypes', '');
|
|
585
|
+
if('' !== allowedTypes){
|
|
586
|
+
let templateName = allowedTypes + multiple;
|
|
587
|
+
if(sc.hasOwn(this.adminFilesContents.fields.view, templateName)){
|
|
588
|
+
return templateName;
|
|
589
|
+
}
|
|
579
590
|
}
|
|
580
|
-
if('text' ===
|
|
591
|
+
if('text' === allowedTypes){
|
|
581
592
|
return 'link'+multiple
|
|
582
593
|
}
|
|
583
594
|
return 'text';
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - CMS - DynamicFormRenderer
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { Logger, sc } = require('@reldens/utils');
|
|
8
|
+
const { FileHandler } = require('@reldens/server-utils');
|
|
9
|
+
|
|
10
|
+
class DynamicFormRenderer
|
|
11
|
+
{
|
|
12
|
+
|
|
13
|
+
constructor(props)
|
|
14
|
+
{
|
|
15
|
+
this.renderEngine = sc.get(props, 'renderEngine', false);
|
|
16
|
+
this.getPartials = sc.get(props, 'getPartials', false);
|
|
17
|
+
this.projectRoot = sc.get(props, 'projectRoot', './');
|
|
18
|
+
this.templatesPath = FileHandler.joinPaths(this.projectRoot, 'templates');
|
|
19
|
+
this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
|
|
20
|
+
this.loadedTemplates = {};
|
|
21
|
+
this.events = sc.get(props, 'events', false);
|
|
22
|
+
if(!this.events){
|
|
23
|
+
Logger.error('EventsManager not provided to DynamicFormRenderer - forms functionality disabled');
|
|
24
|
+
this.isDisabled = true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async renderForm(formConfig, fieldsToRender, domain, req, attributes = {}, systemVariables = {}, enhancedData = {})
|
|
29
|
+
{
|
|
30
|
+
if(this.isDisabled){
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
await this.events.emit('reldens.dynamicFormRenderer.beforeFieldsRender', {
|
|
34
|
+
formConfig,
|
|
35
|
+
fieldsToRender,
|
|
36
|
+
domain,
|
|
37
|
+
req,
|
|
38
|
+
attributes,
|
|
39
|
+
systemVariables,
|
|
40
|
+
enhancedData
|
|
41
|
+
});
|
|
42
|
+
let formFields = await this.renderFormFields(fieldsToRender, domain, req);
|
|
43
|
+
await this.events.emit('reldens.dynamicFormRenderer.afterFieldsRender', {
|
|
44
|
+
formConfig,
|
|
45
|
+
fieldsToRender,
|
|
46
|
+
formFields,
|
|
47
|
+
domain,
|
|
48
|
+
req,
|
|
49
|
+
attributes,
|
|
50
|
+
systemVariables,
|
|
51
|
+
enhancedData
|
|
52
|
+
});
|
|
53
|
+
let formTemplate = await this.loadFormTemplate('form', domain);
|
|
54
|
+
if(!formTemplate){
|
|
55
|
+
Logger.error('Form template not found');
|
|
56
|
+
return '';
|
|
57
|
+
}
|
|
58
|
+
let messageData = this.parseFormMessages(req, attributes);
|
|
59
|
+
return this.renderEngine.render(formTemplate, Object.assign({}, enhancedData, {
|
|
60
|
+
formKey: formConfig.form_key,
|
|
61
|
+
formFields,
|
|
62
|
+
submitUrl: sc.get(attributes, 'submitUrl', '/dynamic-form'),
|
|
63
|
+
successRedirect: sc.get(attributes, 'successRedirect', '/'),
|
|
64
|
+
errorRedirect: sc.get(attributes, 'errorRedirect', '/'),
|
|
65
|
+
honeypotFieldName: sc.get(attributes, 'honeypotFieldName', 'website_url'),
|
|
66
|
+
submitButtonText: sc.get(attributes, 'submitButtonText', 'Submit'),
|
|
67
|
+
cssClass: sc.get(attributes, 'cssClass', 'dynamic-form'),
|
|
68
|
+
showSuccessMessage: messageData.showSuccessMessage,
|
|
69
|
+
successMessage: messageData.successMessage,
|
|
70
|
+
showErrorMessage: messageData.showErrorMessage,
|
|
71
|
+
errorMessage: messageData.errorMessage,
|
|
72
|
+
systemVariables
|
|
73
|
+
}), this.getPartialsForDomain(domain));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
parseFormMessages(req, attributes)
|
|
77
|
+
{
|
|
78
|
+
let queryParams = sc.get(req, 'query', {});
|
|
79
|
+
let formSuccess = sc.get(queryParams, 'form-success', '');
|
|
80
|
+
let formError = sc.get(queryParams, 'form-error', '');
|
|
81
|
+
let formKey = sc.get(queryParams, 'form-key', '');
|
|
82
|
+
let showSuccessMessage = '1' === formSuccess && '' !== formKey;
|
|
83
|
+
let showErrorMessage = '' !== formError && '' !== formKey;
|
|
84
|
+
let successMessage = sc.get(attributes, 'successMessage', 'Form submitted successfully!');
|
|
85
|
+
let errorMessage = sc.get(attributes, 'errorMessage', formError || 'There was an error submitting the form.');
|
|
86
|
+
return {
|
|
87
|
+
showSuccessMessage,
|
|
88
|
+
successMessage,
|
|
89
|
+
showErrorMessage,
|
|
90
|
+
errorMessage
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async renderFormFields(fieldsToRender, domain, req, submittedValues = {}, errors = {})
|
|
95
|
+
{
|
|
96
|
+
if(!sc.isArray(fieldsToRender) || 0 === fieldsToRender.length){
|
|
97
|
+
return '';
|
|
98
|
+
}
|
|
99
|
+
let renderedFields = '';
|
|
100
|
+
for(let field of fieldsToRender){
|
|
101
|
+
if(!sc.isObject(field)){
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
let fieldHtml = await this.renderFormField(field, domain, submittedValues, errors);
|
|
105
|
+
if(fieldHtml){
|
|
106
|
+
renderedFields += fieldHtml;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return renderedFields;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async renderFormField(field, domain, submittedValues = {}, errors = {})
|
|
113
|
+
{
|
|
114
|
+
let fieldType = sc.get(field, 'type', 'text');
|
|
115
|
+
let fieldTemplate = await this.loadFormTemplate('field_'+fieldType, domain);
|
|
116
|
+
if(!fieldTemplate){
|
|
117
|
+
fieldTemplate = await this.loadFormTemplate('field_text', domain);
|
|
118
|
+
}
|
|
119
|
+
if(!fieldTemplate){
|
|
120
|
+
Logger.error('Field template not found for type: '+fieldType);
|
|
121
|
+
return '';
|
|
122
|
+
}
|
|
123
|
+
return this.renderEngine.render(
|
|
124
|
+
fieldTemplate,
|
|
125
|
+
this.buildFieldTemplateData(field, submittedValues, errors),
|
|
126
|
+
this.getPartialsForDomain(domain)
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
buildFieldTemplateData(field, submittedValues = {}, errors = {})
|
|
131
|
+
{
|
|
132
|
+
let fieldName = sc.get(field, 'name', '');
|
|
133
|
+
let fieldType = sc.get(field, 'type', 'text');
|
|
134
|
+
let fieldLabel = sc.get(field, 'label', fieldName);
|
|
135
|
+
let fieldValue = sc.get(submittedValues, fieldName, sc.get(field, 'defaultValue', ''));
|
|
136
|
+
let isRequired = sc.get(field, 'required', false);
|
|
137
|
+
let fieldError = sc.get(errors, fieldName, '');
|
|
138
|
+
let options = sc.get(field, 'options', []);
|
|
139
|
+
if(sc.isArray(options)){
|
|
140
|
+
options = options.map(option => {
|
|
141
|
+
if(sc.isObject(option)){
|
|
142
|
+
return {
|
|
143
|
+
value: sc.get(option, 'value', ''),
|
|
144
|
+
label: sc.get(option, 'label', sc.get(option, 'value', '')),
|
|
145
|
+
selected: sc.get(option, 'value', '') === fieldValue
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
value: option,
|
|
150
|
+
label: option,
|
|
151
|
+
selected: option === fieldValue
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
field,
|
|
157
|
+
fieldName,
|
|
158
|
+
fieldType,
|
|
159
|
+
fieldLabel,
|
|
160
|
+
fieldValue,
|
|
161
|
+
isRequired,
|
|
162
|
+
fieldError,
|
|
163
|
+
hasError: '' !== fieldError,
|
|
164
|
+
requiredClass: isRequired ? 'required' : '',
|
|
165
|
+
errorClass: '' !== fieldError ? 'error' : '',
|
|
166
|
+
options,
|
|
167
|
+
placeholder: sc.get(field, 'placeholder', ''),
|
|
168
|
+
helpText: sc.get(field, 'helpText', ''),
|
|
169
|
+
maxLength: sc.get(field, 'maxLength', ''),
|
|
170
|
+
pattern: sc.get(field, 'pattern', ''),
|
|
171
|
+
min: sc.get(field, 'min', ''),
|
|
172
|
+
max: sc.get(field, 'max', ''),
|
|
173
|
+
step: sc.get(field, 'step', '')
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async loadFormTemplate(templateName, domain)
|
|
178
|
+
{
|
|
179
|
+
let cacheKey = templateName+'_'+domain;
|
|
180
|
+
if(sc.hasOwn(this.loadedTemplates, cacheKey)){
|
|
181
|
+
return this.loadedTemplates[cacheKey];
|
|
182
|
+
}
|
|
183
|
+
let templatePath = this.findFormTemplate(templateName, domain);
|
|
184
|
+
if(!templatePath){
|
|
185
|
+
Logger.warning('Form template not found: '+templateName+' for domain: '+domain);
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
let templateContent = await FileHandler.readFile(templatePath);
|
|
189
|
+
if(!templateContent){
|
|
190
|
+
Logger.error('Failed to read form template: '+templatePath);
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
this.loadedTemplates[cacheKey] = templateContent;
|
|
194
|
+
return templateContent;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
findFormTemplate(templateName, domain)
|
|
198
|
+
{
|
|
199
|
+
let filename = templateName+'.html';
|
|
200
|
+
let domainTemplatePath = FileHandler.joinPaths(this.templatesPath, 'domains', domain, 'cms_forms', filename);
|
|
201
|
+
if(FileHandler.exists(domainTemplatePath)){
|
|
202
|
+
return domainTemplatePath;
|
|
203
|
+
}
|
|
204
|
+
if(this.defaultDomain && domain !== this.defaultDomain){
|
|
205
|
+
let defaultDomainPath = FileHandler.joinPaths(this.templatesPath, 'domains', this.defaultDomain, 'cms_forms', filename);
|
|
206
|
+
if(FileHandler.exists(defaultDomainPath)){
|
|
207
|
+
return defaultDomainPath;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
let rootTemplatePath = FileHandler.joinPaths(this.templatesPath, 'cms_forms', filename);
|
|
211
|
+
if(FileHandler.exists(rootTemplatePath)){
|
|
212
|
+
return rootTemplatePath;
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
getPartialsForDomain(domain)
|
|
218
|
+
{
|
|
219
|
+
if(!this.getPartials){
|
|
220
|
+
Logger.error('getPartials function not provided to DynamicFormRenderer');
|
|
221
|
+
return {};
|
|
222
|
+
}
|
|
223
|
+
return this.getPartials(domain);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports.DynamicFormRenderer = DynamicFormRenderer;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - CMS - DynamicFormRequestHandler
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { Logger, sc } = require('@reldens/utils');
|
|
8
|
+
|
|
9
|
+
class DynamicFormRequestHandler
|
|
10
|
+
{
|
|
11
|
+
|
|
12
|
+
constructor(props)
|
|
13
|
+
{
|
|
14
|
+
this.dynamicForm = sc.get(props, 'dynamicForm', false);
|
|
15
|
+
this.contentRenderer = sc.get(props, 'contentRenderer', false);
|
|
16
|
+
this.requestProcessor = sc.get(props, 'requestProcessor', false);
|
|
17
|
+
this.cacheManager = sc.get(props, 'cacheManager', false);
|
|
18
|
+
this.enableJsonResponse = sc.get(props, 'enableJsonResponse', false);
|
|
19
|
+
this.events = sc.get(props, 'events', false);
|
|
20
|
+
if(!this.events){
|
|
21
|
+
Logger.error('EventsManager not provided to DynamicFormRequestHandler - forms functionality disabled');
|
|
22
|
+
this.isDisabled = true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async handleFormSubmission(req, res)
|
|
27
|
+
{
|
|
28
|
+
if(this.isDisabled){
|
|
29
|
+
return this.handleBadRequest(res, 'Forms functionality disabled');
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
let formKey = sc.get(req.body, 'formKey', '');
|
|
33
|
+
let submittedValues = sc.get(req.body, 'submittedValues', {});
|
|
34
|
+
if(!formKey || !submittedValues){
|
|
35
|
+
return this.handleBadRequest(res, 'Missing formKey or submittedValues');
|
|
36
|
+
}
|
|
37
|
+
await this.events.emit('reldens.dynamicFormRequestHandler.beforeValidation', {
|
|
38
|
+
formKey,
|
|
39
|
+
submittedValues,
|
|
40
|
+
req,
|
|
41
|
+
res
|
|
42
|
+
});
|
|
43
|
+
let validation = await this.dynamicForm.validateFormSubmission(formKey, submittedValues, req);
|
|
44
|
+
if(!validation.isValid){
|
|
45
|
+
return this.handleValidationError(req, res, validation.error, formKey);
|
|
46
|
+
}
|
|
47
|
+
let preparedValues = this.dynamicForm.prepareSubmittedValues(
|
|
48
|
+
submittedValues,
|
|
49
|
+
validation.formConfig.fields_schema
|
|
50
|
+
);
|
|
51
|
+
await this.events.emit('reldens.dynamicFormRequestHandler.beforeSave', {
|
|
52
|
+
formKey,
|
|
53
|
+
preparedValues,
|
|
54
|
+
formConfig: validation.formConfig,
|
|
55
|
+
req,
|
|
56
|
+
res
|
|
57
|
+
});
|
|
58
|
+
let submissionResult = await this.dynamicForm.saveFormSubmission(
|
|
59
|
+
validation.formConfig,
|
|
60
|
+
preparedValues
|
|
61
|
+
);
|
|
62
|
+
if(!submissionResult){
|
|
63
|
+
return this.handleValidationError(req, res, 'Failed to save form submission', formKey);
|
|
64
|
+
}
|
|
65
|
+
await this.events.emit('reldens.dynamicFormRequestHandler.afterSave', {
|
|
66
|
+
formKey,
|
|
67
|
+
submissionResult,
|
|
68
|
+
formConfig: validation.formConfig,
|
|
69
|
+
req,
|
|
70
|
+
res
|
|
71
|
+
});
|
|
72
|
+
return this.handleSuccessResponse(req, res, formKey, submissionResult);
|
|
73
|
+
} catch(error) {
|
|
74
|
+
Logger.error('Form submission handling error: '+error.message);
|
|
75
|
+
return this.handleBadRequest(res, 'Internal server error');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
handleBadRequest(res, message)
|
|
80
|
+
{
|
|
81
|
+
if(this.enableJsonResponse){
|
|
82
|
+
return res.status(400).json({
|
|
83
|
+
success: false,
|
|
84
|
+
error: message
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return res.status(400).send('Bad Request: '+message);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
handleValidationError(req, res, error, formKey)
|
|
91
|
+
{
|
|
92
|
+
if(this.enableJsonResponse){
|
|
93
|
+
return res.status(400).json({
|
|
94
|
+
success: false,
|
|
95
|
+
error: error,
|
|
96
|
+
formKey: formKey
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return res.redirect(this.buildErrorRedirectPath(req, error, formKey));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
handleSuccessResponse(req, res, formKey, submissionResult)
|
|
103
|
+
{
|
|
104
|
+
if(this.enableJsonResponse){
|
|
105
|
+
return res.json({
|
|
106
|
+
success: true,
|
|
107
|
+
message: 'Form submitted successfully',
|
|
108
|
+
formKey: formKey,
|
|
109
|
+
submissionId: submissionResult.id
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return res.redirect(this.buildSuccessRedirectPath(sc.get(req.body, 'successRedirect', '/'), formKey));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
buildErrorRedirectPath(req, error, formKey)
|
|
116
|
+
{
|
|
117
|
+
let baseRedirect = sc.get(req.body, 'errorRedirect', '/');
|
|
118
|
+
let finalRedirect = sc.get(req.headers, 'referer', baseRedirect) || baseRedirect;
|
|
119
|
+
return finalRedirect
|
|
120
|
+
+(finalRedirect.includes('?') ? '&' : '?')
|
|
121
|
+
+'form-error='+encodeURIComponent(error)
|
|
122
|
+
+'&form-key='+encodeURIComponent(formKey);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
buildSuccessRedirectPath(successRedirect, formKey)
|
|
126
|
+
{
|
|
127
|
+
return successRedirect
|
|
128
|
+
+(successRedirect.includes('?') ? '&' : '?')
|
|
129
|
+
+'form-success=1'
|
|
130
|
+
+'&form-key='+encodeURIComponent(formKey);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports.DynamicFormRequestHandler = DynamicFormRequestHandler;
|