Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FormBuilderSearchableDropdown] add multi selector #11

Open
cedricDevWP opened this issue Mar 28, 2022 · 9 comments
Open

[FormBuilderSearchableDropdown] add multi selector #11

cedricDevWP opened this issue Mar 28, 2022 · 9 comments
Labels
enhancement New feature or request

Comments

@cedricDevWP
Copy link

is it possible to use the multi selector feature?

@WilliamCunhaCardoso
Copy link

I believe you can try with manual building a field

@danvick danvick added the enhancement New feature or request label Apr 22, 2022
@deandreamatias deandreamatias transferred this issue from flutter-form-builder-ecosystem/flutter_form_builder Jul 12, 2022
@YouSour
Copy link

YouSour commented Dec 22, 2022

is it possible or not ? and any example how to add multi selector ?

@deandreamatias
Copy link
Contributor

Not currently

@YouSour
Copy link

YouSour commented Dec 23, 2022

@deandreamatias noted

@YouSour
Copy link

YouSour commented Dec 23, 2022

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

@WilliamCunhaCardoso
Copy link

WilliamCunhaCardoso commented Dec 23, 2022

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

@YouSour
Copy link

YouSour commented Dec 24, 2022

@WilliamCunhaCardoso i need an example FormBuilderField implement with DropDownSearch package https://pub.dev/packages/dropdown_search

@YouSour
Copy link

YouSour commented Feb 9, 2023

any news about this ? i think it's very useful and important for app development.

@WilliamCunhaCardoso
Copy link

Unfortunately, I lack time due to my work. So, for now, I cannot implement it :/

@deandreamatias deandreamatias changed the title FormBuilderSearchableDropdown add multi selector [FormBuilderSearchableDropdown] add multi selector Feb 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants