Skip to content

Commit

Permalink
(2.2.4 WIP) added searchResultDisplayFn ; thanks @ramioooz #109
Browse files Browse the repository at this point in the history
  • Loading branch information
lcuis committed Feb 24, 2023
1 parent 6c6a430 commit 4bb045b
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.2.4

* added searchResultDisplayFn. Thanks @ramioooz https://github.com/lcuis/search_choices/issues/109

## 2.2.3

* added buildFutureFilterOrOrderButton to customize future filter and order button. Thanks @agustin-garcia https://github.com/lcuis/search_choices/issues/107
Expand Down
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ Search choices Widget with a single choice that opens a dialog or a menu to let
String? orderBy,
})?
buildFutureFilterOrOrderButton,
Widget Function({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, T value, bool itemSelected) itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
})?
searchResultDisplayFn,
})
```

Expand Down Expand Up @@ -239,6 +249,7 @@ Search choices Widget with a single choice that opens a dialog or a menu to let
** nbFilters is set to the number of filters applied if any.
** orderAsc true when the applied order is ascending.
** orderBy is the string by which the search is sorted.
* searchResultDisplayFn to customize the display of the search result items within the dialog or menu.


#### Multiple choice constructor
Expand Down Expand Up @@ -336,6 +347,16 @@ Search choices Widget with a multiple choice that opens a dialog or a menu to le
String? orderBy,
})?
buildFutureFilterOrOrderButton,
Widget Function({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, T value, bool itemSelected) itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
})?
searchResultDisplayFn,
})
```

Expand Down Expand Up @@ -401,6 +422,7 @@ Search choices Widget with a multiple choice that opens a dialog or a menu to le
** nbFilters is set to the number of filters applied if any.
** orderAsc true when the applied order is ascending.
** orderBy is the string by which the search is sorted.
* searchResultDisplayFn to customize the display of the search result items within the dialog or menu.

#### Example app usage

