Code Duplication    Length = 215-249 lines in 2 locations

skins/10h16/js/lib/form_components.js 1 location

@@ 1-215 (lines=215) @@
1
'use strict';
2
var objectAssign = require( 'object-assign' ),
3
	actions = require( './actions' ),
4
5
	INTERVAL_TYPE_ONE_OFF = 0,
6
	INTERVAL_TYPE_RECURRING = 1,
7
8
	createDefaultChangeHandler = function ( store, contentName ) {
9
		return function ( evt ) {
10
			store.dispatch( actions.newChangeContentAction( contentName, evt.target.value ) );
11
		};
12
	},
13
14
	createRegexValidator = function ( store, contentName ) {
15
		return function ( evt ) {
16
			store.dispatch( actions.newValidateInputAction(
17
				contentName,
18
				evt.target.value,
19
				evt.target.getAttribute( 'data-pattern' )
20
			) );
21
		};
22
	},
23
24
	createNoEmptyStringValidator = function ( store, contentName ) {
25
		return function ( evt ) {
26
			store.dispatch( actions.newValidateInputAction(
27
				contentName,
28
				evt.target.value
29
			) );
30
		};
31
	},
32
33
	RadioComponent = {
34
		element: null,
35
		contentName: '',
36
		onChange: null,
37
		render: function ( formContent ) {
38
			this.element.val( [ formContent[ this.contentName ] ] ); // Needs to be an array
39
		}
40
	},
41
42
	CheckboxComponent = {
43
		element: null,
44
		contentName: '',
45
		onChange: null,
46
		render: function ( formContent ) {
47
			this.element.prop( 'checked', !!formContent[ this.contentName ] ); // !! converts to boolean
48
		}
49
	},
50
51
	TextComponent = {
52
		element: null,
53
		contentName: '',
54
		onChange: null,
55
		validator: null,
56
		render: function ( formContent ) {
57
			if ( this.element.val() !== formContent[ this.contentName ] ) {
58
				// Avoid changing value while element is edited by the user
59
				if ( !this.element.is( ':focus' ) ) {
60
					this.element.val( formContent[ this.contentName ] );
61
					this.element.change();
62
				}
63
			}
64
		}
65
	},
66
67
	AmountComponent = {
68
		inputElement: null,
69
		selectElement: null,
70
		hiddenElement: null,
71
		render: function ( formContent ) {
72
			this.hiddenElement.val( formContent.amount || '' );
73
			if ( formContent.isCustomAmount ) {
74
				this.selectElement.prop( 'checked', false );
75
				this.inputElement.val( formContent.amount );
76
			} else {
77
				this.selectElement.val( [ formContent.amount ] );
78
				this.inputElement.val( '' );
79
			}
80
		}
81
	},
82
83
	PaymentIntervalComponent = {
84
		decisionElement: null,
85
		paymentIntervalElement: null,
86
		render: function ( formContent ) {
87
			var intervalType = formContent.paymentIntervalInMonths > 0 ?
88
				INTERVAL_TYPE_RECURRING :
89
				INTERVAL_TYPE_ONE_OFF;
90
			this.paymentIntervalElement.val( [ formContent.paymentIntervalInMonths ] );
91
			this.decisionElement.val( [ intervalType ] );
92
		}
93
	},
94
95
	BankDataComponent = {
96
		ibanElement: null,
97
		bicElement: null,
98
		accountNumberElement: null,
99
		bankCodeElement: null,
100
		debitTypeElement: null,
101
		bankNameFieldElement: null,
102
		bankNameDisplayElement: null,
103
		render: function ( formContent ) {
104
			this.ibanElement.val( formContent.iban );
105
			this.bicElement.val( formContent.bic );
106
			this.accountNumberElement.val( formContent.accountNumber );
107
			this.bankCodeElement.val( formContent.bankCode );
108
			this.debitTypeElement.val( [ formContent.debitType ] ); // set as array for radio buttons/dropdown field
109
			this.bankNameFieldElement.val( formContent.bankName );
110
			this.bankNameDisplayElement.text( formContent.bankName );
111
		}
112
	};
