Open cedricDevWP opened 2 years ago
I believe you can try with manual building a field
is it possible or not ? and any example how to add multi selector ?
Not currently
@deandreamatias noted
anyone try with manual building a field with drop down package ? i try it everything fine but from builder current State value doesn't change here how i did :
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_extra_fields/form_builder_extra_fields.dart';
import '../../models/option_model.dart';
class FormBuilderSearchableDropdownMultiSelect extends StatefulWidget {
final String name;
final InputDecoration decoration;
final Future<List<OptionModel>> Function(String)? onFind;
final Widget Function(BuildContext, OptionModel, bool)? itemBuilder;
final TextFieldProps searchFieldProps;
final String noSelectedLabel;
final double fontSize;
final ValueChanged<List<String>>? selectedItem;
final String submitButtonText;
FormBuilderSearchableDropdownMultiSelect(
{Key? key,
required this.name,
required this.decoration,
required this.onFind,
this.itemBuilder,
this.searchFieldProps = const TextFieldProps(),
this.noSelectedLabel = 'Select',
this.fontSize = 16.0,
this.selectedItem,
this.submitButtonText = "SUBMIT"})
: super(key: key);
@override
State<FormBuilderSearchableDropdownMultiSelect> createState() =>
_FormBuilderSearchableDropdownMultiSelectState();
}
class _FormBuilderSearchableDropdownMultiSelectState
extends State<FormBuilderSearchableDropdownMultiSelect> {
final _popupCustomValidationKey =
GlobalKey<DropdownSearchState<OptionModel>>();
List<OptionModel> _selectedItems = [];
void setFieldValue({required FormFieldState<dynamic> field}) {
//set selected items to form builder state
List<String> value = _selectedItems.map((e) => e.value.toString()).toList();
if (widget.selectedItem != null) widget.selectedItem!(value);
print(value);
field.didChange(value);
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return FormBuilderField(
name: widget.name,
builder: (FormFieldState<dynamic> field) {
return DropdownSearch<OptionModel>.multiSelection(
key: _popupCustomValidationKey,
asyncItems: widget.onFind,
compareFn: (i, s) => i.value == s.value,
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: widget.decoration,
),
itemAsString: ((OptionModel? item) {
return "${item!.label}";
}),
onChanged: (List<OptionModel> selectedItems) {
setState(() {
_selectedItems = selectedItems;
});
setFieldValue(field: field);
},
dropdownBuilder: (context, selectedItems) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.zero,
child: selectedItems.isEmpty
? Text(
widget.noSelectedLabel,
style: theme.textTheme.bodyText2!.copyWith(
color: theme.hintColor, fontSize: widget.fontSize),
)
: Row(
children: selectedItems
.map((item) => Padding(
padding: const EdgeInsets.only(right: 10.0),
child: InputChip(
padding: EdgeInsets.zero,
label: Text(selectedItems.isEmpty
? "Select"
: item.label),
onDeleted: () {
_popupCustomValidationKey.currentState
?.removeItem(item);
setState(() {
_selectedItems = selectedItems;
});
setFieldValue(field: field);
},
),
))
.toList()),
);
},
popupProps: PopupPropsMultiSelection.dialog(
isFilterOnline: true,
showSelectedItems: true,
showSearchBox: true,
searchFieldProps: widget.searchFieldProps,
itemBuilder: widget.itemBuilder,
validationWidgetBuilder: (ctx, selectedItems) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: ElevatedButton(
child: Text(widget.submitButtonText),
style: ElevatedButton.styleFrom(
padding: EdgeInsets.all(20.0),
),
onPressed: () {
_popupCustomValidationKey.currentState?.popupOnValidate();
},
),
);
},
),
);
},
);
}
}
Can test one solution like this:
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _formKey = GlobalKey<FormBuilderState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form Example'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: FormBuilder(
key: _formKey,
child: Column(
children: [
FormBuilderDropdown(
attribute: 'options',
decoration: InputDecoration(labelText: 'Options'),
hint: Text('Select options'),
items: [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
]
.map((option) => DropdownMenuItem(
value: option,
child: Text(option),
))
.toList(),
validators: [FormBuilderValidators.required()],
),
SizedBox(height: 10),
FormBuilderCheckboxList(
attribute: 'options_checkbox',
decoration: InputDecoration(labelText: 'Options Checkbox'),
initialValue: ['Option 1'],
options: [
FormBuilderFieldOption(
value: 'Option 1',
child: Text('Option 1'),
),
FormBuilderFieldOption(
value: 'Option 2',
child: Text('Option 2'),
),
FormBuilderFieldOption(
value: 'Option 3',
child: Text('Option 3'),
),
FormBuilderFieldOption(
value: 'Option 4',
child: Text('Option 4'),
),
],
),
],
),
),
),
);
}
}
OBS: eu a gerei via Chat GPT. Infelizmente estou muito ocupado com o trabalho no momento
@WilliamCunhaCardoso i need an example FormBuilderField implement with DropDownSearch package https://pub.dev/packages/dropdown_search
any news about this ? i think it's very useful and important for app development.
Unfortunately, I lack time due to my work. So, for now, I cannot implement it :/
is it possible to use the multi selector feature?