@@ -9,6 +9,7 @@ class CreditCardForm extends StatefulWidget {
9
9
final CreditCardTheme ? theme;
10
10
final Function (CreditCardResult ) onChanged;
11
11
final int ? cvcLength;
12
+ final CreditCardController ? controller;
12
13
const CreditCardForm ({
13
14
super .key,
14
15
this .theme,
@@ -19,6 +20,7 @@ class CreditCardForm extends StatefulWidget {
19
20
this .cvcLabel,
20
21
this .fontSize = 16 ,
21
22
this .cvcLength = 4 ,
23
+ this .controller,
22
24
});
23
25
24
26
@override
@@ -38,17 +40,17 @@ class _CreditCardFormState extends State<CreditCardForm> {
38
40
"width" : 30.0 ,
39
41
};
40
42
41
- String error = '' ;
42
-
43
- CardType ? cardType;
44
-
45
43
Map <String , TextEditingController > controllers = {
46
44
"card" : TextEditingController (),
47
45
"expired_date" : TextEditingController (),
48
46
"card_holder_name" : TextEditingController (),
49
47
"cvc" : TextEditingController (),
50
48
};
51
49
50
+ String error = '' ;
51
+
52
+ CardType ? cardType;
53
+
52
54
@override
53
55
Widget build (BuildContext context) {
54
56
CreditCardTheme theme = widget.theme ?? CreditCardLightTheme ();
@@ -65,10 +67,11 @@ class _CreditCardFormState extends State<CreditCardForm> {
65
67
),
66
68
child: Column (
67
69
children: [
68
- textInput (
70
+ TextInputWidget (
71
+ theme: theme,
72
+ fontSize: widget.fontSize,
69
73
controller: controllers['card' ],
70
74
label: widget.cardNumberLabel ?? 'Card number' ,
71
- key: 'card' ,
72
75
bottom: 1 ,
73
76
formatters: [
74
77
FilteringTextInputFormatter .digitsOnly,
@@ -82,6 +85,7 @@ class _CreditCardFormState extends State<CreditCardForm> {
82
85
setState (() {
83
86
cardImg = img;
84
87
cardType = type;
88
+ params['card' ] = val;
85
89
});
86
90
emitResult ();
87
91
},
@@ -94,37 +98,52 @@ class _CreditCardFormState extends State<CreditCardForm> {
94
98
),
95
99
),
96
100
),
97
- textInput (
101
+ TextInputWidget (
102
+ theme: theme,
103
+ fontSize: widget.fontSize,
98
104
label: widget.cardHolderLabel ?? 'Card holder name' ,
99
105
controller: controllers['card_holder_name' ],
100
- key: 'card_holder_name' ,
101
106
bottom: 1 ,
102
107
onChanged: (val) {
108
+ setState (() {
109
+ params['card_holder_name' ] = val;
110
+ });
103
111
emitResult ();
104
112
},
105
113
keyboardType: TextInputType .name,
106
114
),
107
115
Row (
108
116
children: [
109
117
Expanded (
110
- child: textInput (
118
+ child: TextInputWidget (
119
+ theme: theme,
120
+ fontSize: widget.fontSize,
111
121
label: widget.expiredDateLabel ?? 'MM/YY' ,
112
122
right: 1 ,
113
- key: 'expired_date' ,
114
123
onChanged: (val) {
124
+ setState (() {
125
+ params['expired_date' ] = val;
126
+ });
115
127
emitResult ();
116
128
},
117
129
controller: controllers['expired_date' ],
118
- formatters: [CardExpirationFormatter ()],
130
+ formatters: [
131
+ CardExpirationFormatter (),
132
+ LengthLimitingTextInputFormatter (5 )
133
+ ],
119
134
),
120
135
),
121
136
Expanded (
122
- child: textInput (
137
+ child: TextInputWidget (
138
+ theme: theme,
139
+ fontSize: widget.fontSize,
123
140
label: widget.cvcLabel ?? 'CVC' ,
124
- key: 'cvc' ,
125
141
controller: controllers['cvc' ],
126
142
password: true ,
127
143
onChanged: (val) {
144
+ setState (() {
145
+ params['cvc' ] = val;
146
+ });
128
147
emitResult ();
129
148
},
130
149
formatters: [
@@ -167,70 +186,47 @@ class _CreditCardFormState extends State<CreditCardForm> {
167
186
widget.onChanged (result);
168
187
}
169
188
170
- Widget textInput ({
171
- required String label,
172
- required String key,
173
- double left = 0 ,
174
- double right = 0 ,
175
- double bottom = 0 ,
176
- double top = 0 ,
177
- List <TextInputFormatter >? formatters,
178
- TextInputType ? keyboardType,
179
- bool ? password,
180
- Function (String )? onChanged,
181
- Widget ? suffixIcon,
182
- TextEditingController ? controller,
183
- }) {
184
- CreditCardTheme theme = widget.theme ?? CreditCardLightTheme ();
185
- return Container (
186
- decoration: BoxDecoration (
187
- border: Border (
188
- left: BorderSide (
189
- color: left > 0 ? theme.borderColor : Colors .transparent,
190
- width: left,
191
- ),
192
- right: BorderSide (
193
- color: right > 0 ? theme.borderColor : Colors .transparent,
194
- width: right,
195
- ),
196
- top: BorderSide (
197
- color: top > 0 ? theme.borderColor : Colors .transparent,
198
- width: top,
199
- ),
200
- bottom: BorderSide (
201
- color: bottom > 0 ? theme.borderColor : Colors .transparent,
202
- width: bottom,
203
- ),
204
- ),
205
- ),
206
- child: TextField (
207
- controller: controller,
208
- style: TextStyle (
209
- color: theme.textColor,
210
- fontSize: widget.fontSize,
211
- ),
212
- onChanged: (value) {
213
- setState (() {
214
- params[key] = value;
215
- });
216
- if (onChanged != null ) {
217
- onChanged (value);
218
- }
219
- },
220
- obscureText: password ?? false ,
221
- inputFormatters: formatters ?? [],
222
- keyboardType: keyboardType ?? TextInputType .number,
223
- decoration: InputDecoration (
224
- suffixIcon: suffixIcon,
225
- contentPadding: const EdgeInsets .all (15 ),
226
- border: InputBorder .none,
227
- hintText: label,
228
- hintStyle: TextStyle (
229
- color: theme.labelColor,
230
- fontSize: widget.fontSize,
231
- ),
232
- ),
233
- ),
234
- );
189
+ handleController () {
190
+ if (widget.controller != null ) {
191
+ widget.controller? .addListener (() {
192
+ CreditCardValue ? initialValue = widget.controller? .value;
193
+ if (initialValue? .cardNumber != null ) {
194
+ TextEditingValue cardNumber =
195
+ FilteringTextInputFormatter .digitsOnly.formatEditUpdate (
196
+ const TextEditingValue (text: '' ),
197
+ TextEditingValue (text: initialValue! .cardNumber.toString ()),
198
+ );
199
+
200
+ cardNumber = LengthLimitingTextInputFormatter (19 ).formatEditUpdate (
201
+ const TextEditingValue (text: '' ),
202
+ TextEditingValue (text: cardNumber.text),
203
+ );
204
+
205
+ cardNumber = CardNumberInputFormatter ().formatEditUpdate (
206
+ const TextEditingValue (text: '' ),
207
+ TextEditingValue (text: cardNumber.text),
208
+ );
209
+
210
+ controllers['card' ]? .value = cardNumber;
211
+ }
212
+ if (initialValue? .cardHolderName != null ) {
213
+ controllers['card_holder_name' ]? .text =
214
+ initialValue! .cardHolderName.toString ();
215
+ }
216
+ if (initialValue? .expiryDate != null ) {
217
+ controllers['expired_date' ]? .value =
218
+ CardExpirationFormatter ().formatEditUpdate (
219
+ const TextEditingValue (text: '' ),
220
+ TextEditingValue (text: initialValue! .expiryDate.toString ()),
221
+ );
222
+ }
223
+ });
224
+ }
225
+ }
226
+
227
+ @override
228
+ void initState () {
229
+ handleController ();
230
+ super .initState ();
235
231
}
236
232
}
0 commit comments