I'm using the MultiSelectDialogField widget, but I wanted the user to be able to select only one option, does anyone know if there's a way to do this with this widget?
Or if there is another widget with dialog that is more recommended?
MultiSelectDialogField(
searchable: true,
items: _itensStudent,
title: const Text("Students"),
selectedColor: Colors.black,
decoration: BoxDecoration(
border: Border.all(
color: theme.primaryColor,
width: 2,
),
),
isDismissible: false,
buttonText: Text(
"Select student",
style: TextStyle(
color: theme.primaryColor,
fontSize: 16,
),
),
chipDisplay: MultiSelectChipDisplay.none(),
onConfirm: (results) {
},
),
Related
UI
I want to build a form that is used to fill in the departure station and destination station. But I haven't implemented a way to prevent the user from filling in the same value in the 2 fields. And this is my code
Form(
key: _formKey,
child: Column(
children: [
// Stasiun Keberangkatan Form
DropdownSearch<String>(
validator: (value) {
if (value == null) {
return 'please input station';
}
return null;
},
popupProps: const PopupProps.menu(
showSelectedItems: true,
showSearchBox: true,
),
items: stationsToStName(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
filled: true,
fillColor: const Color.fromRGBO(37, 37, 37, 0.1),
//hintText: "Stasiun keberangkatan",
hintText: "Departure Station",
hintStyle:
const TextStyle(fontFamily: 'Inter', fontSize: 14),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.none,
),
),
prefixIcon: const Padding(
padding: EdgeInsets.all(8.0),
child: Image(
height: 33,
image: AssetImage(
'assets/images/icon_departureSt.png'),
),
),
),
),
onChanged: (newvalue) {
setState(() {
stKeberangkatan = newvalue!; //updated
});
},
),
const SizedBox(height: 11),
// Destination Form
DropdownSearch<String>(
validator: (value) {
if (value == null) {
return 'please input station';
}
return null;
},
popupProps: const PopupProps.menu(
showSelectedItems: true,
showSearchBox: true,
),
items: stationsToStName(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
filled: true,
fillColor: const Color.fromRGBO(37, 37, 37, 0.1),
//hintText: "Stasiun tujuan",
hintText: "Destination Station",
hintStyle:
const TextStyle(fontFamily: 'Inter', fontSize: 14),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.none,
),
),
hintMaxLines: 2,
prefixIcon: const Padding(
padding: EdgeInsets.all(11.0),
child: Image(
height: 33,
image: AssetImage(
'assets/images/icon_destinationSt.png'),
),
),
),
),
onChanged: (newvalue) {
setState(() {
stTujuan = newvalue!; //updated
});
},
),
const SizedBox(height: 35),
// "Submit" Button
SizedBox(
width: size.width,
height: 48,
child: ElevatedButton(
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all<Color>(Colors.white),
backgroundColor:
MaterialStateProperty.all<Color>(primColor),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
side: const BorderSide(color: primColor)))),
onPressed: () {
if (_formKey.currentState != null &&
_formKey.currentState!.validate()) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BestRoute(
stKeberangkatan: stKeberangkatan,
stTujuan: stTujuan,
)),
);
}
},
child: const Text("Submit",
style: TextStyle(
fontFamily: 'Inter',
fontWeight: FontWeight.w700,
fontSize: 14))),
),
],
),
),
I want to apply alert or validator if user fill in same value when click submit button
For example, the user fills in station A for departure station and destination station. And I want to avoid that. and I want to apply alert or validator if user fill in same value when click submit button
How can I implement that?
You can create two variables, one called departure and the other called destination. Then when the user selects a value from the dropdown, use setState((){}) to put the value in the variables.
Finally, when the user clicks on submit button, check if the value of destination and departure are different and only then allow the user to proceed.
I am using flutter typeahead to suggest options to a user based on their text input.
When entering any input, the first suggestion is always just what the user types. I would like to restrict this to just suggestions retrieved from the backend, and this is getting in the way of that. Is there a solution?
Widget get typeAheadField{
return SingleChildScrollView (
child: TypeAheadField(
//autoFlipDirection: true,
hideOnEmpty: true,
hideOnLoading: true,
minCharsForSuggestions: 1,
getImmediateSuggestions: false,
direction: AxisDirection.up,
keepSuggestionsOnLoading: false,
textFieldConfiguration: TextFieldConfiguration(
textAlign: TextAlign.center,
autofocus: true,
style: DefaultTextStyle.of(context).style.copyWith(
color: Colors.white,
fontSize: 20.0,
),
decoration: InputDecoration(
hintText: "Tag Friends: ",
hintStyle: TextStyle(color: Colors.grey, fontSize: 20.0,),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.0),
borderSide: const BorderSide(
color: Colors.white,
width: 2.0,
),
),
),
),
suggestionsCallback: getSuggestions,
itemBuilder: (context, suggestion) {
return getList(context, suggestion);
},
onSuggestionSelected: (suggestion) {
addUser(suggestion);
},
)
);
}
replace return getList(context, suggestion);
with
List<String> newSuggestions=suggestion.where((e)=>e!= "the user input from the controller " ) ).toList() ;
return getList(context, newSuggestions);
I use a multi-select
https://pub.dev/packages/multi_select_flutter/example
in a page like below (Properties+)
the multi-select has initialValue property which I could pass pre-selected items in them and it work in firt time of the loading of the page . I want to when I push on edit button in the page the multi-select will cosider new seleced items as pre-selected values and the selected items will change according to the new data.
MultiSelectDialogField(
items: _items,
initialValue: _selectedPorperties,
title: Text("Properties"),
selectedColor: Colors.blue,
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.1),
borderRadius: BorderRadius.all(Radius.circular(40)),
border: Border.all(
color: Colors.blue,
width: 2,
),
),
buttonIcon: Icon(
Icons.add,
color: Colors.blue,
),
buttonText: Text(
"Properties",
style: TextStyle(
color: Colors.blue[800],
fontSize: 16,
),
),
onConfirm: (results) {
_selectedPorperties = results;
},
)
_selectedPorperties is a dynamic list which I fill them after pushing on Edit button. in the body of Widget build(BuildContext context)
List<dynamic> _selectedPorperties = [];
I want to change the text color of the ListView with along with the Checkbox but can't change the text color dynamically with the ListView's onselected item?
I also add the color in the set State option but cant find the result I was lookin for.
here is my code:
ListView(
children: [
Text(
''' Categories''',
style: TextStyle(
color: Color(0xff181725),
fontSize: 24,
fontFamily: "Gilroy",
fontWeight: FontWeight.normal,
),
),
SizedBox(height: 13),
...checkBoxListOne.map(
(item) => ListTile(
onTap: () => onAllClicked(item),
leading: Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
side: BorderSide(
color: Color(0xffC2C2C2),
width: 2,
),
activeColor: Color(0xff53B175),
value: item.value,
onChanged: (value) => onAllClicked(item),
),
title: Text(
item.title!,
style: TextStyle(
color: Color(0xff181725),
),
),
),
),
SizedBox(height: 40),
Text(
''' Brand''',
style: TextStyle(
color: Color(0xff181725),
fontSize: 24,
fontFamily: "Gilroy",
fontWeight: FontWeight.normal,
),
),
SizedBox(height: 13),
...checkBoxListTwo.map(
(item) => ListTile(
onTap: () => onAllClicked(item),
leading: Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
side: BorderSide(
color: Color(0xffC2C2C2),
width: 2,
),
activeColor: Color(0xff53B175),
value: item.value,
onChanged: (value) => onAllClicked(item),
),
title: Text(item.title!),
),
),
],
),
and here is the setState part :
onAllClicked(CheckBoxModal ckbItem) { setState(() { ColoredBox( color: Color(0xff53B175), ); ckbItem.value = !ckbItem.value; }); }
You should add a field isSelected to the item objects in your checkBoxListOne list, and set/reset that field in the onTap of the item (item.isSelected = !item.isSelected), then call setState(){}. When you render the item, instead of activeColor: Color(0xff53B175) do something like activeColor: item.isSelected ? Color(0xff53B175) : Color(0xffffffff).
As a result of this change, the list is re-rendered whenever an item is tapped, and the color of the item when rendered is dependent on its 'tapped or not' state.
If you cannot (or don't want to) add a field, you can create a separate bool array of the same length as your checkBoxListOne list and use that to keep track of which item is selected.
I am using the typeahead package for flutter to show a textfield with the suggestions capability, but I am getting unwanted behavior. When the user first tap the field, I do not want to show any suggestions but it's showing a list of all suggestions like a dropdown field. I have even set getImmediateSuggestion: false but it's still doing this[![enter image description here][1]][1]
alignment: Alignment.center,
//padding: EdgeInsets.symmetric(vertical: 16),
//height: (0.0725 * y),
child: TypeAheadFormField(
keepSuggestionsOnLoading: false,
hideOnEmpty: true,
hideOnLoading: true,
//initialValue: '',
enabled: false,
hideOnError: true,
textFieldConfiguration: TextFieldConfiguration(
//textAlign: TextAlign.left,
//autofocus: true,
controller: _typeAheadController,
style: TextStyle(color: mainTextColor, fontSize:14, fontWeight: FontWeight.w400 ),
decoration: InputDecoration(
filled: true,
fillColor: cardColor,
labelStyle: TextStyle(fontSize: (0.04*x), color: mainTextColor, fontWeight: FontWeight.w400),
hintText: 'Type degree',
hintStyle: TextStyle(fontSize: (14), color: hintColor, fontWeight: FontWeight.w400),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide.none),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide(color: hintColor, width: 0.8)
)
),
),
//suggestionsBoxController: ,
getImmediateSuggestions: false,
suggestionsCallback: (pattern){
return DegreeSearchService(uni: currentUniversity).getSuggestions(pattern);
},
itemBuilder: (context, suggestion){
return ListTile(
dense: true,
title: Text(suggestion, style: TextStyle(fontSize: 14,color: Colors.black),)
);
},
onSuggestionSelected: (suggestion){
_typeAheadController.text = suggestion;
currentDegree = suggestion;//enable next press
//pageController.animateToPage(++currentPage, duration: Duration(milliseconds: 250), curve: Curves.bounceInOut );
}
)
), ```
[1]: https://i.stack.imgur.com/FUXjl.png
Try to change your suggestionsCallback to not show results if the pattern length is 0, for example:
suggestionsCallback: (pattern){
if (pattern.length > 1) {
return DegreeSearchService(uni:currentUniversity).getSuggestions(pattern);
}
},