I can't search in listview, results are wrong - flutter

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)
);

Related

How can I send post request with the attached api?

I want to send post request to this api:
Here is the sample bearer token :
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjY3MjMzNjEzLCJpYXQiOjE2NjcxNDcyMTMsImp0aSI6IjgyNDg0YWYzMDdmOTQ0YjNhMTQ5ZWIzN2NkNjIzNGI4IiwiaWQiOjV9.qc9fmF4B0V6NTwxsztBb6AkF78kU_06wommCa5gLgOo
What I tried:
Here Is my Controller for the API:
Future<bool> createDisplay(
String name, String category, String templateName, int productId) async {
var url = Uri.parse(
"https://digital-display.betafore.com/api/v1/digital-display/displays/");
var token = localStorage.getItem('access');
try {
var formdata = new Map<String, dynamic>();
formdata["name"] = name;
formdata["category"] = category;
formdata["template_name"] = templateName;
formdata["products"] = productId;
http.Response response =
await http.post(url, body: json.encode(formdata), headers: {
"Content-Type": "application/json",
'Authorization':
'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjY3MjMzNjEzLCJpYXQiOjE2NjcxNDcyMTMsImp0aSI6IjgyNDg0YWYzMDdmOTQ0YjNhMTQ5ZWIzN2NkNjIzNGI4IiwiaWQiOjV9.qc9fmF4B0V6NTwxsztBb6AkF78kU_06wommCa5gLgOo'
});
Future.error(response.body);
var data = json.encode(response.body) as Map;
if (response.statusCode == 200) {
print(response.body);
return Future.error("Its working");
} else {
return Future.error("Code Proble");
}
} catch (exception) {
Future.error("Something is wrong with the codes");
return false;
}
}
Here is the front end code where I tried to send post request using textformfield.
import 'package:digitaldisplay/controllers/DisplayController.dart';
import 'package:digitaldisplay/views/widgets/Display.dart';
import 'package:digitaldisplay/views/widgets/ProductDisplayCard.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:provider/provider.dart';
class CreateDisplay extends StatefulWidget {
const CreateDisplay({super.key});
static const routeName = "/create-display";
#override
State<CreateDisplay> createState() => _CreateDisplayState();
}
class _CreateDisplayState extends State<CreateDisplay> {
String _name = "";
String _category = "";
String _templateName = "";
late final int _product;
// String catelogImage = "";
// String video = "";
//String productId = "";
final _form = GlobalKey<FormState>();
void _addDisplay() async {
var isValid = _form.currentState!.validate();
if (!isValid) {
return;
}
_form.currentState!.save();
bool create = await Provider.of<DisplayController>(context, listen: false)
.createDisplay(_name, _category, _templateName, _product);
if (create) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Created"),
actions: [
ElevatedButton(
child: const Text("Return"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Failed to create display!"),
actions: [
ElevatedButton(
child: const Text("Return"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
}
child: Form(
key: _form,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Padding(
padding: EdgeInsets.all(10),
child: TextFormField(
validator: (v) {
if (v!.isEmpty) {
return "Please Enter a valid name";
} else {
return null;
}
},
onSaved: (value) {
_name = value as String;
},
autofocus: true,
style: const TextStyle(
fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Name',
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 73, 57, 55)),
borderRadius: BorderRadius.circular(0.0),
),
enabledBorder: UnderlineInputBorder(
borderSide:
const BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(0.0),
),
),
),
),
),
Flexible(
child: Padding(
padding: EdgeInsets.all(10),
child: TextFormField(
validator: (v) {
if (v!.isEmpty) {
return "Please enter valid category title";
} else {
return null;
}
},
onSaved: (value) {
_category = value as String;
},
autofocus: true,
style: const TextStyle(
fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Category',
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 73, 57, 55)),
borderRadius: BorderRadius.circular(0.0),
),
enabledBorder: UnderlineInputBorder(
borderSide:
const BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(0.0),
),
),
),
),
),
Flexible(
child: Padding(
padding: EdgeInsets.all(10),
child: TextFormField(
validator: (v) {
if (v!.isEmpty) {
return "Please enter valid template name";
} else {
return null;
}
},
onSaved: (value) {
_templateName = value as String;
},
autofocus: true,
style: const TextStyle(
fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Template Name',
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 73, 57, 55)),
borderRadius: BorderRadius.circular(0.0),
),
enabledBorder: UnderlineInputBorder(
borderSide:
const BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(0.0),
),
),
),
),
),
Flexible(
child: Padding(
padding: EdgeInsets.all(10),
child: TextFormField(
keyboardType: TextInputType.number,
validator: (v) {
if (v!.isEmpty) {
return "Please enter valid product Id";
} else {
return null;
}
},
onSaved: (value) {
_product = int.tryParse(value!) ?? 0;
},
autofocus: true,
style: const TextStyle(
fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Product Id',
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 73, 57, 55)),
borderRadius: BorderRadius.circular(0.0),
),
enabledBorder: UnderlineInputBorder(
borderSide:
const BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(0.0),
),
),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
_addDisplay();
},
child: Text("Add Display"),
style: buttonStyle2,
),
),
),
],
),
],
I only added the code of my frontend where I tried to pass the value. But Can't post data. I am getting an error also. The error is:
{"status":"error","message":{"products":["Expected a list of items but got type \"int\"."]}}
When I send data using postman It works perfectly. I think its for formdata though I am not sure about it. Is there any solution for this issue?
It says it in the error there. "Expected a list of items but got type "int" In your post you are putting productId which is an int in the "products". The backend is looking for a list of products here. You can try
formdata["products"] = [productId];
to see what you come up with. I don't know what the backend is looking for in terms of the products list though. It is strange that the post with an int works in Postman too.

