showPlexMultiSelection<T> function

dynamic showPlexMultiSelection<T>(
  1. BuildContext context, {
  2. List<T>? items,
  3. Future<List<T>>? asyncItems,
  4. List<T>? initialSelection,
  5. FocusNode? focusNode,
  6. required String itemText(
    1. T item
    ),
  7. required dynamic onSelect(
    1. List<T> items
    ),
  8. Widget itemWidget(
    1. dynamic item
    )?,
  9. Widget leadingIcon(
    1. T item
    )?,
  10. bool onSearch(
    1. String query,
    2. dynamic item
    )?,
})

Implementation

showPlexMultiSelection<T>(
  BuildContext context, {
  List<T>? items,
  Future<List<T>>? asyncItems,
  List<T>? initialSelection,
  FocusNode? focusNode,
  required String Function(T item) itemText,
  required Function(List<T> items) onSelect,
  Widget Function(dynamic item)? itemWidget,
  Widget Function(T item)? leadingIcon,
  bool Function(String query, dynamic item)? onSearch,
}) async {
  var originalListData = items;
  originalListData ??= await asyncItems;
  if (originalListData == null) throw Exception("Items are null");

  var inputController = TextEditingController();
  var filteredListController = PlexWidgetController<List<T>>(data: originalListData);

  var selectionList = List<T>.empty(growable: true);
  if (initialSelection != null) {
    selectionList.addAll(initialSelection);
  }

  if (focusNode == null) {
    focusNode = FocusNode();
    focusNode.requestFocus();
  }

  // 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(
            children: [
              Row(
                children: [
                  Expanded(
                    child: PlexFormFieldInput(
                      properties: PlexFormFieldGeneric.title("Search"),
                      inputController: inputController,
                      inputFocusNode: focusNode,
                      inputHint: "Search here...",
                      inputOnChange: (data) {
                        var query = data.toLowerCase();
                        if (query.isEmpty) {
                          filteredListController.setValue(originalListData!);
                        }
                        var filteredList = originalListData!.where((element) {
                          if (onSearch != null) {
                            return onSearch.call(query, element);
                          }
                          return itemText(element).toLowerCase().contains(query);
                        }).toList();
                        filteredListController.setValue(filteredList);
                      },
                    ),
                  ),
                  PlexFormFieldButton(
                    properties: PlexFormFieldGeneric.title("Done"),
                    buttonClick: () {
                      onSelect.call(selectionList);
                      Get.back();
                    },
                  ),
                ],
              ),
              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: () {
                                var prevItem = selectionList.firstWhereOrNull((element) => itemText(item) == itemText(element));
                                if (prevItem == null) {
                                  selectionList.add(item);
                                } else {
                                  selectionList.removeWhere((element) => itemText(item) == itemText(element));
                                }
                                filteredListController.setValue(filteredListController.data);
                                onSelect.call(selectionList);
                              },
                              child: itemWidget.call(item),
                            );
                          }
                          return ListTile(
                            leading: leadingIcon?.call(item),
                            title: Text(itemText.call(item)),
                            trailing: Checkbox(
                              value: selectionList.firstWhereOrNull((element) => itemText(item) == itemText(element)) != null,
                              onChanged: (value) {
                                if (value == true) {
                                  selectionList.add(item);
                                } else {
                                  selectionList.removeWhere((element) => itemText(item) == itemText(element));
                                }
                                filteredListController.setValue(filteredListController.data);
                                onSelect.call(selectionList);
                              },
                            ),
                            onTap: () {
                              var prevItem = selectionList.firstWhereOrNull((element) => itemText(item) == itemText(element));
                              if (prevItem == null) {
                                selectionList.add(item);
                              } else {
                                selectionList.removeWhere((element) => itemText(item) == itemText(element));
                              }
                              filteredListController.setValue(filteredListController.data);
                            },
                          );
                        },
                      );
                    }),
              ),
            ],
          ),
        ),
      );
    },
  );
}