Comments (22)
I don't know what exactly is the issue here.
Can you provide a simplified working sample that produce the issue please?
from dropdown_button2.
Trying to make searchable dropdown but dropdown is list but that list is search from api call
Whenever search it will be call api/network call after that we need to update ui based on api call.
Till i hack and working fine but after that i select item's that item whenever i open it will be selected show but whenever i open search and close and again open that selected value will be delected automatically
from dropdown_button2.
Below simplified version of source code
Main widget which one used for main Page of UI
Container(
width: 130,
child: AdvanceDropDownDialog(
widgetTitle: "Title",
dropDownValue: listOfValues, // this listOfValues contain dropdown value
searchCallBack: (searchKey) {
searchRadio(searchKey); // When search happen on actuall in this will call with whatever type in text form field and api call will be happening here after api call success dropdown value need to change and refresh widget
},
textEditingController: raTextEditingController,
),
)
class AdvanceDropDownDialog extends StatefulWidget {
final String widgetTitle;
final List<dynamic> dropDownValue;
final Function(String)? searchCallBack;
final TextEditingController textEditingController;
const AdvanceDropDownDialog(
{required this.widgetTitle,
required this.dropDownValue,
this.searchCallBack,
required this.textEditingController,
Key? key})
: super(key: key);
@override
_AdvanceDropDownDialogState createState() => _AdvanceDropDownDialogState();
}
class _AdvanceDropDownDialogState extends State<AdvanceDropDownDialog> {
dynamic selectedValue;
List<dynamic> selectedItems = [];
bool isExpanded = false;
@override
void initState() {
super.initState();
}
@override
void didUpdateWidget(AdvanceDropDownDialog oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
builder: (context, snapshoot) {
return DropdownButtonHideUnderline(
child: DropdownButton2(
isExpanded: true,
dropdownWidth: 300,
hint: FilterTitleWidget(
titleText: widget.widgetTitle,
icon: isExpanded ? Icons.expand_less : Icons.expand_more),
icon: Container(),
items: widget.dropDownValue
.map((item) => DropdownMenuItem<dynamic>(
value: item,
enabled: false,
child: StatefulBuilder(
builder: (BuildContext context,
void Function(void Function()) change) {
final _isSelected = selectedItems.contains(item);
return InkWell(
onTap: () {
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
change(() {});
},
child: Container(
height: double.infinity,
padding:
const EdgeInsets.symmetric(horizontal: 16.0),
color: _isSelected
? SELECTED_BACKGROUND_COLOR
: null,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
(item is CustomObj)
? item.name
: item['name'],
),
_isSelected
? Icon(Icons.check)
: const SizedBox(),
],
),
),
);
},
),
))
.toList(),
value: selectedValue,
onChanged: (dynamic value) {},
buttonHeight: 40,
itemHeight: 40,
alignment: Alignment.center,
dropdownMaxHeight: 200,
searchController: widget.textEditingController,
searchInnerWidget: Padding(
padding: const EdgeInsets.only(
top: 8,
// bottom: 4,
right: 0,
left: 0,
),
child: TextFormField(
controller: widget.textEditingController,
onChanged: (value) {
if (widget.searchCallBack != null) {
widget.searchCallBack!(value);
}
},
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.only(left: 32, top: 16),
suffixIcon: Icon(Icons.search_rounded),
hintText: "Search ...",
),
),
),
searchMatchFn: (item, searchValue) {
return (item.value
.toString()
.toLowerCase()
.contains(searchValue.toLowerCase()));
},
onMenuStateChange: (isOpen) {
if (!isOpen) {}
isExpanded = isOpen;
},
),
);
},
);
}
}
from dropdown_button2.
Is your issue that the dropdown menu items don't update when you call api?
from dropdown_button2.
Yes after api call that not update & selected item i have customized changing background color and right tick mark that also automatically deselect
from dropdown_button2.
Currently updating an open Dropdown Menu is not fully supported but there's a hacky solution for this as described here #101
from dropdown_button2.
Actually this one tried but not working
from dropdown_button2.
Are you currently able to update the menu when its open?
from dropdown_button2.
yes
from dropdown_button2.
Main problem is selected items not refresh
from dropdown_button2.
onTap: () {
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
change(() {});
//Add this.. This rebuilds the main StatefulWidget
setState(() {});
},
from dropdown_button2.
yes actually did this but when two to three time open close dropdown it will be automatically deselect
from dropdown_button2.
** Please keep in mind i am using like reusable widget like multiple instance
from dropdown_button2.
yes actually did this but when two to three time open close dropdown it will be automatically deselect
I'm not sure why this is happening so I need to test your code.
Can you update your code so I can actually run it? Currently your sample has different dependencies which I don't have.
from dropdown_button2.
latest one shared that have no different dependencies
If possible we can connect also
from dropdown_button2.
Actually it has dependencies.
I can't run it on a new flutter project.
from dropdown_button2.
Open new flutter project and try to let your sample code work on it so I can test it too.
For the api call, you can simulate it by await Future.delayed
from dropdown_button2.
Okay sending you with open create new flutter project and adding all on that
from dropdown_button2.
Full example added please check
class AdvanceDialog extends StatefulWidget {
const AdvanceDialog({Key? key}) : super(key: key);
@override
_AdvanceDialogState createState() => _AdvanceDialogState();
}
class _AdvanceDialogState extends State<AdvanceDialog> {
final TextEditingController searchController = TextEditingController();
final TextEditingController searchController2 = TextEditingController();
List<dynamic> dropdownValue = [
"Aetna",
"Allegiance",
"Anthem",
"BlueCross",
"BlueCrossandBlueShield",
"BlueShield",
"Children'sProgram",
"CHIP",
"Cigna",
"FirstChoiceHealth",
"Humana",
"Kaiser(Out-of-Network)",
"Magellan",
"Medicaid",
"Medicare",
"MHNetBehavioralHealth",
"Optum",
"OtherInsuranceEBMS",
"OutofNetwork",
"PacificSource",
"TRICARE",
"TriWest",
"UMR",
"UnitedHealthcare"
];
List<dynamic> searchItems = [];
List<dynamic> searchItems2 = [];
List<dynamic> dropdownValue2 = [
"Aetna",
"Allegiance",
"Anthem",
"BlueCross",
"BlueCrossandBlueShield",
"BlueShield",
"Children'sProgram",
"CHIP",
"Cigna",
"FirstChoiceHealth",
"Humana",
"Kaiser(Out-of-Network)",
"Magellan",
"Medicaid",
"Medicare",
"MHNetBehavioralHealth",
"Optum",
"OtherInsuranceEBMS",
"OutofNetwork",
"PacificSource",
"TRICARE",
"TriWest",
"UMR",
"UnitedHealthcare"
];
@override
void initState() {
super.initState();
searchItems = dropdownValue;
searchItems2 = dropdownValue2;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
AdvanceDropDownDialog(
dropDownValue: searchItems,
textEditingController: searchController,
searchCallBack: (p0) {
getValue(p0);
}),
AdvanceDropDownDialog(
dropDownValue: searchItems2,
textEditingController: searchController2,
searchCallBack: (p0) {
getValue2(p0);
})
],
),
);
}
getValue(String searchKey) async {
print("Search key $searchKey");
if (searchKey.isNotEmpty) {
await Future.delayed(const Duration(seconds: 1));
searchItems.clear();
dropdownValue.forEach((element) {
if (element.toString().contains(searchKey)) {
searchItems.add(element);
}
});
} else {
searchItems = dropdownValue;
}
setState(() {});
}
getValue2(String searchKey) async {
print("Search key $searchKey");
if (searchKey.isNotEmpty) {
searchItems2.clear();
dropdownValue2.forEach((element) {
if (element.toString().contains(searchKey)) {
searchItems2.add(element);
}
});
} else {
searchItems2 = dropdownValue2;
}
setState(() {});
}
@override
void dispose() {
searchController.dispose();
searchController2.dispose();
super.dispose();
}
}
class AdvanceDropDownDialog extends StatefulWidget {
final List<dynamic> dropDownValue;
final Function(String)? searchCallBack;
final TextEditingController textEditingController;
const AdvanceDropDownDialog(
{required this.dropDownValue,
this.searchCallBack,
required this.textEditingController,
Key? key})
: super(key: key);
@override
_AdvanceDropDownDialogState createState() => _AdvanceDropDownDialogState();
}
class _AdvanceDropDownDialogState extends State<AdvanceDropDownDialog> {
dynamic selectedValue;
List<dynamic> selectedItems = [];
bool isExpanded = false;
@override
void initState() {
super.initState();
}
@override
void didUpdateWidget(AdvanceDropDownDialog oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
builder: (context, snapshoot) {
return DropdownButtonHideUnderline(
child: DropdownButton2(
isExpanded: true,
dropdownWidth: 300,
hint: Container(
height: 17,
margin: const EdgeInsets.symmetric(horizontal: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Text("Title Text"),
SizedBox(width: 5),
Icon(Icons.expand_less),
],
),
),
icon: Container(),
items: widget.dropDownValue
.map((item) => DropdownMenuItem<dynamic>(
value: item,
enabled: false,
child: StatefulBuilder(
builder: (BuildContext context,
void Function(void Function()) change) {
final _isSelected = selectedItems.contains(item);
return InkWell(
onTap: () {
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
change(() {});
},
child: Container(
height: double.infinity,
padding:
const EdgeInsets.symmetric(horizontal: 16.0),
color: _isSelected
? Colors.tealAccent.shade400
: null,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(item),
_isSelected
? const Icon(Icons.check)
: const SizedBox(),
],
),
),
);
},
),
))
.toList(),
value: selectedValue,
onChanged: (dynamic value) {},
buttonHeight: 40,
itemHeight: 40,
alignment: Alignment.center,
dropdownMaxHeight: 200,
searchController: widget.textEditingController,
searchInnerWidget: Padding(
padding: const EdgeInsets.only(
top: 8,
// bottom: 4,
right: 0,
left: 0,
),
child: TextFormField(
controller: widget.textEditingController,
onChanged: (value) {
if (widget.searchCallBack != null) {
widget.searchCallBack!(value);
}
},
decoration: const InputDecoration(
isDense: true,
contentPadding: EdgeInsets.only(left: 32, top: 16),
suffixIcon: Icon(Icons.search_rounded),
hintText: "Search ...",
),
),
),
onMenuStateChange: (isOpen) {
if (!isOpen) {}
isExpanded = isOpen;
},
),
);
},
);
}
}
from dropdown_button2.
This can be tested, Thanks!
What are the steps to produce the issue?
from dropdown_button2.
Here you're doing searchItems.clear()
and as searchItems
is the same reference as dropdownValue
, the forEach will never execute.
await Future.delayed(const Duration(seconds: 1));
searchItems.clear();
//This forEach never execute
dropdownValue.forEach((element) {
if (element.toString().toLowerCase().contains(searchKey)) {
searchItems.add(element);
}
});
You need to clone the list in initState instead of copying the object reference:
@override
void initState() {
super.initState();
searchItems = [...dropdownValue];
}
Another thing is as you're using the default SearchMatchFn
you need to add toLowerCase()
to your condition:
dropdownValue.forEach((element) {
if (element.toString().toLowerCase().contains(searchKey.toLowerCase())) {
searchItems.add(element);
}
});
from dropdown_button2.
As this is unrelated to the package, I'll close it.
Feel free to ask for re-open if you disagree.
from dropdown_button2.
Related Issues (20)
- URGENT! Make selectedItemBuilder return a single Widget and not List<Widget> HOT 3
- Easy way of changing the style of the selected item's text HOT 7
- The getter 'View' isn't defined for the class 'DropdownButton2State<T> HOT 2
- using callTap() with DropdownButtonFormField2 HOT 1
- Search with API HOT 1
- Search Issue in when installing app in real device HOT 8
- Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe. HOT 2
- Bottom line doesn't change color when is focused in desktop application. HOT 9
- Error: unable to find directory entry in pubspec.yaml HOT 2
- Setting scrollbarTheme doesnโt work HOT 6
- openMenuIcon bug and unable to update to the newest version because of shared_preferences HOT 1
- Avoid capturing focus when Dropdown is opened HOT 2
- dropdownStyle.useRootNavigator doesn't work HOT 1
- Key tab not opening dropdown HOT 1
- warning while expanding/reducing listview HOT 3
- text group separator
- Apply BackdropFilter for dropdown menu - "frosted glass" style
- Feature request/question: expand dropdown width to largest item child HOT 12
- Removed ScrollbarThemeData itsAlwaysShown at beta branch of flutter HOT 1
- Show menu behind the dropdown button HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dropdown_button2.