下拉搜索 pkge 中的客户名称首先显示前 20 个名称,如果搜索单词,则需要在 api 中进行搜索并动态检索名称

问题描述 投票:0回答:1
 Future<List<ProductModel>> getcustomer(String filter, BuildContext context) async {
    print('Searching with filter: $filter');  // Debugging line

    final data = Provider.of<MaterialPickupProvider>(context, listen: false);

    // Make API call
    await data.FetchCalibrationcustomer(filter);

    print('Fetched customers: ${data.fetchcustomer.length}'); // Debugging line

    return data.fetchcustomer; // Returning fetched customers
  }

 Consumer<MaterialPickupProvider>(builder: (context,calibprov,child){

              return Container(
              padding: EdgeInsets.only(left: 2.0.w),
              //   height: 5.0.h,
              width: 70.0.w,
              decoration: BoxDecoration(
              border: Border.all(
              color: Colors.black45, // Set border color here
              ),
              borderRadius: BorderRadius.circular(5.0), // Optional: Set border radius
              ),
              child: DropdownSearch<ProductModel>(
                popupProps: PopupProps.menu(
                  showSearchBox: true,
                ),

                asyncItems: (String filter) => getcustomer(filter, context), // Calls getcustomer for every search
                itemAsString: (ProductModel u) => u.name, // Converts ProductModel to a displayable string
                onChanged: (ProductModel? data) {
                  // Handle selection if needed
                  print('Selected customer: ${data?.name}');
                },
                dropdownDecoratorProps: DropDownDecoratorProps(
                  dropdownSearchDecoration: InputDecoration(
                    hintText: calibprov.createcustomername ?? "Contact Person",
                    hintStyle: TextStyle(
                      fontSize: 12.sp,
                      fontWeight: FontWeight.bold,
                      color: Colors.black,
                    ),
                    labelStyle: TextStyle(
                      fontSize: 12.sp,
                      fontWeight: FontWeight.bold,
                      color: Colors.black,
                    ),
                  ),
                ),
              ),

              );
              }),

  List<ProductModel> _fetchcustomer = [];

  List<ProductModel> get fetchcustomer => _fetchcustomer;

  Future<ProductModel?> FetchCalibrationcustomer(String searchText) async {
    try {
      final response = await client.searchRead(
          "res.partner",
          [
            ['name', 'ilike', searchText],
          ],
          [
            'id',
            'name',
          ],
          context: {},
          limit: 20);

      print("result= " + response.getResult().toString());

      final extractedData = response.getResult()['records'];
      print(extractedData);
      final List<ProductModel> category = [];

      extractedData.forEach((value) {
        category.add(ProductModel(
          value['id'],
          value['name'],
        ));
      });
      _fetchcustomer = category;

      print("||||||||||||||||||||||||||||||");
      print(category);
      print("||||||||||||||||||||||||||||||");

      notifyListeners();
    } catch (error) {
      print(error.toString());
      throw (error);
    }
  }

合作伙伴名称有超过 1000 个客户名称,当我在下拉搜索框中搜索每个单词时,第一个客户名称有 20 个名称,它需要调用 API 并直接检索最多 20 个结果,但现在在搜索其时,它首先只检索 20 个名称仅从最先下载的 20 个名称中搜索。

flutter dart flutter-dependencies dropdown
1个回答
0
投票

您可以使用 flutter 中的 Autocomplete Widget(内置) 就像下面的例子一样

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,
          ),
        ],
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.