1
|
|
|
/* |
2
|
|
|
* Copyright (c) 2018. JAGFx |
3
|
|
|
* @author: SMITH Emmanuel |
4
|
|
|
* @version: 2.0.0 |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
(function ( $ ) { |
8
|
|
|
$.fn.formJS = function ( options ) { |
9
|
|
|
var obj = this; |
10
|
|
|
|
11
|
|
|
var settings = $.extend( { |
12
|
|
|
alerts: { |
13
|
|
|
unexpected: { |
14
|
|
|
title: 'Error', |
15
|
|
|
message: 'Unexpected error occurred' |
16
|
|
|
}, |
17
|
|
|
failSend: { |
18
|
|
|
title: 'Error', |
19
|
|
|
message: 'Unable to send data' |
20
|
|
|
} |
21
|
|
|
}, |
22
|
|
|
keys: { |
23
|
|
|
success: 'success', |
24
|
|
|
info: 'info', |
25
|
|
|
warning: 'warning', |
26
|
|
|
error: 'danger' |
27
|
|
|
}, |
28
|
|
|
icons: { |
29
|
|
|
loading: '<span class="fas fa-circle-notch fa-spin"></span>', |
30
|
|
|
success: '<span class="fas fa-check"></span>', |
31
|
|
|
info: '<span class="fas fa-info"></span>', |
32
|
|
|
warning: '<span class="fas fa-exclamation-triangle"></span>', |
33
|
|
|
error: '<span class="fas fa-fire"></span>' |
34
|
|
|
}, |
35
|
|
|
form: { |
36
|
|
|
ajaxSettings: { |
37
|
|
|
contentType: false |
38
|
|
|
}, |
39
|
|
|
alertContainer: '.formJS' |
40
|
|
|
}, |
41
|
|
|
redirection: { |
42
|
|
|
message: 'Automatic redirection in a second', |
43
|
|
|
delay: 1100 |
44
|
|
|
}, |
45
|
|
|
btnSubmit: '.btn[type="submit"]', |
46
|
|
|
callback: function () { |
47
|
|
|
} |
48
|
|
|
}, options ); |
49
|
|
|
|
50
|
|
|
obj.each( function () { |
51
|
|
|
var $this = $( this ); |
52
|
|
|
var action = $this.attr( "action" ); |
53
|
|
|
var method = $this.attr( "method" ); |
54
|
|
|
var btnSubmit = $this.find( settings.btnSubmit ); |
55
|
|
|
var currentAlert = $.extend( settings.alerts.unexpected, { type: 'error' } ); |
56
|
|
|
var ajaxPending = false; |
57
|
|
|
var formdata; |
58
|
|
|
var data; |
59
|
|
|
var ajaxSettings; |
60
|
|
|
|
61
|
|
|
$this.submit( function ( e ) { |
62
|
|
|
e.preventDefault(); |
63
|
|
|
|
64
|
|
|
if ( ajaxPending === false ) |
65
|
|
|
ajaxPending = true; |
|
|
|
|
66
|
|
|
|
67
|
|
|
else return; |
68
|
|
|
|
69
|
|
|
try { |
70
|
|
|
if ( btnSubmit.length === 0 ) |
71
|
|
|
throw 'Unable to find submit button'; |
|
|
|
|
72
|
|
|
|
73
|
|
|
btnSubmit |
74
|
|
|
.append( $( settings.icons.loading ).addClass( 'formJS-loading' ) ) |
75
|
|
|
.attr( 'disabled' ); |
76
|
|
|
|
77
|
|
|
btnSubmit.addClass( 'disabled' ); |
78
|
|
|
|
79
|
|
|
if ( method == "" || method == null ) { |
|
|
|
|
80
|
|
|
throw 'Undefined method of form'; |
81
|
|
|
|
82
|
|
|
} else { |
|
|
|
|
83
|
|
|
formdata = (window.FormData) ? new FormData( $this[ 0 ] ) : null; |
84
|
|
|
data = (formdata !== null) ? formdata : $this.serialize(); |
85
|
|
|
ajaxSettings = $.extend( settings.form.ajaxSettings, { |
86
|
|
|
url: action, |
87
|
|
|
type: method, |
88
|
|
|
data: data, |
89
|
|
|
processData: false |
90
|
|
|
} ); |
91
|
|
|
|
92
|
|
|
$.ajax( ajaxSettings ) |
93
|
|
|
.done( function ( feedback ) { |
94
|
|
|
try { |
95
|
|
|
// If no feedback found, write unexpected alert |
96
|
|
|
if ( feedback.length === 0 ) { |
97
|
|
|
throw 'No data found on response' |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
var feedbackData = $.parseJSON( feedback ); |
101
|
|
|
var notif = ""; |
102
|
|
|
|
103
|
|
|
$this.checkFeedbackStructure( feedbackData ); |
104
|
|
|
|
105
|
|
|
//console.log( currentAlert ); |
106
|
|
|
|
107
|
|
|
// Redirection si type = "success" et si une Url est spécifié |
108
|
|
|
if ( feedbackData.type === settings.keys.success && feedbackData.hasOwnProperty( 'url' ) ) { |
109
|
|
|
|
110
|
|
|
notif = ' - ' + settings.redirection.message; |
111
|
|
|
setTimeout( function () { |
112
|
|
|
window.location.replace( feedbackData.url ); |
113
|
|
|
}, settings.redirection.delay ); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
// Affichage de l'alert |
117
|
|
|
currentAlert.type = feedbackData.type; |
118
|
|
|
currentAlert.title = feedbackData.data.title; |
119
|
|
|
currentAlert.message = feedbackData.data.message + notif; |
120
|
|
|
|
121
|
|
|
} catch ( error ) { |
122
|
|
|
console.error( '[FormJS] ' + error ); |
123
|
|
|
} |
124
|
|
|
} ) |
125
|
|
|
.fail( function ( error ) { |
126
|
|
|
console.error( error ); |
127
|
|
|
} ) |
128
|
|
|
.always( function () { |
129
|
|
|
//console.log( currentAlert ); |
130
|
|
|
$this.writeAlert(); |
131
|
|
|
} ); |
132
|
|
|
} |
133
|
|
|
} catch ( error ) { |
134
|
|
|
console.error( '[FormJS] ' + error ); |
135
|
|
|
$this.writeAlert(); |
136
|
|
|
} |
137
|
|
|
} ); |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Check the structure of feedback response |
141
|
|
|
* @param inputData |
142
|
|
|
*/ |
143
|
|
|
$this.checkFeedbackStructure = function ( inputData ) { |
144
|
|
|
var feedbackStructure = { |
|
|
|
|
145
|
|
|
type: '', |
146
|
|
|
url: '', |
147
|
|
|
data: { |
148
|
|
|
title: '', |
149
|
|
|
message: '' |
150
|
|
|
} |
151
|
|
|
}; |
152
|
|
|
|
153
|
|
|
if ( !inputData.hasOwnProperty( 'type' ) ) |
154
|
|
|
throw 'Invalid feedback structure: "type" missing'; |
|
|
|
|
155
|
|
|
|
156
|
|
|
if ( !inputData.hasOwnProperty( 'data' ) ) |
157
|
|
|
throw 'Invalid feedback structure: "data" missing'; |
|
|
|
|
158
|
|
|
|
159
|
|
|
if ( !inputData.data.hasOwnProperty( 'title' ) ) |
160
|
|
|
throw 'Invalid feedback structure: "data.title" missing'; |
|
|
|
|
161
|
|
|
|
162
|
|
|
if ( !inputData.data.hasOwnProperty( 'message' ) ) |
163
|
|
|
throw 'Invalid feedback structure: "data.message" missing'; |
|
|
|
|
164
|
|
|
|
165
|
|
|
if ( Object.keys( settings.keys ).indexOf( inputData.type ) === -1 ) |
166
|
|
|
throw 'Invalid feedback structure: "type" wrong. Accepted values: ' + Object.keys( settings.keys ).toString(); |
|
|
|
|
167
|
|
|
}; |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* Create DOM alert |
171
|
|
|
*/ |
172
|
|
|
$this.writeAlert = function () { |
173
|
|
|
var alert = $( '<div class="alert formjs-' + currentAlert.type + '" role="alert" />' ) |
174
|
|
|
.html( '<div class="ico">\n\ |
175
|
|
|
' + settings.icons[ currentAlert.type ] + '\n\ |
176
|
|
|
</div>\n\ |
177
|
|
|
<div class="info">\n\ |
178
|
|
|
<h4>' + currentAlert.title + '</h4>\n\ |
179
|
|
|
<p>' + currentAlert.message + '</p>\n\ |
180
|
|
|
</div>' ) |
181
|
|
|
.hide() |
182
|
|
|
.fadeIn( 300 ); |
183
|
|
|
|
184
|
|
|
$( settings.form.alertContainer ) |
185
|
|
|
.empty() |
186
|
|
|
.html( alert ); |
187
|
|
|
|
188
|
|
|
$( 'html, body' ).animate( { |
189
|
|
|
scrollTop: $( settings.form.alertContainer ).offset().top - 55 |
190
|
|
|
}, 300 ); |
191
|
|
|
|
192
|
|
|
var btnSubmit = $( settings.btnSubmit ); |
193
|
|
|
if ( btnSubmit !== undefined && btnSubmit.length ) { |
194
|
|
|
//console.log(btnSender); |
195
|
|
|
btnSubmit |
196
|
|
|
.find( '.formJS-loading' ) |
197
|
|
|
.remove(); |
198
|
|
|
|
199
|
|
|
btnSubmit.removeClass( 'disabled' ); |
200
|
|
|
|
201
|
|
|
ajaxPending = false; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
if ( currentAlert.type === settings.keys.success || currentAlert.type === settings.keys.info ) |
205
|
|
|
console.log( currentAlert.title + " - " + currentAlert.message ); |
|
|
|
|
206
|
|
|
|
207
|
|
|
else if ( currentAlert.type === settings.keys.error ) |
208
|
|
|
console.error( currentAlert.title + " - " + currentAlert.message ); |
|
|
|
|
209
|
|
|
|
210
|
|
|
else if ( currentAlert.type === settings.keys.warning ) |
211
|
|
|
console.warn( currentAlert.title + " - " + currentAlert.message ); |
|
|
|
|
212
|
|
|
|
213
|
|
|
else |
214
|
|
|
console.log( currentAlert.title + " - " + currentAlert.message ); |
215
|
|
|
|
216
|
|
|
settings.callback(); |
217
|
|
|
}; |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Create the container if it not found |
221
|
|
|
*/ |
222
|
|
|
$this.init = function () { |
223
|
|
|
var container = $this.find( settings.form.alertContainer ); |
224
|
|
|
|
225
|
|
|
if ( container.length === 0 ) { |
226
|
|
|
var $el = $( '<div/>' ); |
227
|
|
|
var props = settings.form.alertContainer.split( '.' ), |
228
|
|
|
newelement = $el, |
229
|
|
|
id = '', |
230
|
|
|
className = ''; |
231
|
|
|
$.each( props, function ( i, val ) { |
232
|
|
|
if ( val.indexOf( '#' ) >= 0 ) { |
233
|
|
|
id += val.replace( /^#/, '' ); |
234
|
|
|
} else { |
235
|
|
|
className += val + ' '; |
236
|
|
|
} |
237
|
|
|
} ); |
238
|
|
|
|
239
|
|
|
if ( id.length ) newelement.attr( 'id', id ); |
|
|
|
|
240
|
|
|
if ( className.length ) newelement.attr( 'class', className.trim() ); |
|
|
|
|
241
|
|
|
|
242
|
|
|
$this.prepend( newelement ); |
243
|
|
|
} |
244
|
|
|
}; |
245
|
|
|
|
246
|
|
|
$this.init(); |
247
|
|
|
} ); |
248
|
|
|
|
249
|
|
|
return obj; |
250
|
|
|
}; |
251
|
|
|
|
252
|
|
|
|
253
|
|
|
$.fn.setDisplayForm = function () { |
254
|
|
|
var disp = ($( window ).width() <= 768) ? "block" : "flex"; |
255
|
|
|
$( this ).css( "display", disp ); |
256
|
|
|
|
257
|
|
|
return this; |
258
|
|
|
}; |
259
|
|
|
|
260
|
|
|
|
261
|
|
|
/*$( "form:not(.noForm)" ).submit( function ( e ) { |
262
|
|
|
var $this = $( this ); |
263
|
|
|
var action = $this.attr( "action" ); |
264
|
|
|
var method = $this.attr( "method" ); |
265
|
|
|
var callback = $this.data( 'callback' ); |
266
|
|
|
var btnSubmit = $this.find( ".btn[type=\"submit\"]" ); |
267
|
|
|
var formdata; |
268
|
|
|
var data; |
269
|
|
|
var alert = { |
270
|
|
|
type: "danger", |
271
|
|
|
titre: "Erreur", |
272
|
|
|
msg: "Une erreur inconnue s'est produite." |
273
|
|
|
}; |
274
|
|
|
|
275
|
|
|
//console.log(e.currentTarget); |
276
|
|
|
|
277
|
|
|
if ( $this.attr( "data-preventDefault" ) !== "yes" ) |
278
|
|
|
return e; |
279
|
|
|
else { |
280
|
|
|
e.preventDefault(); |
281
|
|
|
|
282
|
|
|
btnSubmit |
283
|
|
|
.html( btnSubmit.html() + ' <span class="fa fa-circle-o-notch fa-spin"></span>' ) |
284
|
|
|
.attr( "disabled" ); |
285
|
|
|
//console.log(btnSubmit.html()); |
286
|
|
|
|
287
|
|
|
//console.log($this.serialize()); |
288
|
|
|
if ( method == "" || method == null ) { |
289
|
|
|
alert.type = "error"; |
290
|
|
|
alert.titre = "Erreur fatale"; |
291
|
|
|
alert.msg = "Formulaire - Méthode non spécifié"; |
292
|
|
|
writeAlert( $this, alert, btnSubmit ); |
293
|
|
|
} |
294
|
|
|
else { |
295
|
|
|
|
296
|
|
|
formdata = (window.FormData) ? new FormData( $this[ 0 ] ) : null; |
297
|
|
|
data = (formdata !== null) ? formdata : $this.serialize(); |
298
|
|
|
|
299
|
|
|
$.ajax( { |
300
|
|
|
url: action, |
301
|
|
|
type: method, |
302
|
|
|
data: data, |
303
|
|
|
contentType: false, |
304
|
|
|
processData: false, |
305
|
|
|
success: function ( retour ) { |
306
|
|
|
//console.log(retour); |
307
|
|
|
if ( retour == '' ) { |
308
|
|
|
writeAlert( $this, alert, btnSubmit ); |
309
|
|
|
return; |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
var dataRetour = $.parseJSON( retour ); |
313
|
|
|
var notif = ""; |
314
|
|
|
//console.log(dataRetour); |
315
|
|
|
|
316
|
|
|
// Le Type doit strictement être parmis "success", "warning" et "danger" |
317
|
|
|
if ( dataRetour.Type === "success" |
318
|
|
|
|| dataRetour.Type === "warning" |
319
|
|
|
|| dataRetour.Type === "danger" |
320
|
|
|
|| dataRetour.Type === "info" ) { |
321
|
|
|
|
322
|
|
|
// Redirection si Type = "success" et si une Url est spécifié |
323
|
|
|
if ( dataRetour.Type === "success" |
324
|
|
|
&& dataRetour.Url != null ) { |
325
|
|
|
|
326
|
|
|
notif = " - Redirection automatique dans une seconde"; |
327
|
|
|
setTimeout( function () { |
328
|
|
|
window.location.replace( dataRetour.Url ); |
329
|
|
|
}, 1100 ); |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
// Affichage de l'alert |
333
|
|
|
alert.type = dataRetour.Type; |
334
|
|
|
alert.titre = dataRetour.Data.Titre; |
335
|
|
|
alert.msg = dataRetour.Data.Message + notif; |
336
|
|
|
writeAlert( $this, alert, btnSubmit, callback ); |
337
|
|
|
return; |
338
|
|
|
|
339
|
|
|
} else { |
340
|
|
|
writeAlert( $this, alert, btnSubmit ); |
341
|
|
|
return; |
342
|
|
|
} |
343
|
|
|
}, |
344
|
|
|
error: function ( data, status, error ) { |
345
|
|
|
//console.log(data.status); |
346
|
|
|
//console.log(status + " -- " + error); |
347
|
|
|
|
348
|
|
|
alert.type = "error"; |
349
|
|
|
alert.titre = "Erreur: " + error; |
350
|
|
|
alert.msg = "Impossible d'envoyer les données."; |
351
|
|
|
writeAlert( $this, alert, btnSubmit ); |
352
|
|
|
return; |
353
|
|
|
} |
354
|
|
|
} ); |
355
|
|
|
} |
356
|
|
|
} |
357
|
|
|
} );*/ |
358
|
|
|
})( jQuery ); |
359
|
|
|
|
360
|
|
|
$( window ).resize( function () { |
361
|
|
|
$( "form .messageForm .alert" ).setDisplayForm(); |
362
|
|
|
} ); |
363
|
|
|
|
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42
will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.