Skip to content

Commit 2b08fc4

Browse files
support controller to set inputs value (#5)
1 parent b000577 commit 2b08fc4

File tree

4 files changed

+209
-88
lines changed

4 files changed

+209
-88
lines changed

README.md

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,36 @@ CreditCardForm(
2020
),
2121
```
2222

23-
| Param | Description |
24-
| -------------------- | ----------------------------------------------------------- |
23+
| Param | Description |
24+
| -------------------- | ------------------------------------------------------------ |
2525
| `theme` | card theme `CreditCardLightTheme()` or `CreditCardDarkTheme` |
26-
| `onChanged` required | listen for input values changed |
27-
| `cardNumberLabel` | label for card number input |
28-
| `cardHolderLabel` | label for card holder name input |
29-
| `expiredDateLabel` | label for expired date input |
30-
| `cvcLabel` | label for security code |
31-
| `cvcLength` | length for security code. default (4) |
32-
| `fontSize` | font size for all inputs and labels. default (16) |
26+
| `onChanged` required | listen for input values changed |
27+
| `cardNumberLabel` | label for card number input |
28+
| `cardHolderLabel` | label for card holder name input |
29+
| `expiredDateLabel` | label for expired date input |
30+
| `cvcLabel` | label for security code |
31+
| `cvcLength` | length for security code. default (4) |
32+
| `fontSize` | font size for all inputs and labels. default (16) |
33+
| `controller` | `CreditCardController()` to set initial value to inputs |
34+
35+
### Set Credit Card Value Initially
36+
37+
```dart
38+
CreditCardController controller = CreditCardController();
39+
40+
CreditCardForm(
41+
controller: controller,
42+
onChanged: (CreditCardResult result) {
43+
},
44+
),
45+
46+
controller.setValue(CreditCardValue(
47+
cardNumber: '4242 4242 4242 4242',
48+
cardHolderName: 'John Wick',
49+
expiryDate: '08/25',
50+
));
51+
52+
```
3353

3454
### How to create custom theme
3555

@@ -50,4 +70,4 @@ CreditCardForm(
5070
onChanged: (CreditCardResult result) {
5171
},
5272
),
53-
```
73+
```

lib/component.dart

Lines changed: 74 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class CreditCardForm extends StatefulWidget {
99
final CreditCardTheme? theme;
1010
final Function(CreditCardResult) onChanged;
1111
final int? cvcLength;
12+
final CreditCardController? controller;
1213
const CreditCardForm({
1314
super.key,
1415
this.theme,
@@ -19,6 +20,7 @@ class CreditCardForm extends StatefulWidget {
1920
this.cvcLabel,
2021
this.fontSize = 16,
2122
this.cvcLength = 4,
23+
this.controller,
2224
});
2325

2426
@override
@@ -38,17 +40,17 @@ class _CreditCardFormState extends State<CreditCardForm> {
3840
"width": 30.0,
3941
};
4042

41-
String error = '';
42-
43-
CardType? cardType;
44-
4543
Map<String, TextEditingController> controllers = {
4644
"card": TextEditingController(),
4745
"expired_date": TextEditingController(),
4846
"card_holder_name": TextEditingController(),
4947
"cvc": TextEditingController(),
5048
};
5149

50+
String error = '';
51+
52+
CardType? cardType;
53+
5254
@override
5355
Widget build(BuildContext context) {
5456
CreditCardTheme theme = widget.theme ?? CreditCardLightTheme();
@@ -65,10 +67,11 @@ class _CreditCardFormState extends State<CreditCardForm> {
6567
),
6668
child: Column(
6769
children: [
68-
textInput(
70+
TextInputWidget(
71+
theme: theme,
72+
fontSize: widget.fontSize,
6973
controller: controllers['card'],
7074
label: widget.cardNumberLabel ?? 'Card number',
71-
key: 'card',
7275
bottom: 1,
7376
formatters: [
7477
FilteringTextInputFormatter.digitsOnly,
@@ -82,6 +85,7 @@ class _CreditCardFormState extends State<CreditCardForm> {
8285
setState(() {
8386
cardImg = img;
8487
cardType = type;
88+
params['card'] = val;
8589
});
8690
emitResult();
8791
},
@@ -94,37 +98,52 @@ class _CreditCardFormState extends State<CreditCardForm> {
9498
),
9599
),
96100
),
97-
textInput(
101+
TextInputWidget(
102+
theme: theme,
103+
fontSize: widget.fontSize,
98104
label: widget.cardHolderLabel ?? 'Card holder name',
99105
controller: controllers['card_holder_name'],
100-
key: 'card_holder_name',
101106
bottom: 1,
102107
onChanged: (val) {
108+
setState(() {
109+
params['card_holder_name'] = val;
110+
});
103111
emitResult();
104112
},
105113
keyboardType: TextInputType.name,
106114
),
107115
Row(
108116
children: [
109117
Expanded(
110-
child: textInput(
118+
child: TextInputWidget(
119+
theme: theme,
120+
fontSize: widget.fontSize,
111121
label: widget.expiredDateLabel ?? 'MM/YY',
112122
right: 1,
113-
key: 'expired_date',
114123
onChanged: (val) {
124+
setState(() {
125+
params['expired_date'] = val;
126+
});
115127
emitResult();
116128
},
117129
controller: controllers['expired_date'],
118-
formatters: [CardExpirationFormatter()],
130+
formatters: [
131+
CardExpirationFormatter(),
132+
LengthLimitingTextInputFormatter(5)
133+
],
119134
),
120135
),
121136
Expanded(
122-
child: textInput(
137+
child: TextInputWidget(
138+
theme: theme,
139+
fontSize: widget.fontSize,
123140
label: widget.cvcLabel ?? 'CVC',
124-
key: 'cvc',
125141
controller: controllers['cvc'],
126142
password: true,
127143
onChanged: (val) {
144+
setState(() {
145+
params['cvc'] = val;
146+
});
128147
emitResult();
129148
},
130149
formatters: [
@@ -167,70 +186,47 @@ class _CreditCardFormState extends State<CreditCardForm> {
167186
widget.onChanged(result);
168187
}
169188

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();
235231
}
236232
}

lib/credit_card_form.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
library credit_card_form;
22

3+
import 'package:credit_card_form/text_input_widget.dart';
34
import 'package:credit_card_form/utils.dart';
45
import 'package:flutter/material.dart';
56
import 'package:flutter/services.dart';
@@ -20,6 +21,15 @@ enum CardType {
2021
invalid
2122
}
2223

24+
class CreditCardController extends ChangeNotifier {
25+
CreditCardValue value = CreditCardValue();
26+
27+
void setValue(CreditCardValue initialValue) {
28+
value = initialValue;
29+
notifyListeners();
30+
}
31+
}
32+
2333
class CreditCardResult {
2434
final String cardNumber;
2535
final String cvc;
@@ -36,3 +46,14 @@ class CreditCardResult {
3646
this.cardType,
3747
});
3848
}
49+
50+
class CreditCardValue {
51+
String? cardNumber;
52+
String? cardHolderName;
53+
String? expiryDate;
54+
CreditCardValue({
55+
this.cardNumber,
56+
this.cardHolderName,
57+
this.expiryDate,
58+
});
59+
}

0 commit comments

Comments
 (0)