Buy Me A Coffee

DropdownSearch package

Simple and robust DropdownSearch with item search feature, making it possible to use an offline item list or filtering URL for easy customization.

packages.yaml

dropdown_search: <lastest version>

Import

import 'package:dropdown_search/dropdownSearch.dart';

Simple implementation

DropdownSearch(
  items: ["Brazil", "Italia", "Tunisia", "Canada"],
  label: "PaĆ­s",
  onChanged: print,
  selectedItem: "Brazil",
);

customize showed field (itemAsString)

DropdownSearch<UserModel>(
  label: "Name",
  onFind: (String filter) => getData(filter),
  itemAsString: UserModel.userAsStringByName,
  searchBoxDecoration: InputDecoration(
    hintText: "Search",
    border: OutlineInputBorder(),
  ),
  onChanged: (UserModel data) => print(data),
),

DropdownSearch<UserModel>(
  label: "Name",
  onFind: (String filter) => getData(filter),
  itemAsString: UserModel.userAsStringById,
  searchBoxDecoration: InputDecoration(
    hintText: "Search",
    border: OutlineInputBorder(),
  ),
  onChanged: (UserModel data) => print(data),
),

customize Filter Function

DropdownSearch<UserModel>(
  label: "Name",
  filterFn: UserModel.userFilterByCreationDate,
  onFind: (String filter) => getData(filter),
  itemAsString: UserModel.userAsStringByName,
  searchBoxDecoration: InputDecoration(
    hintText: "Search",
    border: OutlineInputBorder(),
  ),
  onChanged: (UserModel data) => print(data),
),

customize Search Mode

DropdownSearch<UserModel>(
  mode: Mode.BOTTOM_SHEET,
  label: "Name",
  maxHeight: 350,
  onFind: (String filter) => getData(filter),
  itemAsString: UserModel.userAsStringByName,
  searchBoxDecoration: InputDecoration(
    hintText: "Search",
    border: OutlineInputBorder(),
  ),
  onChanged: (UserModel data) => print(data),
),

Validation

DropdownSearch(
  items: ["Brazil", "France", "Tunisia", "Canada"],
  label: "Country",
  onChanged: print,
  selectedItem: "Tunisia",
  validate: (String item) {
    if (item == null)
      return "Required field";
    else if (item == "Brazil")
      return "Invalid item";
    else
      return null;
  },
);

Endpoint implementation (using Dio package)

DropdownSearch<UserModel>(
  label: "Nome",
  onFind: (String filter) async {
    var response = await Dio().get(
        "http://5d85ccfb1e61af001471bf60.mockapi.io/user",
        queryParameters: {"filter": filter},
    );
    var models = UserModel.fromJsonList(response.data);
    return models;
  },
  onChanged: (UserModel data) {
    print(data);
  },
);

Layout customization

You can customize the layout of the DropdownSearch and its items. EXAMPLE

PropertiesDescription
labelDropDownSearch label
showSearchBoxshow/hide the search box
isFilteredOnlinetrue if the filter on items is applied onlie (via API)
showClearButtonshow/hide clear selected item
labelStyletext style for the DropdownSearch label
itemsoffline items list
selectedItemselected item
onFindfunction that returns item from API
onChangedcalled when a new item is selected
dropdownBuilderto customize list of items UI
dropdownItemBuilderto customize selected item
validatefunction to apply the validation formula
searchBoxDecorationdecoration for the search box
backgroundColorbackground color for the dialog/menu/bottomSheet
dialogTitlethe title for dialog/menu/bottomSheet
dialogTitleStyletext style for the dialog title
dropdownItemBuilderHeightthe height of the selected item UI
itemAsStringcustomize the fields the be shown
filterFncustom filter function
enabledenable/disable dropdownSearch
modeMENU / DIALOG/ BOTTOM_SHEET
maxHeightthe max height for dialog/bottomSheet/Menu
showSelectedItemmanage selected item visibility (if true, the selected item will be highlighted)
compareFnFunction(T item, T selectedItem), custom comparing function

Attention

To use a template as an item type, and you don't want to use a custom fonction itemAsString you need to implement toString, equals and hashcode, as shown below:

class UserModel {
  final String id;
  final DateTime createdAt;
  final String name;
  final String avatar;

  UserModel({this.id, this.createdAt, this.name, this.avatar});

  ///this method will prevent the override of toString and make the same model useful for different cases
    static String userAsStringByName(UserModel userModel){
      return '#${userModel.id} ${userModel.name}';
    }

    //this method will prevent the override of toString
    static String userAsStringById(UserModel userModel){
      return '#${userModel.id} ${userModel.id}';
    }

  ///this method will prevent the override of toString
  static bool userFilterByCreationDate(UserModel userModel, String filter){
    return userModel?.createdAt?.toString()?.contains(filter);
  }

    ///custom comparing function to check if two users are equal
    static bool isEqual(UserModel model1, UserModel model2) {
        return model1?.id == model2?.id;
      }

  @override
  String toString() => name;

  @override
  operator ==(o) => o is UserModel && o.id == id;

  @override
  int get hashCode => id.hashCode^name.hashCode^createdAt.hashCode;

}

View more Examples

Libraries

selectDialog