Skip to content

Commit 6585986

Browse files
committed
Fix merge conflicts PR #270
2 parents 995a2a7 + 58d7545 commit 6585986

File tree

6 files changed

+529
-17
lines changed

6 files changed

+529
-17
lines changed

example/lib/main.dart

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ class MyHomePageState extends State<MyHomePage> {
4242
bool readOnly = false;
4343
bool showSegmentedControl = true;
4444
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
45-
final GlobalKey<FormFieldState> _specifyTextFieldKey =
46-
GlobalKey<FormFieldState>();
45+
final GlobalKey<FormFieldState> _specifyTextFieldKey = GlobalKey<FormFieldState>();
4746

4847
ValueChanged _onChanged = (val) => print(val);
4948
var genderOptions = ['Male', 'Female', 'Other'];
@@ -486,8 +485,8 @@ class MyHomePageState extends State<MyHomePage> {
486485
"English",
487486
"Spanish",
488487
"Somali",
489-
"Other"
490-
];
488+
"Other"];
489+
491490
return InputDecorator(
492491
decoration: InputDecoration(
493492
labelText: "What's your preferred language?"),
@@ -544,7 +543,33 @@ class MyHomePageState extends State<MyHomePage> {
544543
return "Two or more images required.";
545544
}
546545
return null;
547-
}
546+
}],
547+
),
548+
FormBuilderCountryPicker(
549+
defaultSelectedCountryIsoCode: 'US',
550+
attribute: "country",
551+
cursorColor: Colors.black,
552+
style: TextStyle(color: Colors.black, fontSize: 18),
553+
priorityListByIsoCode: ['US'],
554+
valueTransformer: (value) {
555+
return value.isoCode;
556+
},
557+
decoration: InputDecoration(border: OutlineInputBorder(), labelText: "Country"),
558+
validators: [
559+
FormBuilderValidators.required(errorText: 'This field required.'),
560+
],
561+
),
562+
FormBuilderPhoneField(
563+
attribute: 'phone_number',
564+
keyboardType: TextInputType.phone,
565+
defaultSelectedCountryIsoCode: 'US',
566+
cursorColor: Colors.black,
567+
style: TextStyle(color: Colors.black, fontSize: 18),
568+
decoration: InputDecoration(border: OutlineInputBorder(), labelText: "Phone Number"),
569+
priorityListByIsoCode: ['US'],
570+
validators: [
571+
FormBuilderValidators.numeric(errorText: 'Invalid phone number'),
572+
FormBuilderValidators.required(errorText: 'This field reqired')
548573
],
549574
),
550575
FormBuilderSignaturePad(

lib/flutter_form_builder.dart

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
library flutter_form_builder;
22

3-
export './src/form_builder.dart';
4-
export './src/form_builder_custom_field.dart';
5-
export './src/form_builder_field_option.dart';
6-
export './src/form_builder_validators.dart';
3+
export 'package:flutter_typeahead/flutter_typeahead.dart';
4+
75
export './src/fields/form_builder_checkbox.dart';
86
export './src/fields/form_builder_checkbox_list.dart';
97
export './src/fields/form_builder_chips_choice.dart';
@@ -13,17 +11,21 @@ export './src/fields/form_builder_color_picker.dart';
1311
export './src/fields/form_builder_date_range_picker.dart';
1412
export './src/fields/form_builder_date_time_picker.dart';
1513
export './src/fields/form_builder_dropdown.dart';
14+
export './src/fields/form_builder_image_picker.dart';
15+
export './src/fields/form_builder_image_picker.dart';
16+
export './src/fields/form_builder_phone_field.dart';
1617
export './src/fields/form_builder_radio.dart';
1718
export './src/fields/form_builder_range_slider.dart';
1819
export './src/fields/form_builder_rate.dart';
1920
export './src/fields/form_builder_segmented_control.dart';
21+
export './src/fields/form_builder_signature_pad.dart';
2022
export './src/fields/form_builder_slider.dart';
2123
export './src/fields/form_builder_stepper.dart';
2224
export './src/fields/form_builder_switch.dart';
2325
export './src/fields/form_builder_text_field.dart';
2426
export './src/fields/form_builder_touch_spin.dart';
2527
export './src/fields/form_builder_typeahead.dart';
26-
export './src/fields/form_builder_signature_pad.dart';
27-
export './src/fields/form_builder_image_picker.dart';
28-
29-
export 'package:flutter_typeahead/flutter_typeahead.dart';
28+
export './src/form_builder.dart';
29+
export './src/form_builder_custom_field.dart';
30+
export './src/form_builder_field_option.dart';
31+
export './src/form_builder_validators.dart';
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
import 'package:country_pickers/country.dart';
2+
import 'package:country_pickers/country_pickers.dart';
3+
import 'package:flutter/cupertino.dart';
4+
import 'package:flutter/material.dart';
5+
import 'package:flutter/widgets.dart';
6+
import 'package:flutter_form_builder/flutter_form_builder.dart';
7+
8+
class FormBuilderCountryPicker extends StatefulWidget {
9+
final String attribute;
10+
final List<FormFieldValidator> validators;
11+
final bool readOnly;
12+
final InputDecoration decoration;
13+
final ValueChanged onChanged;
14+
final ValueTransformer valueTransformer;
15+
16+
final TextStyle style;
17+
final FormFieldSetter onSaved;
18+
19+
// For country dialog
20+
final String searchText;
21+
final EdgeInsets titlePadding;
22+
final bool isSearchable;
23+
final Text dialogTitle;
24+
final String defaultSelectedCountryIsoCode;
25+
final List<String> priorityListByIsoCode;
26+
final List<String> countryFilterByIsoCode;
27+
final TextStyle dialogTextStyle;
28+
final bool isCupertinoPicker;
29+
final double cupertinoPickerSheetHeight;
30+
final Color cursorColor;
31+
32+
FormBuilderCountryPicker(
33+
{Key key,
34+
@required this.attribute,
35+
this.validators = const [],
36+
this.readOnly = false,
37+
this.decoration = const InputDecoration(),
38+
this.style,
39+
this.onChanged,
40+
this.valueTransformer,
41+
this.onSaved,
42+
this.searchText,
43+
this.titlePadding,
44+
this.dialogTitle,
45+
this.isSearchable,
46+
@required this.defaultSelectedCountryIsoCode,
47+
this.priorityListByIsoCode,
48+
this.countryFilterByIsoCode,
49+
this.dialogTextStyle,
50+
this.isCupertinoPicker,
51+
this.cupertinoPickerSheetHeight,
52+
this.cursorColor})
53+
: assert(defaultSelectedCountryIsoCode != null),
54+
super(key: key);
55+
56+
@override
57+
_FormBuilderCountryPickerState createState() => _FormBuilderCountryPickerState();
58+
}
59+
60+
class _FormBuilderCountryPickerState extends State<FormBuilderCountryPicker> {
61+
bool _readOnly = false;
62+
final GlobalKey<FormFieldState> _fieldKey = GlobalKey<FormFieldState>();
63+
FormBuilderState _formState;
64+
Country _selectedDialogCountry;
65+
66+
void _openCupertinoCountryPicker() => showCupertinoModalPopup<void>(
67+
context: context,
68+
builder: (BuildContext context) {
69+
return CountryPickerCupertino(
70+
pickerSheetHeight: widget.cupertinoPickerSheetHeight ?? 300.0,
71+
onValuePicked: (Country country) => setState(() => _selectedDialogCountry = country),
72+
itemFilter: widget.countryFilterByIsoCode != null
73+
? (c) => widget.countryFilterByIsoCode.contains(c.isoCode)
74+
: null,
75+
priorityList: widget.priorityListByIsoCode != null
76+
? List.generate(widget.priorityListByIsoCode.length,
77+
(index) => CountryPickerUtils.getCountryByIsoCode(widget.priorityListByIsoCode[index]))
78+
: null,
79+
);
80+
},
81+
);
82+
83+
void _openCountryPickerDialog() => showDialog(
84+
context: context,
85+
builder: (context) => Theme(
86+
data: Theme.of(context).copyWith(
87+
cursorColor: Theme.of(context).primaryColor,
88+
primaryColor: widget.cursorColor ?? Theme.of(context).primaryColor,
89+
),
90+
child: CountryPickerDialog(
91+
titlePadding: widget.titlePadding ?? EdgeInsets.all(8.0),
92+
searchCursorColor: widget.cursorColor ?? Theme.of(context).primaryColor,
93+
searchInputDecoration: InputDecoration(hintText: widget.searchText ?? 'Search...'),
94+
isSearchable: widget.isSearchable ?? true,
95+
title: widget.dialogTitle ??
96+
Text(
97+
'Select Your Country',
98+
style: widget.dialogTextStyle ?? widget.style,
99+
),
100+
onValuePicked: (Country country) => setState(() => _selectedDialogCountry = country),
101+
itemFilter: widget.countryFilterByIsoCode != null
102+
? (c) => widget.countryFilterByIsoCode.contains(c.isoCode)
103+
: null,
104+
priorityList: widget.priorityListByIsoCode != null
105+
? List.generate(widget.priorityListByIsoCode.length,
106+
(index) => CountryPickerUtils.getCountryByIsoCode(widget.priorityListByIsoCode[index]))
107+
: null,
108+
itemBuilder: _buildDialogItem,
109+
),
110+
),
111+
);
112+
113+
Widget _buildDialogItem(Country country) => Container(
114+
child: ListTile(
115+
contentPadding: EdgeInsets.zero,
116+
leading: CountryPickerUtils.getDefaultFlagImage(country),
117+
title: Text("${country.name}"),
118+
visualDensity: VisualDensity.compact,
119+
),
120+
);
121+
122+
@override
123+
void initState() {
124+
_formState = FormBuilder.of(context);
125+
_formState?.registerFieldKey(widget.attribute, _fieldKey);
126+
_selectedDialogCountry = CountryPickerUtils.getCountryByIsoCode(widget.defaultSelectedCountryIsoCode);
127+
128+
super.initState();
129+
}
130+
131+
@override
132+
void dispose() {
133+
_formState?.unregisterFieldKey(widget.attribute);
134+
super.dispose();
135+
}
136+
137+
@override
138+
Widget build(BuildContext context) {
139+
_readOnly = (_formState?.readOnly == true) ? true : widget.readOnly;
140+
141+
return FormField<Country>(
142+
key: _fieldKey,
143+
enabled: !_readOnly,
144+
initialValue: CountryPickerUtils.getCountryByIsoCode(widget.defaultSelectedCountryIsoCode),
145+
validator: (val) {
146+
for (int i = 0; i < widget.validators.length; i++) {
147+
if (widget.validators[i](val) != null) return widget.validators[i](val);
148+
}
149+
return null;
150+
},
151+
onSaved: (val) {
152+
dynamic transformed;
153+
if (widget.valueTransformer != null) {
154+
transformed = widget.valueTransformer(_selectedDialogCountry);
155+
_formState?.setAttributeValue(widget.attribute, transformed);
156+
} else
157+
_formState?.setAttributeValue(widget.attribute, _selectedDialogCountry.name);
158+
if (widget.onSaved != null) {
159+
widget.onSaved(transformed ?? _selectedDialogCountry.name);
160+
}
161+
},
162+
builder: (FormFieldState<Country> field) {
163+
return GestureDetector(
164+
onTap: widget.isCupertinoPicker != null
165+
? (widget.isCupertinoPicker ? _openCupertinoCountryPicker : _openCountryPickerDialog)
166+
: _openCountryPickerDialog,
167+
child: InputDecorator(
168+
decoration: widget.decoration.copyWith(
169+
errorText: field.errorText,
170+
),
171+
child: Row(
172+
children: [
173+
CountryPickerUtils.getDefaultFlagImage(_selectedDialogCountry),
174+
SizedBox(
175+
width: 10,
176+
),
177+
Expanded(
178+
child: Text(
179+
"${_selectedDialogCountry.name}",
180+
style: widget.style,
181+
),
182+
),
183+
],
184+
),
185+
),
186+
);
187+
},
188+
);
189+
}
190+
}

0 commit comments

Comments
 (0)