showPlexAutoCompleteSelectionList<T> function
dynamic
showPlexAutoCompleteSelectionList<T>(
- BuildContext context, {
- FocusNode? focusNode,
- required Future<
List< asyncItems(T> >- String query
- required String itemText(
- T item
- required dynamic onSelect(
- T item
- int minQueryLength = 2,
- Widget itemWidget(
- dynamic item
- Widget leadingIcon(
- T item
- bool showBarCode = false,
- double inputDelay = 1000,
Implementation
showPlexAutoCompleteSelectionList<T>(
BuildContext context, {
FocusNode? focusNode,
required Future<List<T>> Function(String query) asyncItems,
required String Function(T item) itemText,
required Function(T item) onSelect,
int minQueryLength = 2,
Widget Function(dynamic item)? itemWidget,
Widget Function(T item)? leadingIcon,
bool showBarCode = false,
double inputDelay = 1000,
}) async {
DateTime lastInputAt = DateTime.now();
String? query;
String? searchedQuery;
var inputController = TextEditingController();
var filteredListController = PlexWidgetController<List<T>>(data: List.empty());
var loadingController = PlexWidgetController<int>(data: 0);
if (focusNode == null) {
focusNode = FocusNode();
focusNode.requestFocus();
}
onSearch(String data) async {
lastInputAt = DateTime.now();
query = data;
if (data.length < minQueryLength) return;
delay(() async {
if (DateTime.now().difference(lastInputAt).inMilliseconds < inputDelay) return;
if (query == null || query!.length < minQueryLength) return;
if (searchedQuery == query) return;
loadingController.increment();
searchedQuery = query;
var filteredList = await asyncItems.call(searchedQuery!);
loadingController.decrement();
filteredListController.setValue(filteredList);
}, delayMillis: inputDelay.toInt());
}
// ignore: use_build_context_synchronously
showModalBottomSheet(
enableDrag: true,
showDragHandle: true,
useSafeArea: true,
isScrollControlled: true,
context: context,
builder: (context) {
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
constraints: const BoxConstraints(maxHeight: 500),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
child: PlexWidget(
controller: loadingController,
createWidget: (context, data) {
return PlexFormFieldInput(
properties: PlexFormFieldGeneric(title: "Search", enabled: data <= 0),
inputController: inputController,
inputHint: "Search Here...",
inputFocusNode: focusNode,
inputOnChange: (value) async {
onSearch(value);
},
);
},
),
),
if (showBarCode) ...{
PlexFormFieldButton(
buttonIcon: Icon(Icons.barcode_reader),
buttonClick: () async {
var result = await Plex.to(PlexScanner());
if (result != null) {
inputController.text = result.toString();
onSearch(inputController.text);
}
},
)
}
],
),
spaceSmall(),
PlexWidget(
controller: loadingController,
createWidget: (context, data) {
if (data > 0) {
return SizedBox(
width: 50,
height: 50,
child: const PlexLoaderV2(),
);
}
return Container();
}),
spaceSmall(),
Expanded(
child: PlexWidget(
controller: filteredListController,
createWidget: (con, data) {
var listData = data as List<T>;
return ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: listData.length,
itemBuilder: (context, index) {
var item = listData[index];
if (itemWidget != null) {
return InkWell(
onTap: () {
onSelect.call(item);
Get.back();
},
child: itemWidget.call(item),
);
}
return ListTile(
selectedTileColor: Colors.green.withValues(alpha: 0.25),
leading: leadingIcon?.call(item),
title: Text(itemText.call(item)),
onTap: () {
onSelect.call(item);
Get.back();
},
);
},
);
},
),
),
],
),
),
);
},
);
}