oi-narendra / multiselect-dropdown

Streamlined Flutter widget for versatile multi-selection with extensive customization.
https://pub.dev/packages/multi_dropdown
GNU General Public License v3.0
73 stars 83 forks source link

future parameter does not have search keyword #142

Open Abdulvaliy opened 3 months ago

Abdulvaliy commented 3 months ago

What I want to achieve is to show user data from network. when user tries to search items, future needs to be called with search keyword parameter and return user requested data.

What is wrong is search is working only first fetched data.

case: Let's say there are 1000 data on network (backend -> database). When user tap the input first 20 items are returned. When user uses search with some keyword, it should look up 1000 data from network, not fetched 20 items.

This is how I'm using (creating a component)

class SearchableMultiDropdown extends StatelessWidget {
  const SearchableMultiDropdown({
    super.key,
    required this.suggestionApi,
    this.controller,
    this.onChanged,
    this.label,
    this.errorText,
    this.apiParams,
    this.required,
  });

  final String? label;
  final MultiSelectController<Suggestion>? controller;
  final String? errorText;
  final Future<APIResponse> Function(Map<String, dynamic>) suggestionApi;
  final Function(Suggestion?)? onChanged;
  final Map<String, dynamic>? apiParams;
  final bool? required;

  @override
  Widget build(BuildContext context) {
    return MultiDropdown<Suggestion>.future(
      controller: controller,

      /// It would be better with parameter within the function
      // future: (String searchKeyword) async {
      future: () async {
        List<Suggestion> suggestions = [];
        Map<String, dynamic> params = apiParams ?? {};

        /// I have tried to get search input value from controller, but there is not in it
        // params['searchKeyword'] = controller.searchKey;
        final apiResponse = await suggestionApi(params);

        if (apiResponse.success == false) return Future(() => []);

        for (Map suggestion in apiResponse.data) {
          suggestions.add(Suggestion.fromJson(suggestion));
        }
        return Future(() => suggestions.map((e) => DropdownItem(label: e.name ?? '', value: e)).toList());
      },
      searchEnabled: true,
      fieldDecoration: FieldDecoration(
        labelStyle: kTextInputLabel,
        labelText: "$label${required == true ? "*" : ""}",
        hintText: null,
        showClearIcon: true,
        border: kOutlineNumberBorder,
        focusedBorder: kOutlineFocusBorder,
        suffixIcon: Icon(Icons.arrow_drop_down_sharp, color: kPrimaryBaseColor, size: 36),
        hintStyle: kTextInputPlaceholder,
        padding: const EdgeInsets.all(12.0),
      ),
      searchDecoration: SearchFieldDecoration(
        border: kOutlineNumberBorder,
        focusedBorder: kOutlineFocusBorder,
        hintText: 'Поиск',
      ),
      chipDecoration: ChipDecoration(
        backgroundColor: kGreyShade300,
        deleteIcon: Icon(Icons.close, color: kGreyShade400, size: 18),
        runSpacing: 4,
        spacing: 4,
      ),
      dropdownItemDecoration: DropdownItemDecoration(
        selectedIcon: Icon(Icons.check, color: kPrimaryBaseColor),
        selectedBackgroundColor: kGreyShade200,
        selectedTextColor: kPrimaryBaseColor,
      ),
      dropdownDecoration: const DropdownDecoration(elevation: 7),
      itemSeparator: Divider(height: 0, color: kGreyShade300),
    );
  }
}