Select Dropdown with Multi Select and Search in Flutter

518 views Asked by At

As I work on my Flutter application, I'm having trouble with the form widget. I was unable to locate a plugin that would work for my need for this kind of multi-select dropdown with search. enter image description here

Even though I've found one package (select2dot1: ~2.0.9) that somewhat satisfies my needs such as its ability to choose multiple items and built-in dynamic search, but with GetBuilder(i need getbuilder to populate those items) it's not working. What am I not doing right?

This is the simplified version of my code:

GetBuilder<SaveLocationController>(
  init: SaveLocationController(),
  initState: (_) {},
  builder: (_) {
    return Select2dot1(
      selectDataController: SelectDataController(
        data: controller.exampleData,
      ),
      scrollController: controller.scrollController,
    );
  },
),

UPDATE

This plugin, bs_flutter_selectbox: ^1.3.0, is what I'm using now, and it meets my needs and functions well. However, because I need to fill those things via the API, this plugin includes an in-built attribute called serverSide but I'm having trouble doing so because of a model-related issue. This is updated current code:

// view code
Container(
  margin: const EdgeInsets.only(bottom: 10.0),
  child: BsSelectBox(
    searchable: true,
    // serverSide: controller.selectApi,
    controller: controller.select6,
    autoClose: false,
    alwaysUpdate: false,
    padding: const EdgeInsets.fromLTRB(
        20.0, 12.0, 20.0, 12.0),
    hintTextLabel: 'Pilih salah satu',
    style: BsSelectBoxStyle(
      backgroundColor: Color.fromARGB(255, 255, 255, 255),
      hintTextColor: Color.fromARGB(255, 0, 0, 0),
      selectedColor: Color.fromARGB(255, 247, 247, 247),
      selectedTextColor: Colors.white,
      textColor: Colors.white,
      focusedTextColor: Color.fromARGB(255, 255, 255, 255),
      borderRadius: BorderRadius.circular(50.0),
    ),
    dialogStyle: BsDialogBoxStyle(
      borderRadius: BorderRadius.circular(20.0),
    ),
    paddingDialog: const EdgeInsets.all(15),
    marginDialog:
        const EdgeInsets.only(top: 5.0, bottom: 5.0),
  ),
),

// controller code
BsSelectBoxController select6 = 
    BsSelectBoxController(multiple: true, options: [
  const BsSelectBoxOption(value: 1, text: Text('1')),
  const BsSelectBoxOption(value: 2, text: Text('2')),
  const BsSelectBoxOption(value: 3, text: Text('3')),
  const BsSelectBoxOption(value: 4, text: Text('4')),
  const BsSelectBoxOption(value: 5, text: Text('5')),
  const BsSelectBoxOption(value: 6, text: Text('6')),
]);

Future<BsSelectBoxResponse> selectApi(Map<String, String> params) async {
  String apipage = "match/fetch/fetchZipcode.php";
  Map mappedData = {};
  var response = await sendDataServer(apipage, mappedData);
  var servResJson = response.data;
  var data = json.decode(servResJson)["data"];
  var arrayDB = Zipcode.fromJson({"zipcode": data});
  zipCodes = arrayDB.zipcode;
  return BsSelectBoxResponse.createFromJson(zipCodes);
}

This is how my API response look like:

{
    "zipcode": [
        {
            "zipcode_id": 1,
            "manage_country_id": 1,
            "state_id": 53,
            "zipcode": "T4A"
        },
        {
            "zipcode_id": 2,
            "manage_country_id": 1,
            "state_id": 53,
            "zipcode": "T4B"
        },
        //...some more datas
    ]
}

I would much appreciate any help in populating those elements or bits of code. Gratitude

2

There are 2 answers

2
K.D.Dilshan On

To enable selecting multiple options from a dropdown button in Flutter, you can use the MultiSelectFormField widget provided by the flutter_multiselect package.

1.First you should add the dependency following bellow steps,

add flutter_multiselect into pubspec.yaml,

dependencies:
  flutter:
    sdk: flutter
  flutter_multiselect: ^4.0.1

use latest version,

2.Now you can modify your code to use the MultiSelectFormField,

import 'package:flutter/material.dart';
import 'package:flutter_multiselect/flutter_multiselect.dart';

GetBuilder<SaveLocationController>(
  init: SaveLocationController(),
  initState: (_) {},
  builder: (_) {
    return MultiSelectFormField(
      autovalidate: false,
      titleText: 'Select Options',
      dataSource: controller.exampleData,
      textField: 'display',
      valueField: 'value',
      okButtonLabel: 'OK',
      cancelButtonLabel: 'CANCEL',
      searchable: true,
      hintWidget: Text('Please choose one or more'),
      initialValue: [],
      onSaved: (value) {
        // Handle selected values
        print('Selected: $value');
      },
    );
  },
),

key points,

  • dataSource represents the list of options you want to display in the dropdown.
  • textField is the key to display the text of each option.
  • valueField is the key to identify the value of each option.
  • onSaved callback is invoked when the user selects options.
1
Nikunj Panchal On

Try this package: animated_custom_dropdown

You can easily search and multi select the value using this package.

Here is the example

`enter code here`import 'package:animated_custom_dropdown/custom_dropdown.dart';
import 'package:flutter/material.dart';
import 'dart:developer';

const List<Pair> _list = [
    Pair('Developer', Icons.developer_board),
    Pair('Designer', Icons.deblur_sharp),
    Pair('Consultant', Icons.money_off),
    Pair('Student', Icons.edit),
  ];

class MultiSelectSearchRequestDropdown extends StatelessWidget {
  const MultiSelectSearchRequestDropdown({Key? key}) : super(key: key);

  // This should be a call to the api or service or similar
  Future<List<Pair>> _getFakeRequestData(String query) async {
    return await Future.delayed(const Duration(seconds: 1), () {
      return _list.where((e) {
        return e.text.toLowerCase().contains(query.toLowerCase());
      }).toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return CustomDropdown<Pair>.multiSelectSearchRequest(
      futureRequest: _getFakeRequestData,
      hintText: 'Search job role',
      onListChanged: (value) {
        log('changing value to: $value');
      },
    );
  }
}