Bladeren bron

Allow a custom field to be required

Brendan Abolivier 8 jaren geleden
bovenliggende
commit
d9373c4686
Getekend door: Brendan Abolivier <contact@brendanabolivier.com> GPG key ID: 8EF1500759F70623
4 gewijzigde bestanden met toevoegingen van 65 en 57 verwijderingen
  1. 32
    45
      front/form.js
  2. 1
    0
      locales/en.json
  3. 1
    0
      locales/fr.json
  4. 31
    12
      server.js

+ 32
- 45
front/form.js Bestand weergeven

1
-// Consts for readability
2
-const REQUIRED		= true;
3
-const NOT_REQUIRED  = false;
4
-
5
-
6
 var prefix = 'form'
1
 var prefix = 'form'
7
 
2
 
8
 var items = {
3
 var items = {
111
 		name: getField({
106
 		name: getField({
112
 			name: items.name,
107
 			name: items.name,
113
 			label: lang.form_name_label,
108
 			label: lang.form_name_label,
114
-			type: 'text'
115
-		}, REQUIRED),
109
+			type: 'text',
110
+			required: true
111
+		}),
116
 		addr: getField({
112
 		addr: getField({
117
 			name: items.addr,
113
 			name: items.addr,
118
 			label: lang.form_addr_label,
114
 			label: lang.form_addr_label,
119
-			type: 'email'
120
-		}, REQUIRED),
115
+			type: 'email',
116
+			required: true
117
+		}),
121
 		subj: getField({
118
 		subj: getField({
122
 			name: items.subj,
119
 			name: items.subj,
123
 			label: lang.form_subj_label,
120
 			label: lang.form_subj_label,
124
-			type: 'text'
125
-		}, REQUIRED),
121
+			type: 'text',
122
+			required: true
123
+		}),
126
 		text: getField({
124
 		text: getField({
127
 			name: items.text,
125
 			name: items.text,
128
 			label: lang.form_mesg_label,
126
 			label: lang.form_mesg_label,
129
-			type: 'textarea'
130
-		}, REQUIRED)
127
+			type: 'textarea',
128
+			required: true
129
+		})
131
 	};
130
 	};
132
 	
131
 	
133
 	// Adding custom fields
132
 	// Adding custom fields
134
 	for(let fieldName in customFields) {
133
 	for(let fieldName in customFields) {
135
 		let field = customFields[fieldName];
134
 		let field = customFields[fieldName];
136
-		DOMFields[fieldName] = getField(field, NOT_REQUIRED);
135
+		DOMFields[fieldName] = getField(field);
137
 	}
136
 	}
138
 	
137
 	
139
 	// Adding all nodes to document
138
 	// Adding all nodes to document
153
 // fieldInfos: object describing the field
152
 // fieldInfos: object describing the field
154
 // required: boolean on whether the field is required or optional
153
 // required: boolean on whether the field is required or optional
155
 // return: a block containing the field and a label describing it (if enabled)
154
 // return: a block containing the field and a label describing it (if enabled)
