From 320dd21920b239038e76b1d9be2084c14009fde5 Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 30 Jul 2022 13:49:22 +0200 Subject: [PATCH 1/7] build: Update minimal versions --- example/pubspec.lock | 2 +- example/pubspec.yaml | 3 ++- pubspec.lock | 2 +- pubspec.yaml | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index be137becb5..c2862b3b34 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -190,5 +190,5 @@ packages: source: hosted version: "2.1.2" sdks: - dart: ">=2.17.0-206.0.dev <3.0.0" + dart: ">=2.17.0 <3.0.0" flutter: ">=3.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 127c82f6c5..1464469175 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -4,7 +4,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.17.0 <3.0.0" + flutter: ">=3.0.0" dependencies: cupertino_icons: any diff --git a/pubspec.lock b/pubspec.lock index d3f265b51e..a4dd5de741 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -164,5 +164,5 @@ packages: source: hosted version: "2.1.2" sdks: - dart: ">=2.17.0-206.0.dev <3.0.0" + dart: ">=2.17.0 <3.0.0" flutter: ">=3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5335a44b24..ca3c387ef2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,11 +1,11 @@ name: flutter_form_builder description: This package helps in creation of forms in Flutter by removing the boilerplate code, reusing validation, react to changes, and collect final user input. version: 7.5.0 -homepage: https://github.com/flutter-form-builder-ecosystem/flutter_form_builder +repository: https://github.com/flutter-form-builder-ecosystem/flutter_form_builder issue_tracker: https://github.com/flutter-form-builder-ecosystem/flutter_form_builder/issues environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.17.0 <3.0.0" flutter: ">=3.0.0" dependencies: From 54987d5b233512b1d0aea0d4747e1c817f3f3631 Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 30 Jul 2022 13:50:13 +0200 Subject: [PATCH 2/7] feat: Remove parameters related to decoration --- example/lib/main.dart | 24 ++-- example/lib/sources/complete_form.dart | 12 +- lib/src/fields/form_builder_dropdown.dart | 152 +++++++++------------- 3 files changed, 82 insertions(+), 106 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 79bf8a8440..4b62864639 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -177,9 +177,13 @@ class _CompleteFormState extends State { name: 'age', decoration: InputDecoration( labelText: 'Age', - suffixIcon: _ageHasError - ? const Icon(Icons.error, color: Colors.red) - : const Icon(Icons.check, color: Colors.green), + suffixIcon: IconButton( + icon: const Icon(Icons.plus_one), + onPressed: () { + _formKey.currentState!.fields['age'] + ?.didChange('14'); + }, + ), ), onChanged: (val) { setState(() { @@ -203,13 +207,15 @@ class _CompleteFormState extends State { name: 'gender', decoration: InputDecoration( labelText: 'Gender', - suffix: _genderHasError - ? const Icon(Icons.error) - : const Icon(Icons.check), + suffix: IconButton( + icon: const Icon(Icons.close), + onPressed: () { + _formKey.currentState!.fields['gender']?.reset(); + }, + ), + hintText: 'Select Gender', ), - // initialValue: 'Male', - allowClear: true, - hint: const Text('Select Gender'), + initialValue: 'Male', validator: FormBuilderValidators.compose( [FormBuilderValidators.required()]), items: genderOptions diff --git a/example/lib/sources/complete_form.dart b/example/lib/sources/complete_form.dart index 229d9ec3fe..2d560bb7ca 100644 --- a/example/lib/sources/complete_form.dart +++ b/example/lib/sources/complete_form.dart @@ -171,14 +171,12 @@ class _CompleteFormState extends State { // autovalidate: true, name: 'gender', decoration: InputDecoration( - labelText: 'Gender', - suffix: _genderHasError - ? const Icon(Icons.error) - : const Icon(Icons.check), - ), + labelText: 'Gender', + suffix: _genderHasError + ? const Icon(Icons.error) + : const Icon(Icons.check), + hintText: 'Select Gender'), // initialValue: 'Male', - allowClear: true, - hint: const Text('Select Gender'), validator: FormBuilderValidators.compose( [FormBuilderValidators.required()]), items: genderOptions diff --git a/lib/src/fields/form_builder_dropdown.dart b/lib/src/fields/form_builder_dropdown.dart index 411b9ffd6e..4e40a3af49 100644 --- a/lib/src/fields/form_builder_dropdown.dart +++ b/lib/src/fields/form_builder_dropdown.dart @@ -9,9 +9,10 @@ class FormBuilderDropdown extends FormBuilderField { /// If the [onChanged] callback is null or the list of items is null /// then the dropdown button will be disabled, i.e. its arrow will be /// displayed in grey and it will not respond to input. A disabled button - /// will display the [disabledHint] widget if it is non-null. If - /// [disabledHint] is also null but [hint] is non-null, [hint] will instead - /// be displayed. + /// will display the [disabledHint] widget if it is non-null. + /// + /// If [decoration.hint] and variations is non-null and [disabledHint] is null, + /// the [decoration.hint] widget will be displayed instead. final List> items; /// A placeholder widget that is displayed by the dropdown button. @@ -23,8 +24,9 @@ class FormBuilderDropdown extends FormBuilderField { /// A message to show when the dropdown is disabled. /// - /// Displayed if [items] or [onChanged] is null. If [hint] is non-null and - /// [disabledHint] is null, the [hint] widget will be displayed instead. + /// Displayed if [items] or [onChanged] is null. If [decoration.hint] and + /// variations is non-null and [disabledHint] is null, the [decoration.hint] + /// widget will be displayed instead. final Widget? disabledHint; /// Called when the dropdown button is tapped. @@ -219,7 +221,7 @@ class FormBuilderDropdown extends FormBuilderField { /// Defines the corner radii of the menu's rounded rectangle shape. /// - /// The radii of the first menu item's top left and right corners are + /// The radius of the first menu item's top left and right corners are /// defined by the corresponding properties of the [borderRadius]. /// Similarly, the radii of the last menu item's bottom and right corners /// are defined by the corresponding properties of the [borderRadius]. @@ -227,32 +229,34 @@ class FormBuilderDropdown extends FormBuilderField { /// Creates field for Dropdown button FormBuilderDropdown({ - Key? key, - //From Super - required String name, - FormFieldValidator? validator, - T? initialValue, - InputDecoration decoration = const InputDecoration(), - ValueChanged? onChanged, - ValueTransformer? valueTransformer, - bool enabled = true, - FormFieldSetter? onSaved, - AutovalidateMode autovalidateMode = AutovalidateMode.disabled, - VoidCallback? onReset, - FocusNode? focusNode, + super.key, + required super.name, + super.validator, + super.initialValue, + super.decoration, + super.onChanged, + super.valueTransformer, + super.enabled, + super.onSaved, + super.autovalidateMode = AutovalidateMode.disabled, + super.onReset, + super.focusNode, required this.items, this.isExpanded = true, this.isDense = true, this.elevation = 8, this.iconSize = 24.0, - this.hint, + @Deprecated('Please use decoration.hint and variations to set your desired label') + this.hint, this.style, this.disabledHint, this.icon, this.iconDisabledColor, this.iconEnabledColor, - this.allowClear = false, - this.clearIcon = const Icon(Icons.close), + @Deprecated('Please use decoration.suffix to set your desired behavior') + this.allowClear = false, + @Deprecated('Please use decoration.suffixIcon to set your desired icon') + this.clearIcon = const Icon(Icons.close), this.onTap, this.autofocus = false, this.shouldRequestFocus = false, @@ -264,23 +268,9 @@ class FormBuilderDropdown extends FormBuilderField { this.enableFeedback, this.borderRadius, this.alignment = AlignmentDirectional.centerStart, - }) : /*: assert(allowClear == true || clearIcon != null)*/ super( - key: key, - initialValue: initialValue, - name: name, - validator: validator, - valueTransformer: valueTransformer, - onChanged: onChanged, - autovalidateMode: autovalidateMode, - onSaved: onSaved, - enabled: enabled, - onReset: onReset, - decoration: decoration, - focusNode: focusNode, + }) : super( builder: (FormFieldState field) { final state = field as _FormBuilderDropdownState; - // DropdownButtonFormField - // TextFormField void changeValue(T? value) { if (shouldRequestFocus) { @@ -290,60 +280,42 @@ class FormBuilderDropdown extends FormBuilderField { } return InputDecorator( - decoration: state.decoration.copyWith( - floatingLabelBehavior: hint == null - ? decoration.floatingLabelBehavior - : FloatingLabelBehavior.always, - ), + decoration: state.decoration, isEmpty: state.value == null, - child: Row( - children: [ - Expanded( - child: DropdownButtonHideUnderline( - child: DropdownButton( - isExpanded: isExpanded, - hint: hint, - items: items, - value: field.value, - style: style, - isDense: isDense, - disabledHint: field.value != null - ? (items - .firstWhereOrNull((dropDownItem) => - dropDownItem.value == field.value) - ?.child ?? - Text(field.value.toString())) - : disabledHint, - elevation: elevation, - iconSize: iconSize, - icon: icon, - iconDisabledColor: iconDisabledColor, - iconEnabledColor: iconEnabledColor, - onChanged: state.enabled - ? (value) => changeValue(value) - : null, - onTap: onTap, - focusNode: state.effectiveFocusNode, - autofocus: autofocus, - dropdownColor: dropdownColor, - focusColor: focusColor, - itemHeight: itemHeight, - selectedItemBuilder: selectedItemBuilder, - menuMaxHeight: menuMaxHeight, - borderRadius: borderRadius, - enableFeedback: enableFeedback, - alignment: alignment, - ), - ), - ), - if (allowClear && state.enabled && field.value != null) ...[ - const VerticalDivider(), - InkWell( - onTap: () => changeValue(null), - child: clearIcon, - ), - ] - ], + child: DropdownButtonHideUnderline( + child: DropdownButton( + isExpanded: isExpanded, + hint: hint, + items: items, + value: field.value, + style: style, + isDense: isDense, + disabledHint: field.value != null + ? (items + .firstWhereOrNull((dropDownItem) => + dropDownItem.value == field.value) + ?.child ?? + Text(field.value.toString())) + : disabledHint, + elevation: elevation, + iconSize: iconSize, + icon: icon, + iconDisabledColor: iconDisabledColor, + iconEnabledColor: iconEnabledColor, + onChanged: + state.enabled ? (value) => changeValue(value) : null, + onTap: onTap, + focusNode: state.effectiveFocusNode, + autofocus: autofocus, + dropdownColor: dropdownColor, + focusColor: focusColor, + itemHeight: itemHeight, + selectedItemBuilder: selectedItemBuilder, + menuMaxHeight: menuMaxHeight, + borderRadius: borderRadius, + enableFeedback: enableFeedback, + alignment: alignment, + ), ), ); }, From 0d0e657fa776c6e433e2559652d51a2e500e7eb0 Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 30 Jul 2022 13:50:54 +0200 Subject: [PATCH 3/7] docs: Add especifc use case --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/README.md b/README.md index 2cf47263ce..c6b989b0e2 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Also included are common ready-made form input fields for FormBuilder. This give [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/flutter-form-builder-ecosystem/flutter_form_builder/Base?logo=github&style=for-the-badge)](https://github.com/flutter-form-builder-ecosystem/flutter_form_builder/actions/workflows/base.yaml) [![Codecov](https://img.shields.io/codecov/c/github/flutter-form-builder-ecosystem/flutter_form_builder?logo=codecov&style=for-the-badge)](https://codecov.io/gh/flutter-form-builder-ecosystem/flutter_form_builder/) [![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/flutter-form-builder-ecosystem/flutter_form_builder?logo=codefactor&style=for-the-badge)](https://www.codefactor.io/repository/github/flutter-form-builder-ecosystem/flutter_form_builder) +[![Discord](https://img.shields.io/discord/985922433578053673?logo=discord&style=for-the-badge)](https://discord.com/invite/25KNPMJQf2) ___ - [Features](#features) @@ -266,6 +267,57 @@ FormBuilderRadioGroup( ), ``` +#### Implement reset, clear or other button into FormBuilderField + +If you can add some button to reset specific field, can use the `decoration` parameter like this: + +```dart +List genderOptions = ['Male', 'Female', 'Other']; + +FormBuilderDropdown( + name: 'gender', + decoration: InputDecoration( + labelText: 'Gender', + initialValue: 'Male', + suffix: IconButton( + icon: const Icon(Icons.close), + onPressed: () { + _formKey.currentState!.fields['gender'] + ?.reset(); + }, + ), + hintText: 'Select Gender', + ), + items: genderOptions + .map((gender) => DropdownMenuItem( + alignment: AlignmentDirectional.center, + value: gender, + child: Text(gender), + )) + .toList(), +), +``` + +Or if is allowed by the field, set a value like this: + +```dart +FormBuilderTextField( + name: 'age', + decoration: InputDecoration( + labelText: 'Age', + suffixIcon: IconButton( + icon: const Icon(Icons.plus_one), + onPressed: () { + _formKey.currentState!.fields['age'] + ?.didChange('14'); + }, + ), + ), + initialValue: '13', + keyboardType: TextInputType.number, +), +``` + ## Support ### Contribute From 67a83a3f96b2d7da5f67402d610954eff71d648e Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 30 Jul 2022 16:17:27 +0200 Subject: [PATCH 4/7] fix: Revert commit file --- example/lib/main.dart | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 4b62864639..050ae19928 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -177,13 +177,9 @@ class _CompleteFormState extends State { name: 'age', decoration: InputDecoration( labelText: 'Age', - suffixIcon: IconButton( - icon: const Icon(Icons.plus_one), - onPressed: () { - _formKey.currentState!.fields['age'] - ?.didChange('14'); - }, - ), + suffixIcon: _ageHasError + ? const Icon(Icons.error, color: Colors.red) + : const Icon(Icons.check, color: Colors.green), ), onChanged: (val) { setState(() { @@ -207,15 +203,12 @@ class _CompleteFormState extends State { name: 'gender', decoration: InputDecoration( labelText: 'Gender', - suffix: IconButton( - icon: const Icon(Icons.close), - onPressed: () { - _formKey.currentState!.fields['gender']?.reset(); - }, + suffix: _genderHasError + ? const Icon(Icons.error) + : const Icon(Icons.check), ), hintText: 'Select Gender', ), - initialValue: 'Male', validator: FormBuilderValidators.compose( [FormBuilderValidators.required()]), items: genderOptions From 5c9c66ac95703c03c0993de14807bda5a826f33a Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 30 Jul 2022 16:18:18 +0200 Subject: [PATCH 5/7] style: Improve identation --- example/lib/sources/complete_form.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/lib/sources/complete_form.dart b/example/lib/sources/complete_form.dart index 2d560bb7ca..c85720fbf8 100644 --- a/example/lib/sources/complete_form.dart +++ b/example/lib/sources/complete_form.dart @@ -175,7 +175,8 @@ class _CompleteFormState extends State { suffix: _genderHasError ? const Icon(Icons.error) : const Icon(Icons.check), - hintText: 'Select Gender'), + hintText: 'Select Gender', + ), // initialValue: 'Male', validator: FormBuilderValidators.compose( [FormBuilderValidators.required()]), From 32ba298185778917e197fd1526ef5f0e1b8d9b23 Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 30 Jul 2022 14:58:33 +0000 Subject: [PATCH 6/7] fix: Remove extra parentesis --- example/lib/main.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 050ae19928..e127b814ca 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -206,7 +206,6 @@ class _CompleteFormState extends State { suffix: _genderHasError ? const Icon(Icons.error) : const Icon(Icons.check), - ), hintText: 'Select Gender', ), validator: FormBuilderValidators.compose( From 7fd2a2cddeca91726de5cdec74b6e51e18e89b02 Mon Sep 17 00:00:00 2001 From: Matias de Andrea Date: Sat, 30 Jul 2022 17:23:48 +0200 Subject: [PATCH 7/7] style: Format file --- example/lib/sources/complete_form.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/example/lib/sources/complete_form.dart b/example/lib/sources/complete_form.dart index c85720fbf8..5764e4840d 100644 --- a/example/lib/sources/complete_form.dart +++ b/example/lib/sources/complete_form.dart @@ -171,11 +171,11 @@ class _CompleteFormState extends State { // autovalidate: true, name: 'gender', decoration: InputDecoration( - labelText: 'Gender', - suffix: _genderHasError - ? const Icon(Icons.error) - : const Icon(Icons.check), - hintText: 'Select Gender', + labelText: 'Gender', + suffix: _genderHasError + ? const Icon(Icons.error) + : const Icon(Icons.check), + hintText: 'Select Gender', ), // initialValue: 'Male', validator: FormBuilderValidators.compose(