I want to implement a text search in Dropdown Flutter/Dart.
I want to use Flutter/Dart DropdownMenu class.
I don't want to use DropDownButton b/c it does not have a search.
The DropdownMenu Search class has SearchCallback
.
The DropdownMenu class has 3 key things: List
, Controller
, and SearchCallback
.
I want to use Controller to search the Controller's input text.
The SearchCallback
has two things: entries and query.
I am not certain how to define the SearchCallback
correctly.
Could you please provide example of SearchCallback
.
Thank You
I want to implement a text search in Dropdown Flutter/Dart.
I want to use Flutter/Dart DropdownMenu class.
I don't want to use DropDownButton b/c it does not have a search.
The DropdownMenu Search class has SearchCallback
.
The DropdownMenu class has 3 key things: List
, Controller
, and SearchCallback
.
I want to use Controller to search the Controller's input text.
The SearchCallback
has two things: entries and query.
I am not certain how to define the SearchCallback
correctly.
Could you please provide example of SearchCallback
.
Thank You
Share Improve this question edited Nov 19, 2024 at 11:07 sillycone 5263 silver badges13 bronze badges asked Nov 16, 2024 at 23:45 DktPhl2018DktPhl2018 4831 gold badge5 silver badges12 bronze badges2 Answers
Reset to default 1Imagine a function that takes a list of DropdownMenuEntry
s ("entries") and a String
("query"), and returns an int
for the index of a DropdownMenuEntry
in the list that matches the string. This is the function you are passing as the SearchCallback
parameter. If you leave it blank, it will default to a function that returns the index of first entry that contains the query anywhere in it. You can write your own function to customize the search. For example, here is a function you could write that returns the index of the first entry that matches the query exactly.
DropdownMenu<Text>(
searchCallback: (List<DropdownMenuEntry<Text>> entries, String query) {
if (query.isEmpty) {
return null;
}
final int index = entries.indexWhere((DropdownMenuEntry<Text> entry) => entry.label == query);
return index != -1 ? index : null;
},
dropdownMenuEntries: const <DropdownMenuEntry<Text>>[],
)
I used flutter auto complete widget like below and also I implementing this using TextEditingController also in generic clean way let me know if you have any questions
class DropdownSearch<T extends DropAble> extends StatelessWidget {
final TextEditingController textController;
final List<T> items;
final void Function(T) onSuggestionSelected;
final bool required;
final String placeHolder;
final String label;
final String? Function(T?) validator;
const DropdownSearch({
super.key,
required this.textController,
required this.items,
required this.onSuggestionSelected,
this.required = false,
this.label = "",
this.placeHolder = "",
required this.validator,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${required ? "* " : ""}$label",
style: Theme.of(context).textTheme.labelMedium,
),
const SizedBox(
height: 14,
),
RawAutocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
return items.map((e)=>e.name ?? "").toList()
.where((item) =>
(item).toLowerCase().contains(textEditingValue.text.toLowerCase()))
.toList();
},
onSelected: (String selection) {
textController.text = selection;
T? item = items.firstWhereOrNull((element) => element.name == selection);
if (item != null) {
onSuggestionSelected(item);
}
},
fieldViewBuilder: (
BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
VoidCallback onFieldSubmitted,
) {
return TextFormField(
controller: textEditingController,
decoration: InputDecoration(
hintText: placeHolder,
),
focusNode: focusNode,
onFieldSubmitted: (String value) {
T? item = items.firstWhereOrNull((element) => element.name == value);
onFieldSubmitted();
if (item != null) {
onSuggestionSelected(item);
}
},
// validator: vali,
);
},
optionsViewBuilder: (
BuildContext context,
AutocompleteOnSelected<String> onSelected,
Iterable<String> options,
) {
return Align(
alignment: Get.locale?.languageCode == "ar" ? Alignment.topRight : Alignment.topLeft,
child: Material(
elevation: 4.0,
child: SizedBox(
width: Get.width-70,
child: ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.all(8.0),
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final option = options.elementAt(index);
return GestureDetector(
onTap: () {
textController.text = option;
onSelected(option);
T? item = items.firstWhereOrNull((element) => element.name == option);
if(item != null){
onSuggestionSelected(item);
}
},
child: ListTile(
title: Text(option),
),
);
},
),
),
),
);
},
),
const SizedBox(
height: 14,
),
],
),
);
}
}