156
-function getField(fieldInfos, required) {
155
+function getField(fieldInfos) {
157
 	var block = document.createElement('div');
156
 	var block = document.createElement('div');
158
 	block.setAttribute('id', fieldInfos.name);
157
 	block.setAttribute('id', fieldInfos.name);
159
 
158
 
162
 
161
 
163
 	// Easily add new supported input types
162
 	// Easily add new supported input types
164
 	switch(fieldInfos.type) {
163
 	switch(fieldInfos.type) {
165
-		case 'text':		field = getTextField(fieldInfos, required);
164
+		case 'textarea':	field = getTextarea(fieldInfos);
166
 							break;
165
 							break;
167
-		case 'textarea':	field = getTextarea(fieldInfos, required);
166
+		case 'select':		field = getSelectField(fieldInfos);
168
 							break;
167
 							break;
169
-		case 'email':	   field = getEmailField(fieldInfos, required);
170
-							break;
171
-		case 'select':	  field = getSelectField(fieldInfos, required);
168
+		default:			field = getInputField(fieldInfos);
172
 							break;
169
 							break;
173
 	}
170
 	}
174
 
171
 
202
 // fieldInfos: object describing the field
199
 // fieldInfos: object describing the field
203
 // required: boolean on whether the field is required or optional
200
 // required: boolean on whether the field is required or optional
204
 // return: a <select> element corresponding to the info passed as input
201
 // return: a <select> element corresponding to the info passed as input
205
-function getSelectField(fieldInfos, required) {
202
+function getSelectField(fieldInfos) {
206
 	let field = document.createElement('select');
203
 	let field = document.createElement('select');
207
 
204
 
208
 	// Set attributes when necessary
205
 	// Set attributes when necessary
209
-	if(required) {
206
+	if(fieldInfos.required) {
210
 		field.setAttribute('required', 'required');
207
 		field.setAttribute('required', 'required');
211
 	}
208
 	}
212
 	field.setAttribute('id', prefix + '_' + fieldInfos.name + '_select');
209
 	field.setAttribute('id', prefix + '_' + fieldInfos.name + '_select');
213
 
210
 
214
 	let index = 0;
211
 	let index = 0;
215
 	
212
 	
213
+	// Add header option, useful if the field is required
214
+	let header = document.createElement('option');
215
+	// The value must be an empty string so the browser can block the submit
216
+	// event if the field is required
217
+	header.setAttribute('value', '');
218
+	header.innerHTML = lang.form_select_header_option;
219
+	field.appendChild(header);
220
+	
216
 	// Add all options to select
221
 	// Add all options to select
217
 	for(let choice of fieldInfos.options) {
222
 	for(let choice of fieldInfos.options) {
218
 		let option = document.createElement('option');
223
 		let option = document.createElement('option');
229
 }
234
 }
230
 
235
 
231
 
236
 
232
-// Returns a <input> HTML element with 'text' type
237
+// Returns a <input> HTML element with desired type
233
 // fieldInfos: object describing the field
238
 // fieldInfos: object describing the field
234
 // required: boolean on whether the field is required or optional
239
 // required: boolean on whether the field is required or optional
240
+// type: type of the input field (text, email, date...)
235
 // return: a <input> HTML element corresponding to the info passed as input
241
 // return: a <input> HTML element corresponding to the info passed as input
236
-function getTextField(fieldInfos, required) {
237
-	return getBaseInputField(fieldInfos, required, 'text');
238
-}
239
-
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
245
-function getEmailField(fieldInfos, required) {
246
-	return getBaseInputField(fieldInfos, required, 'email');
247
-}
248
-
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
255
-function getBaseInputField(fieldInfos, required, type) {
242
+function getInputField(fieldInfos, required) {
256
 	let field = getBaseField(fieldInfos, required, 'input')
243
 	let field = getBaseField(fieldInfos, required, 'input')
257
-	field.setAttribute('type', type);
244
+	field.setAttribute('type', fieldInfos.type);
258
 	return field;
245
 	return field;
259
 }
246
 }
260
 
247
 
277
 function getBaseField(fieldInfos, required, tag) {
264
 function getBaseField(fieldInfos, required, tag) {
278
 	let field = document.createElement(tag);
265
 	let field = document.createElement(tag);
279
 	
266
 	
280
-	if(required) {
267
+	if(fieldInfos.required) {
281
 		field.setAttribute('required', 'required');
268
 		field.setAttribute('required', 'required');
282
 	}
269
 	}
283
 	field.setAttribute('placeholder', fieldInfos.label);
270
 	field.setAttribute('placeholder', fieldInfos.label);

+ 1
- 0
locales/en.json Bestand weergeven

5
         "form_subj_label": "Your message's subject",
5
         "form_subj_label": "Your message's subject",
6
         "form_mesg_label": "Your message",
6
         "form_mesg_label": "Your message",
7
         "form_subm_label": "Send the mail",
7
         "form_subm_label": "Send the mail",
8
+		"form_select_header_option": "Select an answer",
8
         "send_status_success": "Your message has been sent.",
9
         "send_status_success": "Your message has been sent.",
9
         "send_status_failure": "An error happened while sending your message, please retry later.",
10
         "send_status_failure": "An error happened while sending your message, please retry later.",
10
         "send_status_progress": "Sending the e-mail"
11
         "send_status_progress": "Sending the e-mail"

+ 1
- 0
locales/fr.json Bestand weergeven

5
         "form_subj_label": "Sujet de votre message",
5
         "form_subj_label": "Sujet de votre message",
6
         "form_mesg_label": "Votre message",
6
         "form_mesg_label": "Votre message",
7
         "form_subm_label": "Envoyer",
7
         "form_subm_label": "Envoyer",
8
+		"form_select_header_option": "Sélectionnez une réponse",
8
         "send_status_success": "Votre message a été envoyé.",
9
         "send_status_success": "Votre message a été envoyé.",
9
         "send_status_failure": "Une erreur est survenue lors de l'envoi du message, merci de réessayer plus tard.",
10
         "send_status_failure": "Une erreur est survenue lors de l'envoi du message, merci de réessayer plus tard.",
10
         "send_status_progress": "Envoi du message en cours"
11
         "send_status_progress": "Envoi du message en cours"

+ 31
- 12
server.js Bestand weergeven

252
 // body: body taken from express's request object
252
 // body: body taken from express's request object
253
 // return: true if the body is valid, false else
253
 // return: true if the body is valid, false else
254
 function checkBody(body) {
254
 function checkBody(body) {
255
-	let valid = false;
256
-	
257
-	if(body.token !== undefined && body.subj !== undefined 
258
-		&& body.name !== undefined && body.addr !== undefined 
259
-		&& body.text !== undefined) {
260
-		valid = true;
255
+	// Check default fields
256
+	if(isInvalid(body.token) || isInvalid(body.subj) || isInvalid(body.name) 
257
+		|| isInvalid(body.addr) || isInvalid(body.text)) {
258
+		return false;
261
 	}
259
 	}
262
-	
263
-	return valid;
260
+
261
+	// Checking required custom fields
262
+	for(let field in settings.customFields) {
263
+		// No need to check the field if its not required in the settings
264
+		if(settings.customFields[field].required) {
265
+			if(isInvalid(body.custom[field])) {
266
+				return false;
267
+			}
268
+		}
269
+	}
270
+
271
+	return true;
264
 }
272
 }
265
 
273
 
266
 
274
 
275
+// Checks if the field is invalid. A field is considered as invalid if undefined
276
+// or is an empty string
277
+// field: user-input value of the field
278
+// return: true if the field is valid, false if not
279
+function isInvalid(field) {
280
+	return (field === undefined || field.length == 0);
281
+}
282
+
267
 // Checks the tokens object to see if no token has expired
283
 // Checks the tokens object to see if no token has expired
268
 // return: nothing
284
 // return: nothing
269
 function cleanTokens() {
285
 function cleanTokens() {
307
 											.options[custom[field]];
323
 											.options[custom[field]];
308
 							break;
324
 							break;
309
 		}
325
 		}
310
-		// Insert data into the finale object
311
-		fields[field] = {
312
-			value: custom[field],
313
-			label: settings.customFields[field].label
326
+
327
+		// Insert data into the final object if the value is set
328
+		if(!isInvalid(custom[field])) {
329
+			fields[field] = {
330
+				value: custom[field],
331
+				label: settings.customFields[field].label
332
+			}
314
 		}
333
 		}
315
 	}
334
 	}
316
 	
335