Is there an equivalent widget in flutter to the “select multiple” element in HTML
Is there an equivalent widget in flutter to the “select multiple” element in HTML
I am searching for a widget in flutter that is equal to
<select multiple=""></select>
in flutter.
An example implementation (for the web) is MaterializeCSS Select Multiple
As seen above I should be able to provide a list of items (with some of them preselected) and at the end retrieve a list of selected items or a map or something else.
An example implementation or a link to a documentation is very appreciated.
1 Answer
1
I don't think that a widget like that currently exists in Flutter, but you can build one yourself.
On mobile phones with limited screen space it would probably make sense to display a dialog with a submit button, like this native Android dialog.
Here is a rough sketch how to implement such a dialog in less than 100 lines of code:
class MultiSelectDialogItem<V>
const MultiSelectDialogItem(this.value, this.label);
final V value;
final String label;
class MultiSelectDialog<V> extends StatefulWidget
MultiSelectDialog(Key key, this.items, this.initialSelectedValues) : super(key: key);
final List<MultiSelectDialogItem<V>> items;
final Set<V> initialSelectedValues;
@override
State<StatefulWidget> createState() => _MultiSelectDialogState<V>();
class _MultiSelectDialogState<V> extends State<MultiSelectDialog<V>>
final _selectedValues = Set<V>();
void initState()
super.initState();
if (widget.initialSelectedValues != null)
_selectedValues.addAll(widget.initialSelectedValues);
void _onItemCheckedChange(V itemValue, bool checked)
setState(()
if (checked)
_selectedValues.add(itemValue);
else
_selectedValues.remove(itemValue);
);
void _onCancelTap()
Navigator.pop(context);
void _onSubmitTap()
Navigator.pop(context, _selectedValues);
@override
Widget build(BuildContext context)
return AlertDialog(
title: Text('Select animals'),
contentPadding: EdgeInsets.only(top: 12.0),
content: SingleChildScrollView(
child: ListTileTheme(
contentPadding: EdgeInsets.fromLTRB(14.0, 0.0, 24.0, 0.0),
child: ListBody(
children: widget.items.map(_buildItem).toList(),
),
),
),
actions: <Widget>[
FlatButton(
child: Text('CANCEL'),
onPressed: _onCancelTap,
),
FlatButton(
child: Text('OK'),
onPressed: _onSubmitTap,
)
],
);
Widget _buildItem(MultiSelectDialogItem<V> item)
final checked = _selectedValues.contains(item.value);
return CheckboxListTile(
value: checked,
title: Text(item.label),
controlAffinity: ListTileControlAffinity.leading,
onChanged: (checked) => _onItemCheckedChange(item.value, checked),
);
You can use it like this:
void _showMultiSelect(BuildContext context) async
final items = <MultiSelectDialogItem<int>>[
MultiSelectDialogItem(1, 'Dog'),
MultiSelectDialogItem(2, 'Cat'),
MultiSelectDialogItem(3, 'Mouse'),
];
final selectedValues = await showDialog<Set<int>>(
context: context,
builder: (BuildContext context)
return MultiSelectDialog(
items: items,
initialSelectedValues: [1, 3].toSet(),
);
,
);
print(selectedValues);
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.