113
114
module.exports = {
115
116
	INTERVAL_TYPE_ONE_OFF: INTERVAL_TYPE_ONE_OFF,
117
	INTERVAL_TYPE_RECURRING: INTERVAL_TYPE_RECURRING,
118
119
	createRadioComponent: function ( store, element, contentName ) {
120
		var component = objectAssign( Object.create( RadioComponent ), {
121
			element: element,
122
			contentName: contentName,
123
			onChange: createDefaultChangeHandler( store, contentName )
124
		} );
125
		element.on( 'change', component.onChange );
126
		return component;
127
	},
128
129
	createSelectMenuComponent: function ( store, element, contentName ) {
130
		var component = objectAssign( Object.create( RadioComponent ), {
131
			element: element,
132
			contentName: contentName,
133
			onChange: createDefaultChangeHandler( store, contentName )
134
		} );
135
		element.on( 'selectmenuchange', component.onChange );
136
		return component;
137
	},
138
139
	createCheckboxComponent: function ( store, element, contentName ) {
140
		var component = objectAssign( Object.create( CheckboxComponent ), {
141
			element: element,
142
			contentName: contentName,
143
			onChange: function () {
144
				store.dispatch( actions.newChangeContentAction( contentName, !!element.prop( 'checked' ) ) );
145
			}
146
		} );
147
		element.on( 'change', component.onChange );
148
		return component;
149
	},
150
151
	createValidatingCheckboxComponent: function ( store, element, contentName ) {
152
		var component = objectAssign( this.createCheckboxComponent( store, element, contentName ), {
153
			validator: createNoEmptyStringValidator( store, contentName )
154
		} );
155
		element.on( 'change', component.validator );
156
		return component;
157
	},
158
159
	createTextComponent: function ( store, element, contentName ) {
160
		var component = objectAssign( Object.create( TextComponent ), {
161
			element: element,
162
			contentName: contentName,
163
			onChange: createDefaultChangeHandler( store, contentName )
164
		} );
165
		element.on( 'change', component.onChange );
166
		return component;
167
	},
168
169
	createValidatingTextComponent: function ( store, element, contentName ) {
170
		var component = objectAssign( this.createTextComponent( store, element, contentName ), {
171
			validator: createRegexValidator( store, contentName )
172
		} );
173
		element.on( 'change', component.validator );
174
		return component;
175
	},
176
177
	createAmountComponent: function ( store, inputElement, selectElement, hiddenElement ) {
178
		var component = objectAssign( Object.create( AmountComponent ), {
179
			inputElement: inputElement,
180
			selectElement: selectElement,
181
			hiddenElement: hiddenElement
182
		} );
183
		inputElement.on( 'change', function ( evt ) {
184
			store.dispatch( actions.newInputAmountAction( evt.target.value ) );
185
		} );
186
		selectElement.on( 'change', function ( evt ) {
187
			store.dispatch( actions.newSelectAmountAction( evt.target.value ) );
188
		} );
189
		return component;
190
	},
191
192
	createPaymentIntervalComponent: function ( store, decisionElement, intervalElement ) {
193
		var component = objectAssign( Object.create( PaymentIntervalComponent ), {
194
			decisionElement: decisionElement,
195
			paymentIntervalElement: intervalElement,
196
			onChange: createDefaultChangeHandler( store, 'paymentIntervalInMonths' )
197
		} );
198
		decisionElement.on( 'change', component.onChange );
199
		intervalElement.on( 'change', component.onChange );
200
		return component;
201
	},
202
203
	createBankDataComponent: function ( store, bankDataElements ) {
204
		// TODO check if all elements are passed in
205
		var component = objectAssign( Object.create( BankDataComponent ), bankDataElements );
206
		bankDataElements.ibanElement.on( 'change', createDefaultChangeHandler( store, 'iban' ) );
207
		bankDataElements.bicElement.on( 'change', createDefaultChangeHandler( store, 'bic' ) );
208
		bankDataElements.bicElement.on( 'change', createRegexValidator( store, 'bic' ) );
209
		bankDataElements.accountNumberElement.on( 'change', createDefaultChangeHandler( store, 'accountNumber' ) );
210
		bankDataElements.bankCodeElement.on( 'change', createDefaultChangeHandler( store, 'bankCode' ) );
211
		bankDataElements.debitTypeElement.on( 'change', createDefaultChangeHandler( store, 'debitType' ) );
212
		return component;
213
	}
214
215
};
216

skins/cat17/src/app/lib/form_components.js 1 location

@@ 1-249 (lines=249) @@
1
'use strict';
2
3
var objectAssign = require( 'object-assign' ),
4
	_ = require( 'underscore' ),
5
	actions = require( './actions' ),
6
	NumericInputHandler = require( './numeric_input_handler' ),
