Completed
Push — master ( 616573...58347b )
by wiese
163:41 queued 98:34
created

skins/10h16/web/_js/donationForm.js   B

Complexity

Total Complexity 37
Complexity/F 1.85

Size

Lines of Code 437
Function Count 20

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 37
dl 0
loc 437
rs 8.6
c 3
b 0
f 0
cc 0
nc 128
mnd 3
bc 38
fnc 20
bpm 1.9
cpm 1.85
noi 2
1
$( function () {
2
	/** global: WMDE */
3
4
	var initData = $( '#init-form' ),
5
		store = WMDE.Store.createDonationStore(),
6
		actions = WMDE.Actions
7
		;
8
9
	WMDE.StoreUpdates.connectComponentsToStore(
10
		[
11
			WMDE.Components.createAmountComponent( store, $( '.amount-input' ), $( '.amount-select' ), $( '.amount-hidden' ) ),
12
			WMDE.Components.createRadioComponent( store, $( '.payment-type-select' ), 'paymentType' ),
13
			WMDE.Components.createPaymentIntervalComponent( store, $( '.interval-type-select' ), $( '.payment-period-select' ) ),
14
			WMDE.Components.createBankDataComponent( store, {
15
				ibanElement: $( '#iban' ),
16
				bicElement: $( '#bic' ),
17
				accountNumberElement: $( '#account-number' ),
18
				bankCodeElement: $( '#bank-code' ),
19
				bankNameFieldElement: $( '#field-bank-name' ),
20
				bankNameDisplayElement: $( '#bank-name' ),
21
				debitTypeElement: $( '.debit-type-select' )
22
			} ),
23
			WMDE.Components.createRadioComponent( store, $( '.address-type-select' ), 'addressType' ),
24
			WMDE.Components.createRadioComponent( store, $( '.salutation' ), 'salutation' ),
25
			WMDE.Components.createSelectMenuComponent( store, $( '.personal-title' ), 'title' ),
26
			WMDE.Components.createValidatingTextComponent( store, $( '#first-name' ), 'firstName' ),
27
			WMDE.Components.createValidatingTextComponent( store, $( '#last-name' ), 'lastName' ),
28
			WMDE.Components.createValidatingTextComponent( store, $( '#company-name' ), 'companyName' ),
29
			WMDE.Components.createValidatingTextComponent( store, $( '#street' ), 'street' ),
30
			WMDE.Components.createValidatingTextComponent( store, $( '#post-code' ), 'postcode' ),
31
			WMDE.Components.createValidatingTextComponent( store, $( '#city' ), 'city' ),
32
			WMDE.Components.createSelectMenuComponent( store, $( '#country' ), 'country' ),
33
			WMDE.Components.createTextComponent( store, $( '#email' ), 'email' ),
34
			WMDE.Components.createValidatingCheckboxComponent( store, $( '#confirm_sepa' ), 'confirmSepa' ),
35
			WMDE.Components.createValidatingCheckboxComponent( store, $( '#confirm_shortterm' ), 'confirmShortTerm' )
36
		],
37
		store,
38
		'donationFormContent'
39
	);
40
41
	WMDE.StoreUpdates.connectValidatorsToStore(
42
		function ( initialValues ) {
43
			return [
44
				WMDE.ValidationDispatchers.createAmountValidationDispatcher(
45
					WMDE.FormValidation.createAmountValidator( initData.data( 'validate-amount-url' ) ),
46
					initialValues
47
				),
48
				WMDE.ValidationDispatchers.createAddressValidationDispatcher(
49
					WMDE.FormValidation.createAddressValidator( 
50
						initData.data( 'validate-address-url' ),
51
						WMDE.FormValidation.DefaultRequiredFieldsForAddressType
52
					),
53
					initialValues
54
				),
55
				WMDE.ValidationDispatchers.createEmailValidationDispatcher(
56
					WMDE.FormValidation.createEmailAddressValidator( initData.data( 'validate-email-address-url' ) ),
57
					initialValues
58
				),
59
				WMDE.ValidationDispatchers.createBankDataValidationDispatcher(
60
					WMDE.FormValidation.createBankDataValidator(
61
						initData.data( 'validate-iban-url' ),
62
						initData.data( 'generate-iban-url' )
63
					),
64
					initialValues
65
				),
66
				WMDE.ValidationDispatchers.createSepaConfirmationValidationDispatcher(
67
					WMDE.FormValidation.createSepaConfirmationValidator(),
68
					initialValues
69
				)
70
			];
71
		},
72
		store,
73
		initData.data( 'initial-form-values' ),
74
		'donationFormContent'
75
	);
76
77
	// Connect view handlers to changes in specific parts in the global state, designated by 'stateKey'
78
	WMDE.StoreUpdates.connectViewHandlersToStore(
79
		[
80
			{
81
				viewHandler: WMDE.View.createFormPageVisibilityHandler( {
82
					payment: $( "#paymentPage" ),
83
					personalData: $( "#personalDataPage" ),
84
					bankConfirmation: $( '#bankConfirmationPage' )
85
				} ),
86
				stateKey: 'formPagination'
87
			},
88
			{
89
				viewHandler: WMDE.View.createErrorBoxHandler( $( '#validation-errors' ), {
90
					amount: 'Betrag',
91
					paymentType: 'Zahlungsart',
92
					salutation: 'Anrede',
93
					title: 'Titel',
94
					firstName: 'Vorname',
95
					lastName: 'Nachname',
96
					companyName: 'Firma',
97
					street: 'Straße',
98
					postcode: 'PLZ',
99
					city: 'Ort',
100
					country: 'Land',
101
					email: 'E-Mail',
102
					iban: 'IBAN',
103
					bic: 'BIC',
104
					accountNumber: 'Kontonummer',
105
					bankCode: 'Bankleitzahl',
106
					confirmSepa: 'SEPA-Lastschrift',
107
					confirmShortTerm: 'SEPA-Informationsfrist'
108
				} ),
109
				stateKey: 'donationInputValidation'
110
			},
111
			// show payment periods if interval payment is selected
112
			{
113
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '.periode-2-list' ), /^(1|3|6|12)$/ ),
114
				stateKey: 'donationFormContent.paymentIntervalInMonths'
115
			},
116
			// Show bank data input when doing direct debit
117
			{
118
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '#bank-data' ), 'BEZ' ),
119
				stateKey: 'donationFormContent.paymentType'
120
			},
