mirror of
https://github.com/Iconica-Development/flutter_form_wizard.git
synced 2025-05-19 19:03:47 +02:00
Merge pull request #50 from Iconica-Development/feature/multiple_choice
feat: add multiple choice form field
This commit is contained in:
commit
204d0c6ca2
4 changed files with 164 additions and 1 deletions
|
@ -142,3 +142,6 @@
|
||||||
## 6.4.0 - June 28th 2024
|
## 6.4.0 - June 28th 2024
|
||||||
- Added `FlutterFormInputDropdown` for dropdown selection
|
- Added `FlutterFormInputDropdown` for dropdown selection
|
||||||
- Added style property to `FlutterFormInputEmail`
|
- Added style property to `FlutterFormInputEmail`
|
||||||
|
|
||||||
|
## 6.5.0 - July 1st 2024
|
||||||
|
- Added `FlutterFormMultipleChoice` for multiple choice selection
|
||||||
|
|
|
@ -15,3 +15,4 @@ export 'input_phone.dart';
|
||||||
export 'input_plain_text.dart';
|
export 'input_plain_text.dart';
|
||||||
export 'input_slider/input_slider.dart';
|
export 'input_slider/input_slider.dart';
|
||||||
export 'input_switch/input_switch.dart';
|
export 'input_switch/input_switch.dart';
|
||||||
|
export 'multiple_choice.dart';
|
||||||
|
|
159
lib/src/widgets/input/input_types/multiple_choice.dart
Normal file
159
lib/src/widgets/input/input_types/multiple_choice.dart
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_form_wizard/flutter_form.dart';
|
||||||
|
|
||||||
|
class FlutterFormInputMultipleChoice extends FlutterFormInputWidget<String> {
|
||||||
|
/// Creates a [FlutterFormInputMultipleChoice].
|
||||||
|
///
|
||||||
|
/// The [controller], [options], [builder], [validationMessage] parameters
|
||||||
|
/// are required.
|
||||||
|
/// The [key], [focusNode], [label] are optional.
|
||||||
|
const FlutterFormInputMultipleChoice({
|
||||||
|
required super.controller,
|
||||||
|
required this.options,
|
||||||
|
required this.builder,
|
||||||
|
required this.validationMessage,
|
||||||
|
super.focusNode,
|
||||||
|
super.label,
|
||||||
|
super.key,
|
||||||
|
this.mainAxisExtent,
|
||||||
|
this.childAspectRatio = 1,
|
||||||
|
this.mainAxisSpacing = 0,
|
||||||
|
this.crossAxisSpacing = 0,
|
||||||
|
this.crossAxisCount = 3,
|
||||||
|
this.height,
|
||||||
|
this.shrinkwrap = true,
|
||||||
|
this.validator,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<String> options;
|
||||||
|
final double? mainAxisExtent;
|
||||||
|
final double childAspectRatio;
|
||||||
|
final double mainAxisSpacing;
|
||||||
|
final double crossAxisSpacing;
|
||||||
|
final int crossAxisCount;
|
||||||
|
final double? height;
|
||||||
|
final bool shrinkwrap;
|
||||||
|
final Widget Function(
|
||||||
|
BuildContext context,
|
||||||
|
int index,
|
||||||
|
ValueNotifier<int?> selectedIndex,
|
||||||
|
FlutterFormInputController controller,
|
||||||
|
List<String> options,
|
||||||
|
FormFieldState<String> state,
|
||||||
|
) builder;
|
||||||
|
final String? Function(String? value, String validationMessage)? validator;
|
||||||
|
final String validationMessage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
super.registerController(context);
|
||||||
|
var selectedIndex = ValueNotifier<int?>(null);
|
||||||
|
|
||||||
|
return FormField<String>(
|
||||||
|
onSaved: controller.onSaved,
|
||||||
|
validator: (value) =>
|
||||||
|
validator?.call(value, validationMessage) ??
|
||||||
|
controller.onValidate(value, validationMessage),
|
||||||
|
builder: (state) => SizedBox(
|
||||||
|
height: height,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
GridView.builder(
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
itemCount: options.length,
|
||||||
|
shrinkWrap: shrinkwrap,
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
mainAxisExtent: mainAxisExtent,
|
||||||
|
childAspectRatio: childAspectRatio,
|
||||||
|
mainAxisSpacing: mainAxisSpacing,
|
||||||
|
crossAxisSpacing: crossAxisSpacing,
|
||||||
|
crossAxisCount: crossAxisCount,
|
||||||
|
),
|
||||||
|
itemBuilder: (context, index) => ListenableBuilder(
|
||||||
|
listenable: selectedIndex,
|
||||||
|
builder: (context, widget) => builder.call(
|
||||||
|
context,
|
||||||
|
index,
|
||||||
|
selectedIndex,
|
||||||
|
controller,
|
||||||
|
options,
|
||||||
|
state,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (state.hasError)
|
||||||
|
Text(
|
||||||
|
state.errorText!,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Color(0xFFAD3645),
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
const SizedBox.shrink(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FlutterFormInputMultipleChoiceController
|
||||||
|
implements FlutterFormInputController<String> {
|
||||||
|
/// Creates a [FlutterFormInputMultipleChoiceController].
|
||||||
|
///
|
||||||
|
/// The [id] parameter specifies the unique identifier for the controller.
|
||||||
|
/// The [mandatory] parameter specifies whether the input is mandatory.
|
||||||
|
/// The [value], [checkPageTitle], [checkPageDescription], [onChanged],
|
||||||
|
/// and [onSubmit] parameters are optional.
|
||||||
|
FlutterFormInputMultipleChoiceController({
|
||||||
|
required this.id,
|
||||||
|
this.mandatory = false,
|
||||||
|
this.value,
|
||||||
|
this.checkPageTitle,
|
||||||
|
this.checkPageDescription,
|
||||||
|
this.onChanged,
|
||||||
|
this.onSubmit,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool mandatory;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String Function(String? value)? checkPageTitle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String Function(String? value)? checkPageDescription;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void Function(String? value)? onChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void Function(String? value)? onSubmit;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onSaved(String? value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? onValidate(
|
||||||
|
String? value,
|
||||||
|
String validationMessage,
|
||||||
|
) {
|
||||||
|
if (mandatory) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return validationMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_form_wizard
|
name: flutter_form_wizard
|
||||||
description: A new Flutter package project.
|
description: A new Flutter package project.
|
||||||
version: 6.4.0
|
version: 6.5.0
|
||||||
homepage: https://github.com/Iconica-Development/flutter_form_wizard
|
homepage: https://github.com/Iconica-Development/flutter_form_wizard
|
||||||
|
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
Loading…
Reference in a new issue