How to get data in a Flutter-ListView?

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
}

How to upload images in Firestore collection flutter

I have a user profil form , and i want the profile image to be stored in firestore with the other infromation of the user ! I did the part of stocking the information but idon't know how to store the image in the same document!
can you please help me ?
My code can just pick the picture , i didn't integrate the part of storing it in firestore
const kTextFieldDecoration = InputDecoration(
hintText: 'Enter a value',
hintStyle: TextStyle(color: Colors.grey),
contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xff5AA7A7), width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xff5AA7A7), width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
);
class Background extends StatefulWidget {
final Widget child;
const Background({
Key? key,
required this.child,
}) : super(key: key);
#override
_BackgroundState createState() => _BackgroundState();
}
class _BackgroundState extends State<Background>{
final _auth = FirebaseAuth.instance;
final _firebaseStorage = FirebaseStorage.instance ;
uploadImage() async {
Reference ref = _firebaseStorage.ref().child('profileimage');
UploadTask uploadTask = ref.putFile(imageFile);
var imageUrl = await ( await uploadTask).ref.getDownloadURL();
setState(() => {
imageurl= imageUrl.toString()
});
}
late File imageFile;
late String name;
late DateTime birth ;
late String pass ;
late String? genre ;
TextEditingController dateinput = TextEditingController();
final List<String> genderItems = [
'Male',
'Female',
];
String? selectedValue;
final ImagePicker _picker = ImagePicker();
bool showSpinner = false;
static final DateFormat format = DateFormat('yyyy-MM-dd');
File? imagePicked;
late Future<PickedFile?> pickedFile = Future.value(null);
String? imageurl ;
// Pick Image From Gallery
_getFromGallery() async {
final picker = ImagePicker();
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
);
final pickedImageFile = File(pickedImage!.path);
setState(() {
imagePicked = pickedImageFile;
});
}
void addPatient() {
FirebaseFirestore.instance.collection("patient").add(
{
"name" : name,
"genre" : genre,
"birth" : birth,
"pass" : pass,
}).then((value){
print("Patient data Added");
});
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
resizeToAvoidBottomInset: false ,
backgroundColor: Colors.white,
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
child : CircleAvatar(
radius: 70.0,
backgroundColor: Colors.grey,
backgroundImage: imagePicked == null
? null
: FileImage(
imagePicked!,
),
),
),
Container(
padding: EdgeInsets.only( left: 100.0),
child : Positioned(
bottom: 50.0,
right: 20.0,
child: InkWell(
onTap: () {
_getFromGallery();
},
child: Icon(
Icons.camera_alt_outlined,
size:28.0,color:
Colors.teal,
),
),
), ),
SizedBox(
height: 25.0,
),
SizedBox(
height: 8.0,
),
TextField(
keyboardType: TextInputType.text,
textAlign: TextAlign.center,
onChanged: (value) {
name = value;
},
decoration: kTextFieldDecoration.copyWith(
labelText: 'Name')),
SizedBox(
height: 8.0,
),
SizedBox(
height: 8.0,
),
TextField(
obscureText: true,
textAlign: TextAlign.center,
onChanged: (value) {
pass = value ;
},
decoration: kTextFieldDecoration.copyWith(
labelText: 'Password',)),
SizedBox(
height: 8.0,
),
SizedBox(
height: 8.0,
),
Column(
children: [
DropdownButtonFormField(
decoration:
//Add isDense true and zero Padding.
//Add Horizontal padding using buttonPadding and Vertical padding by increasing buttonHeight instead of add Padding here so that The whole TextField Button become clickable, and also the dropdown menu open under The whole TextField Button.
InputDecoration(
hintStyle: TextStyle(color: Colors.grey),
contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xff5AA7A7), width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xff5AA7A7), width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
//Add more decoration as you want here
//Add label If you want but add hint outside the decoration to be aligned in the button perfectly.
labelText: 'Gender',
),
isExpanded: true,
icon: const Icon(
Icons.arrow_drop_down,
color: Colors.teal,
),
iconSize: 30,
items: genderItems
.map((item) =>
DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
validator: (value) {
if (value == null) {
return 'Please select gender.';
}
},
onChanged: (value) {
genre = value as String? ; //Do something when changing the item if you want.
},
onSaved: (value) {
selectedValue = value.toString();
},
),
],
),
SizedBox(
height: 8.0,),
SizedBox(
height: 8.0,
),
TextField(
controller: dateinput,
textAlign: TextAlign.center,
readOnly: true,
decoration: InputDecoration(
hintStyle: TextStyle(color: Colors.grey),
contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xff5AA7A7), width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xff5AA7A7), width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
//icon of text field
labelText: "Date of Birth" , //label text of field
),
onTap: () => BottomPicker.date(
minDateTime: DateTime(1900),
maxDateTime: DateTime.now(),
dateOrder: DatePickerDateOrder.dmy ,
bottomPickerTheme: BOTTOM_PICKER_THEME.morningSalad,
closeIconColor: Colors.teal,
title: "Set your Birthday",
titleStyle: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.teal,
),
onSubmit: (value) {
dateinput.text = '$value';
birth = value ;
} ,
).show(context),
),
RoundedButton(
colour: Color(0xff96D7C6),
title: 'Submit',
onPressed: () async {
setState(() {
showSpinner = true;
addPatient();
});
Navigator.pushNamed(context, 'patient_screen');
}, ),],),),),),);}}
You can use Firebase Storage ( firebase_storage ) to upload the image file and then you store the download url of the image inside the document in the Cloud Firestore ( cloud_firestore ).
Here is the official docs for using Firebase Storage with Flutter, Inside you can find a section that explains the steps to upload files, and another to get the download URL.