121
			// Show the right submit buttons on page 2, depending on payment type
122
			{
123
				viewHandler: WMDE.View.createSimpleVisibilitySwitcher( $( '#finishFormSubmit2' ), /^MCP|PPL|UEB|SUB/ ),
124
				stateKey: 'donationFormContent.paymentType'
125
			},
126
			{
127
				viewHandler: WMDE.View.createSimpleVisibilitySwitcher( $( '#continueFormSubmit2' ), 'BEZ' ),
128
				stateKey: 'donationFormContent.paymentType'
129
			},
130
			// Hide anonymous payment when doing direct debit
131
			{
132
				viewHandler: WMDE.View.createSimpleVisibilitySwitcher( $( '.anonymous-payment-select, #tooltip-icon-addresstype' ), /^MCP|PPL|UEB|SUB/ ),
133
				stateKey: 'donationFormContent.paymentType'
134
			},
135
			// Switch bank data input between IBAN/BIC and Account Number/Bank code
136
			{
137
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '.slide-sepa' ), 'sepa' ),
138
				stateKey: 'donationFormContent.debitType'
139
			},
140
			{
141
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '.slide-non-sepa' ), 'non-sepa' ),
142
				stateKey: 'donationFormContent.debitType'
143
			},
144
			// Show only the right data fields for personal data
145
			{
146
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '.personal-data-person' ), 'person' ),
147
				stateKey: 'donationFormContent.addressType'
148
			},
149
			{
150
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '.personal-data-company' ), 'firma' ),
151
				stateKey: 'donationFormContent.addressType'
152
			},
153
			{
154
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '.personal-data-full, #notice-unsubscribe' ), /firma|person/ ),
155
				stateKey: 'donationFormContent.addressType'
156
			},
157
			// Show notice for anonymous donations
158
			{
159
				viewHandler: WMDE.View.createSlidingVisibilitySwitcher( $( '.notice-anonymous' ), 'anonym' ),
160
				stateKey: 'donationFormContent.addressType'
161
			},
162
			// Show "credit card required" notice for recurrent payments via Paypal
163
			{
164
				viewHandler: WMDE.View.createRecurrentPaypalNoticeHandler(
165
					WMDE.View.Animator.createSlidingElementAnimator( $( '.notice-ppl-recurrent' ) )
166
				),
167
				stateKey: 'donationFormContent'
168
			},
169
			// Show warning when street contains no house number
170
			{
171
				viewHandler: WMDE.View.createWarningBox(
172
					$( '#street-warning-box' ),
173
					function( fieldValue ) {
174
						return fieldValue.trim() !== '' && fieldValue.match(/\d+/g) === null;
175
					}
176
				),
177
				stateKey: 'donationFormContent.street'
178
			},