Expand Down Expand Up @@ -2734,6 +2756,50 @@ SearchChoices.single(
)),
);
},
// Here, searchResultDisplayFn doesn't change anything.
// This is a way to make sure this parameter still works with automated
// integration testing.
searchResultDisplayFn: ({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, dynamic value, bool itemSelected)
itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
}) {
return Expanded(
child: Scrollbar(
controller: scrollController,
thumbVisibility: thumbVisibility,
child: itemsToDisplay.length == 0
? emptyListWidget
: ListView.builder(
controller: scrollController,
itemBuilder: (context, index) {
int itemIndex = itemsToDisplay[index].item1;
DropdownMenuItem item = itemsToDisplay[index].item2;
bool isItemSelected = itemsToDisplay[index].item3;
return InkWell(
onTap: () {
itemTapped(
itemIndex,
item.value,
isItemSelected,
);
},
child: displayItem(
item,
isItemSelected,
),
);
},
itemCount: itemsToDisplay.length,
),
),
);
},
)
```
### Single dialog custom field presentation
Expand Down
44 changes: 44 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2282,6 +2282,50 @@ class MyAppState extends State<MyApp> {
)),
);
},
// Here, searchResultDisplayFn doesn't change anything.
// This is a way to make sure this parameter still works with automated
// integration testing.
searchResultDisplayFn: ({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, dynamic value, bool itemSelected)
itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
}) {
return Expanded(
child: Scrollbar(
controller: scrollController,
thumbVisibility: thumbVisibility,
child: itemsToDisplay.length == 0
? emptyListWidget
: ListView.builder(
controller: scrollController,
itemBuilder: (context, index) {
int itemIndex = itemsToDisplay[index].item1;
DropdownMenuItem item = itemsToDisplay[index].item2;
bool isItemSelected = itemsToDisplay[index].item3;
return InkWell(
onTap: () {
itemTapped(
itemIndex,
item.value,
isItemSelected,
);
},
child: displayItem(
item,
isItemSelected,
),
);
},
itemCount: itemsToDisplay.length,
),
),
);
},
),
"Single dialog custom field presentation": SearchChoices.single(
items: items,
Expand Down
22 changes: 22 additions & 0 deletions lib/src/dropdown/dropdown_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ class DropdownDialog<T> extends StatefulWidget {
String? orderBy,
})? buildFutureFilterOrOrderButton;

/// See SearchChoices class.
final Widget Function({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, T value, bool itemSelected) itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
})? searchResultDisplayFn;

DropdownDialog({
Key? key,
this.items,
Expand Down Expand Up @@ -198,6 +209,7 @@ class DropdownDialog<T> extends StatefulWidget {
this.clearSearchIcon,
this.listValidator,
this.buildFutureFilterOrOrderButton,
this.searchResultDisplayFn,
}) : super(key: key);

_DropdownDialogState<T> createState() => _DropdownDialogState<T>();
Expand Down Expand Up @@ -715,6 +727,16 @@ class _DropdownDialogState<T> extends State<DropdownDialog> {
/// [int] as the index in the [selectedItems] list.
Widget listDisplay(
List<Tuple3<int, DropdownMenuItem<dynamic>, bool>> itemsToDisplay) {
if (widget.searchResultDisplayFn != null) {
return widget.searchResultDisplayFn!(
itemsToDisplay: itemsToDisplay,
scrollController: widget.listScrollController,
thumbVisibility: widget.itemsPerPage == null ? false : true,
emptyListWidget: emptyList(),
itemTapped: itemTapped as Function(int, dynamic, bool),
displayItem: displayItem,
);
}
return Expanded(
child: Scrollbar(
controller: widget.listScrollController,
Expand Down
93 changes: 93 additions & 0 deletions lib/src/search_choices.dart
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,71 @@ class SearchChoices<T> extends FormField<T> {
String? orderBy,
})? buildFutureFilterOrOrderButton;

/// [searchResultDisplayFn] to customize the display of the search result
/// items within the dialog or menu.
/// Example:
/// searchResultDisplayFn: ({
/// required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
/// required ScrollController scrollController,
/// required bool thumbVisibility,
/// required Widget emptyListWidget,
/// required void Function(int index, dynamic value, bool itemSelected)
/// itemTapped,
/// required Widget Function(DropdownMenuItem item, bool isItemSelected)
/// displayItem,
/// }) {
/// return Expanded(
/// child: itemsToDisplay.length == 0
/// ? emptyListWidget
/// : SingleChildScrollView(
/// child: Wrap(
/// spacing: 10,
/// children: itemsToDisplay.map(
/// (Tuple3<int, DropdownMenuItem, bool> item) {
/// return Padding(
/// padding:
/// const EdgeInsets.symmetric(vertical: 8.0),
/// child: InkWell(
/// onTap: () {
/// itemTapped(
/// item.item1,
/// item.item2.value,
/// item.item3,
/// );
/// },
/// child: Container(
/// decoration: BoxDecoration(
/// border: Border.all(
/// color: Colors.grey,
/// width: 5,
/// )),
/// child: Row(
/// mainAxisSize: MainAxisSize.min,
/// children: [
/// Padding(
/// padding: const EdgeInsets.symmetric(
/// horizontal: 8.0),
/// child: item.item2,
/// ),
/// ],
/// ),
/// ),
/// ),
/// );
/// },
/// ).toList()),
/// ));
/// },
final Widget Function({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, T value, bool itemSelected) itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
})? searchResultDisplayFn;

/// Search choices Widget with a single choice that opens a dialog or a menu
/// to let the user do the selection conveniently with a search.
///
Expand Down Expand Up @@ -459,6 +524,8 @@ class SearchChoices<T> extends FormField<T> {
/// ** [nbFilters] is set to the number of filters applied if any.
/// ** [orderAsc] true when the applied order is ascending.
/// ** [orderBy] is the string by which the search is sorted.
/// * [searchResultDisplayFn] to customize the display of the search result
/// items within the dialog or menu.
factory SearchChoices.single({
Key? key,
List<DropdownMenuItem<T>>? items,
Expand Down Expand Up @@ -550,6 +617,16 @@ class SearchChoices<T> extends FormField<T> {
String? orderBy,
})?
buildFutureFilterOrOrderButton,
Widget Function({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, T value, bool itemSelected) itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
})?
searchResultDisplayFn,
}) {
return (SearchChoices._(
key: key,
Expand Down Expand Up @@ -610,6 +687,7 @@ class SearchChoices<T> extends FormField<T> {
restorationId: restorationId,
giveMeThePop: giveMeThePop,
buildFutureFilterOrOrderButton: buildFutureFilterOrOrderButton,
searchResultDisplayFn: searchResultDisplayFn,
));
}

Expand Down Expand Up @@ -748,6 +826,8 @@ class SearchChoices<T> extends FormField<T> {
/// ** [nbFilters] is set to the number of filters applied if any.
/// ** [orderAsc] true when the applied order is ascending.
/// ** [orderBy] is the string by which the search is sorted.
/// * [searchResultDisplayFn] to customize the display of the search result
/// items within the dialog or menu.
factory SearchChoices.multiple({
Key? key,
List<DropdownMenuItem<T>>? items,
Expand Down Expand Up @@ -840,6 +920,16 @@ class SearchChoices<T> extends FormField<T> {
String? orderBy,
})?
buildFutureFilterOrOrderButton,
Widget Function({
required List<Tuple3<int, DropdownMenuItem, bool>> itemsToDisplay,
required ScrollController scrollController,
required bool thumbVisibility,
required Widget emptyListWidget,
required void Function(int index, T value, bool itemSelected) itemTapped,
required Widget Function(DropdownMenuItem item, bool isItemSelected)
displayItem,
})?
searchResultDisplayFn,
}) {
return (SearchChoices._(
key: key,
Expand Down Expand Up @@ -902,6 +992,7 @@ class SearchChoices<T> extends FormField<T> {
restorationId: restorationId,
giveMeThePop: giveMeThePop,
buildFutureFilterOrOrderButton: buildFutureFilterOrOrderButton,
searchResultDisplayFn: searchResultDisplayFn,
));
}

Expand Down Expand Up @@ -971,6 +1062,7 @@ class SearchChoices<T> extends FormField<T> {
this.restorationId,
this.giveMeThePop,
this.buildFutureFilterOrOrderButton,
this.searchResultDisplayFn,
}) : assert(!multipleSelection || doneButton != null),
assert(menuConstraints == null || !dialogBox),
assert(itemsPerPage == null || currentPage != null,
Expand Down Expand Up @@ -1341,6 +1433,7 @@ class _SearchChoicesState<T> extends FormFieldState<T> {
clearSearchIcon: widget.clearSearchIcon,
listValidator: widget.listValidator,
buildFutureFilterOrOrderButton: widget.buildFutureFilterOrOrderButton,
searchResultDisplayFn: widget.searchResultDisplayFn,
));
});
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: search_choices
description: Highly versatile Widget to search through a single or multiple choices list in a dialog box or a menu. Supports pagination and future/API/webservice searches with sort and filter.
version: 2.2.3
version: 2.2.4
homepage: https://github.com/lcuis/search_choices
repository: https://github.com/lcuis/search_choices
issue_tracker: https://github.com/lcuis/search_choices/issues
Expand Down

0 comments on commit 4bb045b

Please sign in to comment.