Browse Source

Commented custom fields

Brendan Abolivier 7 years ago
parent
commit
70e6db6248
Signed by: Brendan Abolivier <contact@brendanabolivier.com> GPG key ID: 8EF1500759F70623
2 changed files with 62 additions and 14 deletions
  1. 46
    11
      front/form.js
  2. 16
    3
      server.js

+ 46
- 11
front/form.js View File

105
     var status = document.createElement('p');
105
     var status = document.createElement('p');
106
     status.setAttribute('id', 'form_status');
106
     status.setAttribute('id', 'form_status');
107
     el.appendChild(status);
107
     el.appendChild(status);
108
-    
108
+
109
+    // Default fields
109
     DOMFields = {
110
     DOMFields = {
110
         name: getField({
111
         name: getField({
111
             name: items.name,
112
             name: items.name,
130
     };
131
     };
131
     
132
     
132
     // Adding custom fields
133
     // Adding custom fields
133
-    
134
     for(let fieldName in customFields) {
134
     for(let fieldName in customFields) {
135
         let field = customFields[fieldName];
135
         let field = customFields[fieldName];
136
         DOMFields[fieldName] = getField(field, NOT_REQUIRED);
136
         DOMFields[fieldName] = getField(field, NOT_REQUIRED);
137
     }
137
     }
138
     
138
     
139
-    // Adding nodes to document
140
-
139
+    // Adding all nodes to document
141
     for(let field in DOMFields) {
140
     for(let field in DOMFields) {
142
         el.appendChild(DOMFields[field]);
141
         el.appendChild(DOMFields[field]);
143
     }
142
     }
144
 
143
 
145
     // Adding submit button
144
     // Adding submit button
146
-    
147
     el.appendChild(getSubmitButton('form_subm', lang.form_subm_label));
145
     el.appendChild(getSubmitButton('form_subm', lang.form_subm_label));
148
     
146
     
149
     // Retrieve the token from the server
147
     // Retrieve the token from the server
150
-    
151
     getToken();
148
     getToken();
152
 }
149
 }
153
 
150
 
154
 
151
 
152
+// Get the HTML element for a given field
153
+// fieldInfos: object describing the field
154
+// required: boolean on whether the field is required or optional
155
+// return: a block containing the field and a label describing it (if enabled)
155
 function getField(fieldInfos, required) {
156
 function getField(fieldInfos, required) {
156
     var block = document.createElement('div');
157
     var block = document.createElement('div');
157
-    
158
     block.setAttribute('id', fieldInfos.name);
158
     block.setAttribute('id', fieldInfos.name);
159
-    
159
+
160
+    // Declare the variable first
160
     let field = {};
161
     let field = {};
161
-    
162
+
163
+    // Easily add new supported input types
162
     switch(fieldInfos.type) {
164
     switch(fieldInfos.type) {
163
         case 'text':        field = getTextField(fieldInfos, required);
165
         case 'text':        field = getTextField(fieldInfos, required);
164
                             break;
166
                             break;
170
                             break;
172
                             break;
171
     }
173
     }
172
 
174
 
175
+    // We need the input field's ID to bind it to the label, so we generate the
176
+    // field first
173
     if(labels) {
177
     if(labels) {
174
         block.appendChild(getLabel(fieldInfos.label, field.id));
178
         block.appendChild(getLabel(fieldInfos.label, field.id));
175
     }
179
     }
176
-
177
-    block.appendChild(field);
178
     
180
     
181
+    // Assemble the block and return it
182
+    block.appendChild(field);
179
     return block;
183
     return block;
180
 }
184
 }
181
 
185
 
194
 }
198
 }
195
 
199
 
196
 
200
 
201
+// Returns a <select> HTML element
202
+// fieldInfos: object describing the field
203
+// required: boolean on whether the field is required or optional
204
+// return: a <select> element corresponding to the info passed as input
197
 function getSelectField(fieldInfos, required) {
205
 function getSelectField(fieldInfos, required) {
198
     let field = document.createElement('select');
206
     let field = document.createElement('select');
199
 
207
 
208
+    // Set attributes when necessary
200
     if(required) {
209
     if(required) {
201
         field.setAttribute('required', 'required');
210
         field.setAttribute('required', 'required');
202
     }
211
     }
207
     // Add all options to select
216
     // Add all options to select
208
     for(let choice of fieldInfos.options) {
217
     for(let choice of fieldInfos.options) {
209
         let option = document.createElement('option');
218
         let option = document.createElement('option');
219
+        // Options' values are incremental numeric indexes
210
         option.setAttribute('value', index);
220
         option.setAttribute('value', index);
221
+        // Set the value defined by the user
211
         option.innerHTML = choice;
222
         option.innerHTML = choice;
212
         field.appendChild(option);
223
         field.appendChild(option);
224
+        // Increment the index
213
         index++;
225
         index++;
214
     }
226
     }
215
 
227
 
217
 }
229
 }