179
			{
180
				viewHandler: WMDE.View.createPaymentSummaryDisplayHandler(
181
					$( '.interval-text' ),
182
					$( '.amount-formatted'),
183
					$( '#payment-display'),
184
					{
185
						'0': 'einmalig',
186
						'1': 'monatlich',
187
						'3': 'quartalsweise',
188
						'6': 'halbjährlich',
189
						'12': 'jährlich'
190
					},
191
					{
192
						'BEZ': 'Lastschrift',
193
						'UEB': 'Überweisung',
194
						'MCP': 'Kreditkarte',
195
						'PPL': 'PayPal',
196
						'SUB': 'Sofortüberweisung'
197
					},
198
					WMDE.CurrencyFormatter.createCurrencyFormatter( 'de' )
199
				),
200
				stateKey: 'donationFormContent'
201
			},
202
			{
203
				viewHandler: WMDE.View.createDisplayAddressHandler( {
204
					fullName: $( '.confirm-name' ),
205
					street: $( '.confirm-street' ),
206
					postcode: $( '.confirm-postcode' ),
207
					city: $( '.confirm-city' ),
208
					country: $( '.confirm-country' ),
209
					email: $( '.confirm-email' )
210
				} ),
211
				stateKey: 'donationFormContent'
212
			},
213
			{
214
				viewHandler: WMDE.View.createBankDataDisplayHandler(
215
					$( '.confirm-iban' ),
216
					$( '.confirm-bic' ),
217
					$( '.confirm-bank-name' )
218
				),
219
				stateKey: 'donationFormContent'
220
			},
221
			{
222
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#first-name' ) ),
223
				stateKey: 'donationInputValidation.firstName'
224
			},
225
			{
226
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#last-name' ) ),
227
				stateKey: 'donationInputValidation.lastName'
228
			},
229
			{
230
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#street' ) ),
231
				stateKey: 'donationInputValidation.street'
232
			},
233
			{
234
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#post-code' ) ),
235
				stateKey: 'donationInputValidation.postcode'
236
			},
237
			{
238
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#city' ) ),
239
				stateKey: 'donationInputValidation.city'
240
			},
241
			{
242
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#email' ) ),
243
				stateKey: 'donationInputValidation.email'
244
			},
245
			{
246
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#company-name' ) ),
247
				stateKey: 'donationInputValidation.companyName'
248
			},
249
			{
250
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#iban' ) ),
251
				stateKey: 'donationInputValidation.iban'
252
			},
253
			{
254
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#bic' ) ),
255
				stateKey: 'donationInputValidation.bic'
256
			},
257
			{
258
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#account-number' ) ),
259
				stateKey: 'donationInputValidation.accountNumber'
260
			},
261
			{
262
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '#bank-code' ) ),
263
				stateKey: 'donationInputValidation.bankCode'
264
			},
265
			{
266
				viewHandler: WMDE.View.createFieldValueValidityIndicator( $( '.amount-input' ) ),
267
				stateKey: 'donationInputValidation.amount'
268
			}
269
		],
270
		store
271
	);
272
273
	// Validity checks for different form parts
274
275
	function addressIsValid() {
276
		var validity = store.getState().validity,
277
			formContent = store.getState().donationFormContent;
278
		return formContent.addressType === 'anonym' || validity.address;
279
	}
280
281
	function bankDataIsValid() {
282
		var validity = store.getState().validity,
283
			formContent = store.getState().donationFormContent;
284
		return formContent.paymentType !== 'BEZ' || validity.bankData;
285
	}
286
287
	function personalDataPageIsValid() {
288
		var validity = store.getState().validity;
0 ignored issues
show
Unused Code introduced by
The assignment to variable validity seems to be never used. Consider removing it.
Loading history...
289
		return !hasInvalidFields() && paymentDataIsValid() && addressIsValid() && bankDataIsValid();
290
	}
291
292
	function triggerValidityCheckForPaymentPage() {
293
		if ( !paymentDataIsValid() ) {
294
			store.dispatch( actions.newMarkEmptyFieldsInvalidAction( [ 'amount' ] ) );
295
		}
296
	}
297
298
	function triggerValidityCheckForPersonalDataPage() {
299
		var formContent = store.getState().donationFormContent;
300
301
		if ( !addressIsValid() ) {
302
			if ( formContent.addressType === 'person' ) {
303
				store.dispatch( actions.newMarkEmptyFieldsInvalidAction(
304
					[ 'salutation', 'firstName', 'lastName', 'street', 'postcode', 'city', 'email' ],
305
					[ 'companyName' ]
306
				) );
307
			} else if ( formContent.addressType === 'firma' ) {
308
				store.dispatch( actions.newMarkEmptyFieldsInvalidAction(
309
					[ 'companyName', 'street', 'postcode', 'city', 'email' ],
310
					[ 'firstName', 'lastName' ]
311
				) );
312
			}
313
		}
314
315
		if ( !bankDataIsValid() ) {
316
			store.dispatch( actions.newMarkEmptyFieldsInvalidAction(
317
				[ 'iban', 'bic' ]
318
			) );
319
		}
320
	}