7
8
	/**
9
	 * Wrapper around underscore debounce function with a delay of 300 milliseconds
10
	 *
11
	 * @param {function} f
12
	 * @param {Number} milliseconds
13
	 * @return {Function}
14
	 */
15
	defaultDebounce = function ( f, milliseconds ) {
16
		return _.debounce( f, milliseconds || 300 );
17
	},
18
19
	createDefaultChangeHandler = function ( store, contentName ) {
20
		return function ( evt ) {
21
			store.dispatch( actions.newChangeContentAction( contentName, evt.target.value ) );
22
		};
23
	},
24
25
	createRegexValidator = function ( store, contentName ) {
26
		return function ( evt ) {
27
			store.dispatch( actions.newValidateInputAction(
28
				contentName,
29
				evt.target.value,
30
				evt.target.getAttribute( 'data-pattern' )
31
			) );
32
		};
33
	},
34
35
	createNoEmptyStringValidator = function ( store, contentName ) {
36
		return function ( evt ) {
37
			store.dispatch( actions.newValidateInputAction(
38
				contentName,
39
				evt.target.value
40
			) );
41
		};
42
	},
43
44
	RadioComponent = {
45
		element: null,
46
		contentName: '',
47
		onChange: null,
48
		render: function ( formContent ) {
49
			this.element.val( [ formContent[ this.contentName ] ] ); // Needs to be an array
50
		}
51
	},
52
53
	SelectComponent = {
54
		element: null,
55
		contentName: '',
56
		onChange: null,
57
		render: function ( formContent ) {
58
59
			if ( this.element.val() === formContent[ this.contentName ]  || this.elementAndContentAreEmpty( formContent ) ) {
60
				return;
61
			}
62
63
			this.element.val( [ formContent[ this.contentName ] ] );
64
			this.element.change();
65
		},
66
		elementAndContentAreEmpty: function( formContent ) {
67
			// calling this.element.val( '' ) leads to this.element.val() === null in some cases,
68
			// so we need to compare different types
69
			return this.element.val() === null && formContent[ this.contentName ] === '';
70
		}
71
	},
72
73
	CheckboxComponent = {
74
		element: null,
75
		contentName: '',
76
		onChange: null,
77
		render: function ( formContent ) {
78
			this.element.prop( 'checked', !!formContent[ this.contentName ] ); // !! converts to boolean
79
		}
80
	},
81
82
	TextComponent = {
83
		element: null,
84
		contentName: '',
85
		onChange: null,
86
		validator: null,
87
		render: function ( formContent ) {
88
			if ( this.element.val() !== formContent[ this.contentName ] ) {
89
				// Avoid changing value while element is edited by the user
90
				if ( !this.element.is( ':focus' ) ) {
91
					this.element.val( formContent[ this.contentName ] );
92
					this.element.change();
93
				}
94
			}
95
		}
96
	},
97
98
	AmountComponent = {
99
		inputElement: null,
100
		selectElement: null,
101
		hiddenElement: null,
102
		numberFormatter: null,
103
		render: function ( formContent ) {
104
			this.hiddenElement.val( this.numberFormatter.format( formContent.amount ) );
105
			if ( formContent.isCustomAmount ) {
106
				this.inputElement.parent().addClass( 'filled' );
107
				this.selectElement.prop( 'checked', false );
108
				this.inputElement.val( this.numberFormatter.format( formContent.amount ) );
109
			} else {
110
				this.inputElement.parent().removeClass( 'filled' );
111
				this.selectElement.val( [ String( formContent.amount ) ] );
112
				this.inputElement.val( '' );
113
			}
114
		}
115
	},
116
117
	BankDataComponent = {
118
		ibanElement: null,
119
		bicElement: null,
120
		accountNumberElement: null,
121
		bankCodeElement: null,
122
		bankNameFieldElement: null,
123
		bankNameDisplayElement: null,
124
		render: function ( formContent ) {
125
			this.ibanElement.val( formContent.iban );
126
			this.bicElement.val( formContent.bic );
127
			this.accountNumberElement.val( formContent.accountNumber );
128
			this.bankCodeElement.val( formContent.bankCode );
129
			this.bankNameFieldElement.val( formContent.bankName );
130
			this.bankNameDisplayElement.text( formContent.bankName );
131
		}
132
	};