Can i Select Multiple Accounts in a Banking app and pay them different amounts at the same time in flutter?

import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart';
import 'package:money_formatter/money_formatter.dart';
import 'package:shukela_app/api/banking_app_api.dart';
import 'package:shukela_app/screens/stokvel_detail.dart';
import 'package:shukela_app/screens/stokvels.dart';
import 'package:shukela_app/utils/constants.dart';
import 'package:shukela_app/utils/global_variables.dart';
import 'package:sizer/sizer.dart';
import 'package:shukela_app/model/bankingapp_model.dart';
import '../utils/user_preferences.dart';
class PayMultipleStokvelScreen extends StatefulWidget {
const PayMultipleStokvelScreen({Key? key}) : super(key: key);
#override
State<PayMultipleStokvelScreen> createState() =>
_PayMultipleStokvelScreenState();
}
TextEditingController txtSearch = TextEditingController();
TextEditingController txtAmount = TextEditingController();
class _PayMultipleStokvelScreenState extends State<PayMultipleStokvelScreen> {
String? selectedType;
bool hasText = false;
String buttonText = "PAY NOW";
bool isLoading = false;
Widget? showHideIcon() {
if (hasText) {
return IconButton(
icon: const Icon(
Icons.clear,
color: AppColors.primaryBlue,
),
onPressed: () {
txtSearch.clear();
setState(() {
hasText = false;
});
},
);
} else {
return null;
}
}
// void _showMultiSelectDialog(BuildContext context) async {
// await showDialog(
// context: context,
// builder: (ctx) {
// return MultiSelectDialog(
// items: _animals.map((e) => MultiSelectItem(e, e)).toList(),
// initialValue: _selectedAnimals,
// onConfirm: (values) {...},
// );
// },
// );
// }
double? balance;
final _formKey = GlobalKey<FormState>();
var selectedValue;
List<StokvelDetail> selectedStokvel = [];
#override
void initState() {
super.initState();
balance = double.parse(UserPreferences.getBalance() ?? '');
}
mf() {
MoneyFormatter mf = MoneyFormatter(amount: balance!);
return mf;
}
StokvelListState currentState = StokvelListState.showAllListState;
#override
Widget build(BuildContext context) => KeyboardDismisser(
gestures: const [GestureType.onTap],
child: SafeArea(
child: Scaffold(
backgroundColor: AppColors.secondaryColor,
appBar: AppBar(
backgroundColor: AppColors.secondaryColor,
elevation: 0,
title: const Text('Pay Multiple Stokvel',
style: screenTitleTextStyle),
leading: IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: AppColors.primaryBlue,
),
onPressed: () => Navigator.pop(context),
),
),
body: Form(
key: _formKey,
child: Column(
children: [
SizedBox(height: 5.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TypeAheadFormField<Stokvel?>(
debounceDuration: const Duration(milliseconds: 500),
hideSuggestionsOnKeyboardHide: false,
suggestionsBoxDecoration: const SuggestionsBoxDecoration(
constraints: BoxConstraints(maxHeight: 450),
color: AppColors.secondaryColor,
borderRadius: BorderRadius.all(Radius.circular(10))),
textFieldConfiguration: TextFieldConfiguration(
style: const TextStyle(
color: AppColors.primaryBlue,
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
controller: txtSearch,
onChanged: (value) {
setState(() {
hasText = true;
});
},
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.search,
color: AppColors.primaryBlue,
),
suffixIcon: showHideIcon(),
hintText: 'Search Stokvel',
border: const OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4.0),
borderSide:
const BorderSide(color: AppColors.primaryBlue),
),
),
),
validator: (val) {
if (val!.isEmpty) {
return "Please select stokvel";
}
return null;
},
suggestionsCallback: BankingAppApi.getStokvelSuggestions,
itemBuilder: (context, Stokvel? suggestion) {
final stokvel = suggestion!;
//
return ListTile(
trailing: SizedBox(
height: 20.0,
width: 20.0,
child: Container(
color: AppColors.primaryBlue,
),
),
title: Text(
stokvel.stokvelName!,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue,
),
),
subtitle: Text(
stokvel.stokvelType!,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue),
),
);
},
noItemsFoundBuilder: (context) => const SizedBox(
height: 60,
child: Center(
child: Text(
'No Stokvel Found.',
style: TextStyle(fontSize: 20),
),
),
),
onSuggestionSelected: (Stokvel? suggestion) {
final stokvel = suggestion!;
setState(() {
txtSearch.text = stokvel.stokvelName!;
hasText = true;
});
stokvelID = stokvel.stokvelID;
memberID = stokvel.memberID;
},
),
),
SizedBox(
height: 4.h,
),
SizedBox(height: 3.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TextFormField(
controller: txtAmount,
decoration: const InputDecoration(
labelStyle: TextStyle(
color: AppColors.primaryBlue,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
suffixText: "ZAR",
border: OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
labelText: 'Amount',
contentPadding:
EdgeInsets.only(left: 20, right: 15, bottom: 8),
),
keyboardType: TextInputType.number,
style: const TextStyle(
fontSize: 20.0,
fontFamily: Fonts.primaryFont,
color: AppColors.primaryBlue),
validator: (val) {
if (val!.isEmpty) {
return "Please enter amount";
}
return null;
},
),
),
SizedBox(height: 3.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TextField(
readOnly: true,
style: const TextStyle(
fontSize: 18.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "Wallet Balance : R " + mf().output.nonSymbol,
border: const OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue),
borderRadius: BorderRadius.horizontal()),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
),
),
),
SizedBox(height: 3.h),
Container(
height: 50,
width: 400,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white)),
child: isLoading
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(
color: AppColors.secondaryColor),
SizedBox(width: 24),
Text(
"Submitting payment...",
style: TextStyle(
color: AppColors.secondaryColor),
)
],
)
: Text(
buttonText,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue),
),
onPressed: () {
if (_formKey.currentState!.validate()) {
if (double.parse(txtAmount.text) <= balance!) {
setState(
() {
isLoading = true;
},
);
stokvelTransact.amount =
double.parse(txtAmount.text);
stokvelTransact.memberID = memberID;
stokvelTransact.stokvelID = stokvelID;
stokvelTransact.transactionTypeID = 1;
api
.stokvelDeposit(stokvelTransact,
"StokvelTransaction/StokvelTransact")
.then(
(value) => setState(
() {
Future.delayed(
const Duration(seconds: 3));
isLoading = false;
if (value == "Success") {
ScaffoldMessenger.of(context)
.showSnackBar(snackBar(
content:
'Payment made succesfully',
duration: 5));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(snackBar(
content:
'We have encountered technical problems, Try again later',
duration: 5));
}
},
),
)
.catchError(
(err) {
setState(() {
isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
content: err.toString(), duration: 7));
},
);
} else {
ScaffoldMessenger.of(context).showSnackBar(snackBar(
content: "Insuficient funds!", duration: 7));
}
}
},
),
),
],
),
),
),
),
);
}
The above code is for the single page that I want to achieve this
This is what I want to achieve or any suggestions are accepted, I want to mark the Group of Stokvels I want to pay and pay them different accounts I don't know if it's possible please I'm new in flutter it a project I have to get it done as soon as possible this is the source code for my whole payment page, for now, I'm able to pay a single Stokvel Group but I want to select multiple
I highly suggest starting with formatting of the current code - its hard to read and with that hard to maintain.
The simple idea would be:
use List<StokvelDetail> selectedStokvel = []; you created to add the Stokvel's in every time you select Stokvel in SearchBar
Add Map<int,double> amounts = {}; <StokvelId, amount> to keep track of the amount you want to send to each Stokvel
Based on selectedStokvel build multiple 'amount window' widgets
Before submit verify walletBalance >= amounts.values.reduce((a,b)=> a + b)
For each selectedStokvel call api.stokvelDeposit(stokvelTransact, ...
I would primarly focus on spliting this code to multiple Widget classes, there are many schools but I like to have around 150 lines of code in single file at most.
From what i see your file can be easily split into:
Column(
children: [
SizedBox(),
SearchBar(),
SizedBox(),
AmountInput(), --> StokvelAmountInput() for each selectedStokvel
SizedBox(),
WalletBalance(),
SizedBox(),
SubmitButton(),
]),
```

flutter my textfiled dropdown button options not selecting

[]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;
},
),
),
]
)
),