218
 
230
 
219
 
231
 
232
+// Returns a <input> HTML element with 'text' type
233
+// fieldInfos: object describing the field
234
+// required: boolean on whether the field is required or optional
235
+// return: a <input> HTML element corresponding to the info passed as input
220
 function getTextField(fieldInfos, required) {
236
 function getTextField(fieldInfos, required) {
221
     return getBaseInputField(fieldInfos, required, 'text');
237
     return getBaseInputField(fieldInfos, required, 'text');
222
 }
238
 }
223
 
239
 
224
 
240
 
241
+// Returns a <input> HTML element with 'email' type
242
+// fieldInfos: object describing the field
243
+// required: boolean on whether the field is required or optional
244
+// return: a <input> HTML element corresponding to the info passed as input
225
 function getEmailField(fieldInfos, required) {
245
 function getEmailField(fieldInfos, required) {
226
     return getBaseInputField(fieldInfos, required, 'email');
246
     return getBaseInputField(fieldInfos, required, 'email');
227
 }
247
 }
228
 
248
 
229
 
249
 
250
+// Returns a basic <input> HTML element with generic info to be processed by
251
+// functions at higher level
252
+// fieldInfos: object describing the field
253
+// required: boolean on whether the field is required or optional
254
+// return: a basic <input> HTML element with generic info
230
 function getBaseInputField(fieldInfos, required, type) {
255
 function getBaseInputField(fieldInfos, required, type) {
231
     let field = getBaseField(fieldInfos, required, 'input')
256
     let field = getBaseField(fieldInfos, required, 'input')
232
     field.setAttribute('type', type);
257
     field.setAttribute('type', type);
234
 }
259
 }
235
 
260
 
236
 
261
 
262
+// Returns a <textarea> HTML element
263
+// fieldInfos: object describing the field
264
+// required: boolean on whether the field is required or optional
265
+// return: a <textarea> element corresponding to the info passed as input
237
 function getTextarea(fieldInfos, required) {
266
 function getTextarea(fieldInfos, required) {
238
     return getBaseField(fieldInfos, required, 'textarea');
267
     return getBaseField(fieldInfos, required, 'textarea');
239
 }
268
 }
240
 
269
 
241
 
270
 
271
+// Returns a base HTML element with generic info to be processed by functions at 
272
+// higher level
273
+// fieldInfos: object describing the field
274
+// required: boolean on whether the field is required or optional
275
+// tag: the HTML tag the field element must have
276
+// return: a HTML element of the given tag with basic info given as input
242
 function getBaseField(fieldInfos, required, tag) {
277
 function getBaseField(fieldInfos, required, tag) {
243
     let field = document.createElement(tag);
278
     let field = document.createElement(tag);
244
     
279
     

+ 16
- 3
server.js View File

77
     
77
     
78
     let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
78
     let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
79
     
79
     
80
+    // Token verification
80
     if(!checkToken(ip, req.body.token)) {
81
     if(!checkToken(ip, req.body.token)) {
81
         return res.status(403).send();
82
         return res.status(403).send();
82
     }
83
     }
97
         html: req.body.text
98
         html: req.body.text
98
     };
99
     };
99
 
100
 
101
+    // Process custom fields to get data we can use in the HTML generation
100
     params.custom = processCustom(req.body.custom);
102
     params.custom = processCustom(req.body.custom);
101
     
103
     
102
     // Replacing the mail's content with HTML from the pug template
104
     // Replacing the mail's content with HTML from the pug template
283
 }
285
 }
284
 
286
 
285
 
287
 
288
+// Process custom fields to something usable in the HTML generation
289
+// For example, this function replaces indexes with answers in select fields
290
+// custom: object describing data from custom fields
291
+// return: an object with user-input data from each field:
292
+// {
293
+//      field name: {
294
+//          value: String,
295
+//          label: String
296
+//      }
297
+// }
286
 function processCustom(custom) {
298
 function processCustom(custom) {
287
     let fields = {};
299
     let fields = {};
288
-    
300
+
301
+    // Process each field
289
     for(let field in custom) {
302
     for(let field in custom) {
290
         let type = settings.customFields[field].type;
303
         let type = settings.customFields[field].type;
291
-
304
+        // Match indexes with data when needed
292
         switch(type) {
305
         switch(type) {
293
             case 'select':  custom[field] = settings.customFields[field]
306
             case 'select':  custom[field] = settings.customFields[field]
294
                                             .options[custom[field]];
307
                                             .options[custom[field]];
295
                             break;
308
                             break;
296
         }
309
         }
297
-
310
+        // Insert data into the finale object
298
         fields[field] = {
311
         fields[field] = {
299
             value: custom[field],
312
             value: custom[field],
300
             label: settings.customFields[field].label
313
             label: settings.customFields[field].label