321
322
	function triggerValidityCheckForSepaPage() {
323
		if ( !store.getState().validity.sepaConfirmation ) {
324
			store.dispatch( actions.newMarkEmptyFieldsInvalidAction(
325
				[ 'confirmSepa', 'confirmShortTerm' ]
326
			) );
327
		}
328
	}
329
330
	function hasInvalidFields() {
331
		var invalidFields = false;
332
		$.each( store.getState().donationInputValidation, function( key, value ) {
333
			if ( value.isValid === false ) {
334
				invalidFields = true;
335
			}
336
		} );
337
338
		return invalidFields;
339
	}
340
341
	function paymentDataIsValid() {
342
		var currentState = store.getState();
343
		return currentState.validity.paymentData;
344
	}
345
346
	function displayErrorBox() {
347
		$( '#validation-errors' ).show();
348
		$( 'html, body' ).animate( { scrollTop: $( '#validation-errors' ).offset().top } );
349
	}
350
351
	function triggerPiwikEvent( eventData ) {
352
		if ( typeof _paq !== 'undefined' ) {
0 ignored issues
show
Bug introduced by
The variable _paq seems to be never declared. If this is a global, consider adding a /** global: _paq */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
353
			_paq.push( eventData );
354
		}
355
	}
356
357
	function handlePaymentDataSubmit() {
358
		if ( paymentDataIsValid() ) {
359
			store.dispatch( actions.newNextPageAction() );
360
			triggerPiwikEvent( [ 'trackGoal', 2 ] );
361
		} else {
362
			triggerValidityCheckForPaymentPage();
363
			displayErrorBox();
364
		}
365
	}
366
367
	function handlePersonalDataSubmitForDirectDebit() {
368
		if ( personalDataPageIsValid() ) {
369
			store.dispatch( actions.newNextPageAction() );
370
			triggerPiwikEvent( [ 'trackGoal', 4 ] );
371
		} else {
372
			triggerValidityCheckForPersonalDataPage();
373
			displayErrorBox();
374
		}
375
	}
376
377
	function handlePersonalDataSubmitForNonDirectDebit() {
378
		if ( personalDataPageIsValid() ) {
379
			$( '#donForm2' ).submit();
380
		} else {
381
			triggerValidityCheckForPersonalDataPage();
382
			displayErrorBox();
383
		}
384
	}
385
386
	// connect DOM element events to actions
387
388
	$( '#continueFormSubmit1' ).click( WMDE.StoreUpdates.makeEventHandlerWaitForAsyncFinish( handlePaymentDataSubmit, store ) );
389
390
	$( '#continueFormSubmit2' ).click( WMDE.StoreUpdates.makeEventHandlerWaitForAsyncFinish( handlePersonalDataSubmitForDirectDebit, store )  );
391
392
	$( '#finishFormSubmit2' ).click( WMDE.StoreUpdates.makeEventHandlerWaitForAsyncFinish( handlePersonalDataSubmitForNonDirectDebit, store ) );
393
394
	$( '.back-button' ).click( function () {
395
		store.dispatch( actions.newResetFieldValidityAction( [ 'confirmSepa', 'confirmShortTerm' ] ) );
396
		store.dispatch( actions.newPreviousPageAction() );
397
	} );
398
399
	$( '#finishFormSubmit3' ).click( function () {
400
		var validity = store.getState().validity;
401
		// we use validity directly here because SEPA really needs these values to be valid
402
		if ( validity.paymentData && validity.address && validity.bankData && validity.sepaConfirmation ) {
403
			$( '#donForm2' ).submit();
404
		} else {
405
			triggerValidityCheckForSepaPage();
406
			displayErrorBox();
407
		}
408
	} );
409
410
411
	$( '#donForm1 .amount-input' ).keypress( function ( evt ) {
412
		if( evt.which === 13 ) {
413
			$( '#continueFormSubmit1' ).click();
414
			evt.preventDefault();
415
		}
416
	} );
417
418
	// Set initial form values
419
	store.dispatch( actions.newInitializeContentAction( initData.data( 'initial-form-values' ) ) );
420
421
	// Set initial validation state
422
	store.dispatch( actions.newInitializeValidationStateAction(
423
		initData.data( 'violatedFields' ),
424
		initData.data( 'initial-validation-result' )
425
	) );
426
427
	// Initialize form pages
428
	store.dispatch( actions.newAddPageAction( 'payment' ) );
429
	store.dispatch( actions.newAddPageAction( 'personalData' ) );
430
	store.dispatch( actions.newAddPageAction( 'bankConfirmation' ) );
431
432
	// switch to personal page if payment data is filled in
433
	if ( paymentDataIsValid() ) {
434
		store.dispatch( actions.newNextPageAction() );
435
	}
436
437
} );
438