ElasticAutocomplete is a widget combines Autocomplete
and LocalStorage
.
elasticAutocompleteDemo.full.webm
- It is easy to handle the option list by
ElasticAutocompleteController
and share the same options byid
.- You can store data in local storage, which keeps data until users clean it.
- You can also store data just in memory (like session storage), which keeps data until the program terminates.
- You can use case-sensitive mode or case-insensitive mode when generating candidates. Nevertheless, if you want to generate candidates by yourself, you can set
contains
function instead.
- You can generate
fieldViewBuilder
andoptionsBuilder
simply byElasticAutocompleteController
. However, if you don't want to use a controller, you can still set them two by yourself.
- You can control the options list by
optionsBuilder
. - Besides, you can decorate
TextFormField
infieldViewBuilder
by yourself.
ElasticAutocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
const List<String> options = [
"app",
"bar",
"car"
];
return options.where((String option) {
return option.contains(textEditingValue.text);
});
}, fieldViewBuilder: (BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
void Function() onFieldSubmitted) {
return TextFormField(
autofocus: true,
// You must set controller, focusNode, and onFieldSubmitted
// in the textFormField
controller: textEditingController,
focusNode: focusNode,
onFieldSubmitted: (String value) {
onFieldSubmitted();
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
));
});
- It is easy for using
ElasticAutocompleteController
to load and set the options list. - Besides, it is easy to generate
optionsBuilder
andfieldViewBuilder
. - You can set case sensitive or case insensitive in
ElasticAutocompleteController
to effectoptionBuilder
generated by controller automatically. Default is case-sensitive. - Unlike
TextEditingController
,ElasticAutocompleteController
does not need disposed.
class MyWidgetState extends State<MyWidget> {
final _formKey = GlobalKey<FormState>();
late FocusNode _node;
late ElasticAutocompleteController<String> _elasticAutocompleteCtrl;
late TextEditingController _textEditingCtrl;
@override
void initState() {
_node = FocusNode();
_textEditingCtrl = TextEditingController();
_elasticAutocompleteCtrl =
ElasticAutocompleteController(id: 'example', caseSensitive: false);
super.initState();
}
@override
void dispose() {
_textEditingCtrl.dispose();
_node.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElasticAutocomplete<String>(
controller: _elasticAutocompleteCtrl,
// use optionsBuilder generated by controller
optionsBuilder: _elasticAutocompleteCtrl.optionsBuilder,
// use fieldViewBuilder generated by controller
fieldViewBuilder: _elasticAutocompleteCtrl.fieldViewBuilder(
decoration: const InputDecoration(
border: OutlineInputBorder(),
)),
// use textEditingCtrl to get values in the TextFormField.
textEditingController: _textEditingCtrl,
// when setting the textEditingController, set the focusNode simultaneously.
focusNode: _node),
// store new value to the memory unit
ElevatedButton(
onPressed: () async {
if (_formKey.currentState?.validate() ?? false) {
String val = _textEditingCtrl.text;
// clear the text input field
_textEditingCtrl.clear();
// store to the memory unit
await _elasticAutocompleteCtrl.store(val);
print(val);
}
},
child: const Text("send")),
// clear all options in the memory unit
ElevatedButton(
onPressed: () {
_elasticAutocompleteCtrl.clear();
},
child: const Text("clear"),
),
],
));
}
}