133
134
module.exports = {
135
136
	createRadioComponent: function ( store, element, contentName ) {
137
		var component = objectAssign( Object.create( RadioComponent ), {
138
			element: element,
139
			contentName: contentName,
140
			onChange: createDefaultChangeHandler( store, contentName )
141
		} );
142
		element.on( 'change', component.onChange );
143
		return component;
144
	},
145
146
	createSelectMenuComponent: function ( store, element, contentName ) {
147
		var component = objectAssign( Object.create( SelectComponent ), {
148
			element: element,
149
			contentName: contentName,
150
			onChange: createDefaultChangeHandler( store, contentName )
151
		} );
152
		element.on( 'selectmenuchange, change', component.onChange );
153
		return component;
154
	},
155
156
	createCheckboxComponent: function ( store, element, contentName ) {
157
		var component = objectAssign( Object.create( CheckboxComponent ), {
158
			element: element,
159
			contentName: contentName,
160
			onChange: function () {
161
				store.dispatch( actions.newChangeContentAction( contentName, !!element.prop( 'checked' ) ) );
162
			}
163
		} );
164
		element.on( 'change', component.onChange );
165
		return component;
166
	},
167
168
	createValidatingCheckboxComponent: function ( store, element, contentName ) {
169
		var component = objectAssign( this.createCheckboxComponent( store, element, contentName ), {
170
			validator: createNoEmptyStringValidator( store, contentName )
171
		} );
172
		element.on( 'change', component.validator );
173
		return component;
174
	},
175
176
	createTextComponent: function ( store, element, contentName ) {
177
		var component = objectAssign( Object.create( TextComponent ), {
178
			element: element,
179
			contentName: contentName,
180
			onChange: createDefaultChangeHandler( store, contentName )
181
		} );
182
		element.on( 'change', component.onChange );
183
		return component;
184
	},
185
186
	createValidatingTextComponent: function ( store, element, contentName ) {
187
		var component = objectAssign( this.createTextComponent( store, element, contentName ), {
188
			validator: createRegexValidator( store, contentName )
189
		} );
190
		element.on( 'change', component.validator );
191
		return component;
192
	},
193
194
	/**
195
	 * @param store
196
	 * @param {jQuery} inputElement
197
	 * @param {jQuery} selectElement
198
	 * @param {jQuery} hiddenElement
199
	 * @param {CurrencyParser} numberParser
200
	 * @param {CurrencyFormatter} numberFormatter
201
	 * @return {AmountComponent}
202
	 */
203
	createAmountComponent: function ( store, inputElement, selectElement, hiddenElement, numberParser, numberFormatter ) {
204
		var component = objectAssign( Object.create( AmountComponent ), {
205
			inputElement: inputElement,
206
			selectElement: selectElement,
207
			hiddenElement: hiddenElement,
208
			numberFormatter: numberFormatter
209
		} );
210
		NumericInputHandler.createNumericInputHandler( inputElement, numberParser.getDecimalDelimiter() );
211
		inputElement.on( 'change', function ( evt ) {
212
			var amount;
213
			try {
214
				amount = numberParser.parse( evt.target.value );
215
			} catch ( e ) {
216
				amount = 0;
217
				inputElement.val( '0' );
218
			}
219
			store.dispatch( actions.newInputAmountAction( amount ) );
220
		} );
221
		selectElement.on( 'change', function ( evt ) {
222
			store.dispatch( actions.newSelectAmountAction( evt.target.value ) );
223
		} );
224
		return component;
225
	},
226
227
	createBankDataComponent: function ( store, bankDataElements ) {
228
		var component = objectAssign( Object.create( BankDataComponent ), bankDataElements );
229
		bankDataElements.ibanElement.on( 'change', createDefaultChangeHandler( store, 'iban' ) );
230
		bankDataElements.bicElement.on( 'change', createDefaultChangeHandler( store, 'bic' ) );
231
		bankDataElements.bicElement.on( 'change', createRegexValidator( store, 'bic' ) );
232
		bankDataElements.accountNumberElement.on( 'change', createDefaultChangeHandler( store, 'accountNumber' ) );
233
		bankDataElements.bankCodeElement.on( 'change', createDefaultChangeHandler( store, 'bankCode' ) );
234
		return component;
235
	},
236
237
	addEagerChangeBehavior: function( textComponent, debouncingFunction ) {
238
		debouncingFunction = debouncingFunction || defaultDebounce;
239
		textComponent.element.on( 'keypress', debouncingFunction( function ( evt ) {
240
			textComponent.onChange( evt );
241
			if ( textComponent.validator ) {
242
				textComponent.validator( evt );
243
			}
244
		} ) );
245
		return textComponent;
246
	},
247
248
	SelectComponent: SelectComponent
249
};
250