[]1] here is my code for ..
i have two textfiled for selecting birth date and month....! and user is existing then value will shown automatically on textfiled ! and user can add new selected value from dropdown selection....! in my case i can select items from dropdown but cant show selected items/value on tetxfild it is removing and textfiled showing blank ! plz help me on this......
String _Dob;
String _Anniversary;
Future<UserUpdate> _futureDateeupdate;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
var month = [
"JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUEST", "SEPTEMBER", "OCTOBER",
"NOVEMBER", "DECEMBER"];
var date = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31];
#override
void initState() {
super.initState();
_futureDateeupdate = DateUpadte();
}
void nextField({String value, FocusNode focusNode}) {
if (value.isNotEmpty) {
focusNode.requestFocus();
}
}
FocusNode Anniversary;
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
resizeToAvoidBottomInset: false,
body: (_isLoading)
? Center(child: CircularProgressIndicator())
: FutureBuilder<UserUpdate>(
future: _futureDateeupdate,
// ignore: missing_return
builder: (context, snapshot) {
if (snapshot.hasData) {
TextEditingController _textEditingControllerDOBb = TextEditingController(
text: snapshot.data.birthDate);
TextEditingController _textEditingControllerDate = TextEditingController(
text: snapshot.data.birthMonth);
TextEditingController _textEditingControllerAnniversaryy = TextEditingController(
text: snapshot.data.anniversaryDate);
return Form(
key: _formKey,
child: Stack(
children: <Widget>[
Positioned(
top: 330,
left: 30,
right: 30,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
height: 70,
width: MediaQuery
.of(context)
.size
.width / 2.6,
child: TextFormField(
textInputAction: TextInputAction.next,
onTap: () {
FocusScope.of(context).requestFocus(
new FocusNode());
},
onFieldSubmitted: (value) {
nextField(
value: value, focusNode: Anniversary);
},
keyboardType: TextInputType.datetime,
controller: _textEditingControllerDOBb,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
5.0),
borderSide: BorderSide(
color: const Color(0x3df58634)
)
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
5.0)
),
labelText: 'Date Of Birth',
labelStyle: GoogleFonts.nunito(
color: const Color(0xfff58634)),
hintText: "Date Of Birth",
hintStyle: GoogleFonts.nunito(
color: const Color(0xfff58634)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
5.0),
borderSide: BorderSide(
color: const Color(0x3df58634),
)
),
suffixIcon: PopupMenuButton<String>(
icon: const Icon(Icons.arrow_drop_down),
onSelected: (String value) {
_textEditingControllerDOBb.text = value;
},
itemBuilder: (BuildContext context) {
return month
.map<PopupMenuItem<String>>((
String value) {
return new PopupMenuItem(
child: new Text(value),
value: value);
}).toList();
},
),
),
validator: (String value) {
if (value.isEmpty) {
return 'DOB is Missing';
}
return null;
},
onSaved: (String value) {
_Dob = value;
},
),
),
SizedBox(
height: 70,
width: MediaQuery
.of(context)
.size
.width / 2.6,
child: TextFormField(
onTap: () {
FocusScope.of(context).requestFocus(
new FocusNode());
},
onFieldSubmitted: (value) {
nextField(
value: value, focusNode: Anniversary);
},
controller: _textEditingControllerDate,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
5.0),
borderSide: BorderSide(
color: const Color(0x3df58634)
)
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
5.0)
),
labelText: 'Date Of Birth',
labelStyle: GoogleFonts.nunito(
color: const Color(0xfff58634)),
hintText: "Date Of Birth",
hintStyle: GoogleFonts.nunito(
color: const Color(0xfff58634)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
5.0),
borderSide: BorderSide(
color: const Color(0x3df58634),
)
),
suffixIcon: PopupMenuButton<int>(
icon: const Icon(Icons.arrow_drop_down),
onSelected: (int value) {
_textEditingControllerDate.text =
"$value";
},
itemBuilder: (BuildContext context) {
return date
.map<PopupMenuItem<int>>((
int value) {
return new PopupMenuItem(
child: new Text("$value"),
value: value);
}).toList();
},
),
),
validator: (String value) {
if (value.isEmpty) {
return 'DOB is Missing';
}
return null;
},
onSaved: (String value) {
_Dob = value;
},
),
),
]
)
),
Related
If I click away from a TextField and then back on it and want to focus on the next TextField (using FocusScope.of(context).nextFocus()) by hitting enter on the software keyboard I get this error:
Exception has occurred.
_AssertionError ('package:flutter/src/widgets/focus_manager.dart': Failed assertion: line 790 pos 7: 'context != null': Tried to get the bounds of a focus node that didn't have its context set yet.
The context needs to be set before trying to evaluate traversal policies. Setting the context is typically done with the attach method.)
This is my code:
import 'package:quizlet/api/convert_json.dart';
import 'package:quizlet/style.dart';
class CreateQuiz extends StatefulWidget {
const CreateQuiz({super.key});
#override
State<CreateQuiz> createState() => _CreateQuizState();
}
class _CreateQuizState extends State<CreateQuiz> {
int wordCount = 3;
List errorDefinitions = [false, false, false];
List errorAnswers = [false, false, false];
bool errorTitle = false;
bool errorDescription = false;
final List definitions = [
TextEditingController(),
TextEditingController(),
TextEditingController()
];
final List answers = [
TextEditingController(),
TextEditingController(),
TextEditingController()
];
final title = TextEditingController();
final description = TextEditingController();
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
final brightness = MediaQuery.of(context).platformBrightness;
bool darkMode = brightness == Brightness.dark;
final hintColor = darkMode ? Colors.white : Colors.black;
return Scaffold(
appBar: AppBar(
title: const Text("Create Quiz"),
actions: [
TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.white,
),
onPressed: () {
onPressed();
},
child: Text(
"Done",
style: TextStyle(fontSize: height / 55),
),
),
],
),
body: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView(
children: [
SizedBox(
height: height / 40,
),
TextField(
onSubmitted: (value) {
FocusScope.of(context).nextFocus();
},
onChanged: (value) {
setState(() {
errorTitle = false;
});
},
textInputAction: TextInputAction.next,
onEditingComplete: () {},
keyboardType: TextInputType.multiline,
controller: title,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
hintStyle: TextStyle(
color: errorTitle ? Colors.red : hintColor,
),
hintText: errorTitle ? "Title can't be blank" : "Title",
border: const OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: errorTitle ? Colors.red : color1,
width: 2.0,
),
),
),
),
const SizedBox(
height: 5,
),
TextField(
onSubmitted: (value) {
FocusScope.of(context).nextFocus();
},
onChanged: (value) {
setState(() {
errorDescription = false;
});
},
textInputAction: TextInputAction.newline,
onEditingComplete: () {},
controller: description,
maxLines: null,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
hintText: errorDescription
? "Description can't be blank"
: "Description",
hintStyle: TextStyle(
color: errorDescription ? Colors.red : hintColor,
),
border: const OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: errorDescription ? Colors.red : color1,
width: 2.0,
),
),
),
),
SizedBox(
height: height / 20,
),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: wordCount,
itemBuilder: (BuildContext context, int i) {
return Column(
children: [
TextField(
onSubmitted: (value) {
FocusScope.of(context).nextFocus();
},
onChanged: (value) {
setState(() {
errorDefinitions[i] = false;
});
},
textInputAction: TextInputAction.next,
onEditingComplete: () {},
autocorrect: false,
controller: definitions[i],
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
hintStyle: TextStyle(
color: errorDefinitions[i] ? Colors.red : hintColor,
),
hintText: errorDefinitions[i]
? "Definition can't be blank"
: "Definition",
border: const OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: errorDefinitions[i] ? Colors.red : color1,
width: 2.0,
),
),
),
),
const SizedBox(
height: 5,
),
TextField(
onSubmitted: (value) {
setState(() {
if (definitions[i].text != "" &&
answers[i].text != "") {
if (i + 2 >= wordCount) {
wordCount++;
definitions.add(TextEditingController());
answers.add(TextEditingController());
errorAnswers.add(false);
errorDefinitions.add(false);
}
FocusScope.of(context).nextFocus();
}
});
},
onChanged: (value) {
setState(() {
errorAnswers[i] = false;
});
},
textInputAction: TextInputAction.next,
onEditingComplete: () {},
autocorrect: false,
controller: answers[i],
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
hintStyle: TextStyle(
color: errorAnswers[i] ? Colors.red : hintColor,
),
hintText: errorAnswers[i]
? "Answer can't be blank"
: "Answer",
border: const OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: errorAnswers[i] ? Colors.red : color1,
width: 2.0,
),
),
),
),
SizedBox(
height: height / 50,
),
],
);
},
),
],
),
),
),
);
}```
I'm building a form for shipping and am able to add as many items as possible. (Adding a Widget in a ListView every time a button is pressed)
My question is, once the form widgets are created and filled, how do I get the information from each TextFormField in each Widget?
Once the information is retrieved I will send it to Firebase.
Here's the code I Have:
import 'package:flutter/material.dart';
import 'package:flutter_login_test/helpers/constants.dart';
class AddItemsToRequest extends StatefulWidget {
const AddItemsToRequest({Key? key}) : super(key: key);
#override
State<AddItemsToRequest> createState() => _AddItemsToRequestState();
}
class _AddItemsToRequestState extends State<AddItemsToRequest> {
List<TextEditingController> controllers = [];
List<Widget> fields = [];
RegExp regExp = RegExp('[aA-zZ]');
int quantity = 0;
double weight = 0;
double height = 0;
Widget itemForm() {
return Column(children: [
Container(
decoration:
BoxDecoration(color: grey, border: Border.all(color: black)),
width: double.infinity,
child: const Center(
child: Text('Package details',
style: TextStyle(
fontWeight: FontWeight.bold,
backgroundColor: grey,
fontSize: 24)),
)),
Row(
children: [
Flexible(
child: TextFormField(
onChanged: (value) {
quantity = value as int;
},
keyboardType: TextInputType.number,
validator: (value) => value!.isEmpty || value is int
? 'Quantity cannot be empty'
: null,
autovalidateMode: AutovalidateMode.onUserInteraction,
decoration: const InputDecoration(
errorStyle: TextStyle(color: Colors.redAccent),
border: OutlineInputBorder(
borderSide: BorderSide(),
borderRadius: BorderRadius.all(
Radius.circular(0.0),
),
),
fillColor: Color.fromARGB(255, 238, 238, 238),
filled: true,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent, width: 2.5),
),
hintText: "Quantity : "),
),
),
Flexible(
child: TextFormField(
onChanged: (value) {
weight = value as double;
},
keyboardType: TextInputType.number,
validator: (value) => value!.isEmpty || regExp.hasMatch(value)
? 'Weight cannot be empty'
: null,
autovalidateMode: AutovalidateMode.onUserInteraction,
decoration: const InputDecoration(
errorStyle: TextStyle(color: Colors.redAccent),
border: OutlineInputBorder(
borderSide: BorderSide(),
borderRadius: BorderRadius.all(
Radius.circular(0.0),
),
),
fillColor: Color.fromARGB(255, 238, 238, 238),
filled: true,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent, width: 2.5),
),
hintText: "Weight : "),
),
),
Flexible(
child: TextFormField(
onChanged: (value) {
height = value;
},
validator: (value) => value!.isEmpty ? 'Height cannot be empty' : null,
autovalidateMode: AutovalidateMode.onUserInteraction,
decoration: const InputDecoration(
errorStyle: TextStyle(color: Colors.redAccent),
border: OutlineInputBorder(
borderSide: BorderSide(),
borderRadius: BorderRadius.all(
Radius.circular(0.0),
),
),
fillColor: Color.fromARGB(255, 238, 238, 238),
filled: true,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent, width: 2.5),
),
hintText: "Height : "),
),
),
],
),
]);
}
Widget _addTile() {
return ElevatedButton(
child: const Icon(Icons.add),
onPressed: () async {
final controller = TextEditingController();
final field = itemForm();
setState(() {
controllers.add(controller);
fields.add(field);
});
});
}
Widget _listView() {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: fields.length,
itemBuilder: (context, index) {
final item = fields[index];
return Dismissible(
key: ObjectKey(item),
onDismissed: (direction) {
// Remove the item from the data source.
setState(() {
fields.removeAt(index);
});
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('Package removed')));
},
background: Container(
color: const Color.fromARGB(255, 210, 31, 19),
child: const Center(
child: Text(
'Remove ',
style: TextStyle(
color: white, fontWeight: FontWeight.bold, fontSize: 32),
),
)),
child: Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
child: fields[index],
),
);
},
);
}
Widget _okButton() {
return ElevatedButton(
onPressed: () {
for (var element in fields) {
print(quantity);
}
Navigator.of(context).pop();
print('ok');
},
child: const Text("OK"),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: blue),
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(child: _addTile()),
SizedBox(
height: MediaQuery.of(context).size.height - 200,
child: _listView()),
Flexible(child: _okButton()),
],
),
);
}
}
I think you are expecting this answer. iterate your list of texteditingcontroller and get the text stored in that controllers one by one.
for (int i = 0; i < controllers.length; i++) {
var data = controllers[i].text;
//print or add data to any other list and insert to another list and save to database
}
Still a newbie with flutter and was wondering if someone could help me with a problem I'm having. I am trying to create a registeration form with email, password, password confirmation, a county and a zip code. (County and zip code forms are the drop down button form fields) I have successfully coded all else except for the zip code drop down. I would need it to be conditional on the county selection. (In a way that if I select a specific county in cali, it would only display that selected county's zip codes and nothing else). Also if someone would know a quick fix to make the dropdown button form fields empty unless clicked on. My current adaptation on it isn't very functional, since you can just leave the option unanswered, when it's supposed to be mandatory. Thank you in advance :)
Existing code below
(I only have the string for one county zip codes) (Also deleted the irrelevant firebase related code for this post)
class RegisterPage extends StatefulWidget {
const RegisterPage({Key? key}) : super(key: key);
#override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
// dropdown area
_MyFormStateArea(){
selectedArea = dropdownListArea[0];
}
var selectedArea = '';
final dropdownListArea = <String>['', 'LA', 'San Francisco'...'Santa Barbara'];
// dropdown zipcode
_MyFormStateZip(){
selectedZip = dropdownListZip[0];
}
var selectedZip = '';
final dropdownListZip = <String>['', '90001', '90002', '90003',..., '91609'];
// editing Controller
final emailEditingController = new TextEditingController();
final passwordEditingController = new TextEditingController();
final confirmPasswordEditingController = new TextEditingController();
#override
Widget build(BuildContext context) {
// email field
final emailField = TextFormField(
autofocus: false,
controller: emailEditingController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return ("Please enter email.");
}
// reg expression for email validation
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Please enter a working email.");
}
return null;
},
onSaved: (value) {
emailEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.mail_outline_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// password field
final passwordField = TextFormField(
autofocus: false,
controller: passwordEditingController,
obscureText: true,
validator: (value) {
RegExp regex = new RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return ("A password required.");
}
if(!regex.hasMatch(value)) {
return ("Please enter other password (Min. 6 characters)");
}
},
onSaved: (value) {
passwordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
));
// confirm password field
final confirmPasswordField = TextFormField(
autofocus: false,
controller: confirmPasswordEditingController,
obscureText: true,
validator: (value)
{
if(confirmPasswordEditingController.text != passwordEditingController.text)
{
return "Passwords don't match";
}
return null;
},
onSaved: (value) {
confirmPasswordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password again",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// area dropdown
final areaField = DropdownButtonFormField(
value: selectedArea,
items: dropdownListArea.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: dropdownListZip.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// sign up button
final signUpButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.white,
child: MaterialButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
signUp(emailEditingController.text, passwordEditingController.text);
},
child: Text("Sign Up", textAlign: TextAlign.center,
style: TextStyle(fontSize: 20,
color: Colors.lightBlue[900],
fontWeight: FontWeight.bold)
),
),
);
return Scaffold(
backgroundColor: Color(0xFFAED8E6),
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => FrontPage()));
},
icon: Icon(Icons.arrow_back),
color: Colors.lightBlue[900],
),
),
body: Center(
child: SingleChildScrollView(
child: Container(
color: Color(0xFFAED8E6),
child: Padding(
padding: const EdgeInsets.fromLTRB(36, 20, 36, 30),
child: Form(
key: _formKey,
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 170,
child: Image.asset("assets/AR_logoBold.png",
fit: BoxFit.contain
)),
SizedBox(height: 40,),
emailField,
SizedBox(height: 25,),
passwordField,
SizedBox(height: 25,),
confirmPasswordField,
SizedBox(height: 25,),
areaField,
SizedBox(height: 25,),
zipCodeField,
SizedBox(height: 35,),
signUpButton,
SizedBox(height: 15,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("You already own an account? "),
GestureDetector(onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage()));
},
child: Text("Login",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.lightBlue[900])
),)
],
)
],
)),
),
),
),
),
);
}
}
First you should initalize the selectedArea and selectedZip with the first Entry of your List: = dropdownListZip.first and the first entry should not be an empty String
To get only zips that belong to the choosen area you need to know them. At the moment you have two independent lists.
Better you use a map like:
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
Than you can only display zips that belong to the area quite easy.
Take a look at: Flutter Documentation for Map
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
final areaField = DropdownButtonFormField(
value: selectedArea,
items: zipmap.keys.toList().map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: zipmap[selectedArea].map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
im new in flutter and I create a drop down button fields in flutter for the record form. My question is when I click save in the record, how can I make the dropdown is clear (back to the first or no value) for now when I click save, it did not reset the drop down value (still have a value from previous record) And also when I click the clear button, how can I make the drop down is clear? Thanks
class RecordExpense extends StatefulWidget {
#override
_RecordExpenseState createState() => _RecordExpenseState();
}
class _RecordExpenseState extends State<RecordExpense> {
//DatabaseReference _ref;
final date = TextEditingController();
final currency = TextEditingController();
final category = TextEditingController();
final amount = TextEditingController();
final description = TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
final databaseReference = FirebaseFirestore.instance;
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _email, _password;
Future<String> getCurrentUID() async {
Future.value(FirebaseAuth.instance.currentUser);
//return uid;
}
#override
String selectCurrency;
String selectExpense;
final expenseSelected = TextEditingController();
final currencySelected = TextEditingController();
DateTime _selectedDate;
void initState(){
//_ref = FirebaseDatabase.instance.reference().child('Transaction');
}
Widget build(BuildContext context) {
//FirebaseFirestore firestore = FirebaseFirestore.instance;
//CollectionReference collect= firestore.collection("TransactionExpense");
final FirebaseAuth _auth = FirebaseAuth.instance;
final User user =_auth.currentUser;
final uid = user.uid;
String dates;
String amounts;
//String selectExpenses;
String descriptions;
return new Form(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20.0),
child: Container(
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Please fill up the text fields';
},
cursorColor: Colors.grey,
controller: date,
onTap: () {
_selectDate(context);
},
decoration: InputDecoration(
labelText: getTranslated((context), "date_text"),
labelStyle: TextStyle(
fontSize: 18.0, color: Colors.black),
hintText: getTranslated((context), "date_hint"),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
),
),
SizedBox(height: 20),
Row(
children: <Widget> [
new Expanded(child: new DropdownButtonFormField<String>(
value: selectCurrency,
hint: Text(getTranslated((context), "currency_hint"),),
//controller: currencySelected,
//labelText: getTranslated((context), "currency_hint"),
//enabled: true,
//itemsVisibleInDropdown: 4,
//items: currencycategories,
onChanged: (salutation) =>
setState(() => selectCurrency = salutation),
validator: (value) => value == null ? 'Please fill up the drop down' : null,
items:
['IDR.', 'MYR', 'USD', 'CNY'].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
//flex: 2,
),
//value: selectCurrency,
//required: false,
),
new SizedBox(
width: 10.0,
),
new Expanded(child:
TextFormField(
validator: (input) {
if (input.isEmpty) return 'Please fill up the text fields';
},
cursorColor: Colors.grey,
controller: amount,
decoration: InputDecoration(
labelText: getTranslated((context), "amount_text"),
labelStyle: TextStyle(
fontSize: 18.0, color: Colors.black),
hintText: getTranslated((context), "amount_text"),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
keyboardType: TextInputType.number,
),)
],
),
Container(
padding: EdgeInsets.only(top: 20.0),
child: DropdownButtonFormField <String>(
value: selectExpense,
hint: Text(getTranslated((context), "category_text"),),
//controller: currencySelected,
//labelText: getTranslated((context), "currency_hint"),
//enabled: true,
//itemsVisibleInDropdown: 4,
//items: currencycategories,
onChanged: (salutation) =>
setState(() => selectExpense = salutation),
validator: (value) => value == null ? 'Please fill up the drop down' : null,
items:
['Food.', 'Social Life', 'Transportation', 'Beauty', 'Household', 'Education', 'Health', 'Gift', 'Other'].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
//flex: 2,
),
),
SizedBox(height: 20),
Container(
//padding: EdgeInsets.all(20),
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Please fill up the text fields';
},
cursorColor: Colors.grey,
controller: description,
maxLines: 2,
decoration: InputDecoration(
labelText: getTranslated((context), "description_text"),
labelStyle: TextStyle(
fontSize: 18.0, color: Colors.black),
hintText: getTranslated((context), "description_expense"),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
),
),
Container(
padding: EdgeInsets.only(
top: 25.0, left: 20.0, right: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: ElevatedButton(
onPressed: () async {
if(!_formKey.currentState.validate()){
return;
}
_formKey.currentState.save();
await FirebaseFirestore.instance.collection('users').doc(userID).collection('TransactionExpense').add({
'date': date.text,
'currency': selectCurrency,
'amount': amount.text,
'category': selectExpense,
'description': description.text,
});
date.text = "";
amount.text = "";
description.text = "";
//selectCurrency = "";
//selectExpense = "";
/*
UserCredential _user =
await FirebaseAuth.instance.signInWithEmailAndPassword(email: _email, password: _password);
String _uid = _user.user.uid;
*/
//await FirebaseFirestore.instance.collection('TransactionExpense').doc(_uid).set({
/*
final FirebaseAuth _auth = FirebaseAuth
.instance;
final User user = _auth.currentUser;
final uid = user.uid;
await DatabaseService().updateData(
uid, date.text, amount.text,
selectExpense, description.text);
Navigator.pop(context);
*/
},
child: Text(
getTranslated((context), "save_button").toUpperCase(), style: TextStyle(
fontSize: 14,
)),
style: ButtonStyle(
padding: MaterialStateProperty.all<
EdgeInsets>(EdgeInsets.all(15)),
foregroundColor: MaterialStateProperty
.all<Color>(Colors.white),
backgroundColor: MaterialStateProperty
.all<Color>(Colors.pink),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
15.0),
side: BorderSide(color: secondary)
),
),
),
),
),
SizedBox(width: 20, height: 10),
Expanded(
child: ElevatedButton(
onPressed: () {
clearButton();
},
child: Text(
getTranslated((context), "clear_button").toUpperCase(), style: TextStyle(
fontSize: 14
)),
style: ButtonStyle(
padding: MaterialStateProperty.all<
EdgeInsets>(EdgeInsets.all(15)),
foregroundColor: MaterialStateProperty
.all<Color>(Colors.white),
backgroundColor: MaterialStateProperty
.all<Color>(Colors.pink),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
15.0),
side: BorderSide(color: secondary)
),
),
),
),
)
],
)
),
],
),
),
),
)
),
);
}
void clearButton(){
date.clear();
amount.clear();
category.clear();
description.clear();
//selectCurrency.clear();
}
_selectDate(BuildContext context) async {
DateTime newSelectedDate = await showDatePicker(
context: context,
initialDate: _selectedDate != null ? _selectedDate : DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2040),
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.dark().copyWith(
colorScheme: ColorScheme.dark(
primary: secondary,
onPrimary: Colors.black,
surface: primary,
onSurface: Colors.white,
),
dialogBackgroundColor: Colors.black,
),
child: child,
);
});
if (newSelectedDate != null) {
_selectedDate = newSelectedDate;
date
..text = DateFormat.yMMMd().format(_selectedDate)
..selection = TextSelection.fromPosition(TextPosition(
offset: date.text.length,
affinity: TextAffinity.upstream));
}
}
}
class AlwaysDisabledFocusNode extends FocusNode {
#override
bool get hasFocus => false;
}
When the user taps on the save button the onPressed function is executed, inside that function use setstate to set selectCurrency = null; & selectExpense = null;. This will make the dropdownbutton show the hint instead of old record
class _HomeScreenState extends State<HomeScreen> {
TextEditingController _textController = TextEditingController();
var list = List<Widget>();
var channels = ChannelService.channels;
....
buildBody() {
return Container(
child: Column(children: [
searchArea(),
Expanded(
flex: 6,
child: ListView.builder(
itemCount: channels.length,
itemBuilder: (BuildContext context, int index){
return ChannelService.getChannelWidget(channels[index]);
},
)
),
ControlPanel()
]));
}
searchArea() {
return Container(
color: Colors.black87,
height: 45,
padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5),
child: TextField(
cursorColor: Colors.black,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: EdgeInsets.only(left: 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: BorderSide(color: Colors.black87, width: 3)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: BorderSide(color: Colors.red, width: 2)),
hintText: "Aramak için yazın.",
hintStyle: TextStyle(color: Colors.black),
suffixIcon: Icon(
Icons.search,
size: 30,
color: Colors.black,
)),
controller: _textController,
onChanged: onChanged,
),
);
}
onChanged(String value) {
if(value.isNotEmpty){
setState(() {
channels = ChannelService.channels
.where((item) => item.name.toLowerCase().contains(value.toLowerCase()))
.toList();
});
}
else{
setState(() {
channels = ChannelService.channels;
});
}
}
}
Results:This
I've been dealing with this error for a long time. What I want to do is a simple search operation. However, I could not succeed. The word I want to search for and the result are different. Please help me.
Where am i doing wrong?
Another problem. My app was started listview is empty.
getChannelWidget:
static Widget getChannelWidget(Channel channel) {
return ChannelListWidget(
id: channel.id,
name: channel.name,
image: channel.image,
categories: channel.categories.toList(),
url: channel.url,
listened: channel.listened,
favorite: isFavorite(channel.id)
);