Home > Net >  Update Text() based on user input in a TextFormField() within a form, perform a calculation and disp
Update Text() based on user input in a TextFormField() within a form, perform a calculation and disp

Time:02-10

I'm still new in Flutter, I'm trying to Update Text() based on user input in a TextFormField() within a form, perform two calculations and display results in other TextFormField() then POST the data to an API on pressing the Upload Button. I have tried using setState(){} as below but it's not working out. 'serviceFee' is supposed to be 2% of the 'amount' entered by the user then 'takeHome' is supposed to be 'amount' minus 'serviceFee'. Below is my code...

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:keilvog/Screens/6kg_cylinder_screen.dart';
import 'package:keilvog/Widget/edit_image.dart';
import 'package:keilvog/Widget/header.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:http/http.dart' as http;
import 'package:keilvog/Widget/validators.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SellDetails extends StatefulWidget {
  const SellDetails({Key? key}) : super(key: key);

  @override
  State<SellDetails> createState() => _SellDetailsState();
}

class _SellDetailsState extends State<SellDetails> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  final brandController = TextEditingController();
  final capacityController = TextEditingController();
  final amountController = TextEditingController();
  final serviceFeeController = TextEditingController();
  final takeHomeController = TextEditingController();
  File? image;

  bool isLoading = false;
  double _serviceFee = 0;
  // ignore: unused_field
  double _takeHome = 0;
  double amount = 0;


  Future UploadData({
    String? brand,
    String? capacity,
    double? amount,
    double? serviceFee,
    double? takeHome,
    File? image
  }) async
  {
    final SharedPreferences preferences = await SharedPreferences.getInstance();
    final String? myJWT = preferences.getString('jwt');
    Map<String, dynamic> token = jsonDecode(myJWT!);
    final myResponse = await http.post(
    Uri.parse('https://kelivog.com/sell/cylinder'),
    headers: <String, String>{
                'Content-Type': 'application/json; charset=UTF-8',
                'X-Requested-With': 'XMLHttpRequest',
                'Authorization': '$token',
                },
      
    body: jsonEncode(
      {
        'brand': brand,
        'capacity': capacity,
        'amount': amount,
        'serviceFee': serviceFee,
        'takeHome': takeHome,
        'image':'data:image/png;base64,'   base64Encode(image!.readAsBytesSync()),
      }),
    
    );
    return myResponse.statusCode;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
          image: DecorationImage(
              image: AssetImage("images/background.jpg"), fit: BoxFit.cover)),
      child: Scaffold(
        // body: SingleChildScrollView(
        body: SingleChildScrollView(
          child: Column(
            children: [
              header(),
              SizedBox(height: 20.h),
              const EditImage(),
              SizedBox(height: 30.h),
              Container(
                width: 350.w,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(15.r)),
                  image: const DecorationImage(
                    image: AssetImage("images/background.jpg"),
                    fit: BoxFit.fitWidth,
                    alignment: Alignment.topCenter,
                  ),
                  boxShadow: const [
                    BoxShadow(color: Colors.grey, spreadRadius: 2),
                  ],
                ),
                child: Column(
                  children: [
                    Padding(
                      padding: EdgeInsets.symmetric(
                          vertical: 12.h, horizontal: 16.w),
                      child: Row(
                        children: [
                          Expanded(
                            child: Text("BRAND",
                                style: TextStyle(
                                  fontSize: 18.sp,
                                  fontWeight: FontWeight.bold,
                                )),
                          ),
                          SizedBox(width: 1.w),
                          Expanded(
                            child: Container(
                              width: 90.w,
                              height: 40.h,
                              decoration: BoxDecoration(
                                  color: Colors.yellow[600],
                                  borderRadius: BorderRadius.circular(15)),
                              child: Center(
                                child: TextFormField(
                                  //textAlignVertical: TextAlignVertical.center,
                                  validator: brandValidator,
                                  controller: brandController,
                                  showCursor: false,
                                  style: const TextStyle(
                                    fontSize: 20.0,
                                    height: 2.0,
                                    color: Colors.black,
                                  ),
                                  decoration: const InputDecoration(
                                    contentPadding: EdgeInsets.only(
                                        top: 1.0, bottom: 100.0, left: 8.0),
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(15.0)),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    //const Divider(indent: 15, endIndent: 15, thickness: 2),

                    Padding(
                      padding: EdgeInsets.symmetric(
                          vertical: 12.h, horizontal: 16.w),
                      child: Row(
                        children: [
                          Expanded(
                            child: Text("CAPACITY",
                                style: TextStyle(
                                  fontSize: 18.sp,
                                  fontWeight: FontWeight.bold,
                                )),
                          ),
                          SizedBox(width: 1.w),
                          Expanded(
                            child: Container(
                              width: 90.w,
                              height: 40.h,
                              decoration: BoxDecoration(
                                  color: Colors.yellow[600],
                                  borderRadius: BorderRadius.circular(15)),
                              child: Center(
                                child: TextFormField(
                                  validator: capacityValidator,
                                  controller: capacityController,
                                  showCursor: false,
                                  style: const TextStyle(
                                    fontSize: 20.0,
                                    height: 2.0,
                                    color: Colors.black,
                                  ),
                                  decoration: const InputDecoration(
                                    contentPadding: EdgeInsets.only(
                                        top: 1.0, bottom: 100.0, left: 8.0),
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(15.0)),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

                    Padding(
                      padding: EdgeInsets.symmetric(
                          vertical: 12.h, horizontal: 16.w),
                      child: Row(
                        children: [
                          Expanded(
                            child: Text("AMOUNT",
                                style: TextStyle(
                                  fontSize: 18.sp,
                                  fontWeight: FontWeight.bold,
                                )),
                          ),
                          SizedBox(width: 1.w),
                          Expanded(
                            child: Container(
                              width: 90.w,
                              height: 40.h,
                              decoration: BoxDecoration(
                                  color: Colors.yellow[600],
                                  borderRadius: BorderRadius.circular(15)),
                              child: Center(
                                child: TextFormField(
                                  validator: amountValidator,
                                  controller: amountController,
                                  keyboardType: TextInputType.number,
                                  showCursor: false,
                                  style: const TextStyle(
                                    fontSize: 20.0,
                                    height: 2.0,
                                    color: Colors.black,
                                  ),
                                  decoration: const InputDecoration(
                                    contentPadding: EdgeInsets.only(
                                        top: 1.0, bottom: 100.0, left: 8.0),
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(15.0)),
                                    ),
                                  ),
                                  onChanged: (value) {
                                    setState(() {
                                      amount = value as double;
                                    });
                                  },
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

                    Padding(
                      padding: EdgeInsets.symmetric(
                          vertical: 12.h, horizontal: 16.w),
                      child: Row(
                        children: [
                          Expanded(
                            child: Text("SERVICE FEE",
                                style: TextStyle(
                                  fontSize: 18.sp,
                                  fontWeight: FontWeight.bold,
                                )),
                          ),
                          SizedBox(width: 1.w),
                          Expanded(
                            child: Container(
                              width: 90.w,
                              height: 40.h,
                              decoration: BoxDecoration(
                                  color: Colors.yellow[600],
                                  borderRadius: BorderRadius.circular(15)),
                              child: Center(
                                //child: Text(serviceFeeController.text),
                                child: TextFormField(
                                  onChanged: (value) => setState(() {
                                    _serviceFee = value as double;
                                  }),
                                  // validator: ,
                                  // controller: ,
                                  showCursor: false,
                                  style: const TextStyle(
                                    fontSize: 20.0,
                                    height: 2.0,
                                    color: Colors.black,
                                  ),
                                  decoration: const InputDecoration(
                                    contentPadding: EdgeInsets.only(
                                        top: 1.0, bottom: 100.0, left: 8.0),
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(15.0)),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

                    Padding(
                      padding: EdgeInsets.symmetric(
                          vertical: 12.h, horizontal: 16.w),
                      child: Row(
                        children: [
                          Expanded(
                            child: Text("TAKE HOME",
                                style: TextStyle(
                                  fontSize: 18.sp,
                                  fontWeight: FontWeight.bold,
                                )),
                          ),
                          SizedBox(width: 1.w),
                          Expanded(
                            child: Container(
                              width: 90.w,
                              height: 40.h,
                              decoration: BoxDecoration(
                                  color: Colors.yellow[600],
                                  borderRadius: BorderRadius.circular(15)),
                              child: Center(
                                //child: Text(serviceFeeController.text),
                                child: TextFormField(
                                  onChanged: (value) => setState(() {
                                    _takeHome = value as double;
                                  }),
                                  // validator: ,
                                  // controller: ,
                                  showCursor: false,
                                  style: const TextStyle(
                                    fontSize: 20.0,
                                    height: 2.0,
                                    color: Colors.black,
                                  ),
                                  decoration: const InputDecoration(
                                    contentPadding: EdgeInsets.only(
                                        top: 1.0, bottom: 100.0, left: 8.0),
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(15.0)),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    // rowItem('BRAND'),
                    // rowItem('CAPACITY'),
                    // rowItem('AMOUNT'),
                    // rowItem('SERVICE FEE'),
                    // rowItem('TAKE HOME'),
                  ],
                ),
              ),
              SizedBox(height: 40.h),
              ElevatedButton(
                onPressed: () async {
                  setState(() {
                    _serviceFee = (amount * 0.02);
                  });

                  setState(() {
                    _takeHome = amount - _serviceFee;
                  });
                  //final FormState? form = _formKey.currentState;
                  if (_formKey.currentState!.validate()){
                    if (image != null) {
                      await UploadData(
                        image: image,
                        brand: brandController.text,
                        capacity: capacityController.text,
                        amount: amountController.text as double,
                        serviceFee: serviceFeeController.text as double,
                        takeHome: takeHomeController.text as double
                      );                       
                    }
                    else
                    {
                      // ignore: avoid_print
                      print('You have not added an image');
                    }
                    if (isLoading) {
                      Navigator.pushReplacement(
                          context,
                          MaterialPageRoute(
                              builder: (context) =>
                                  const SixCylindersListsScreen(
                                    item: '', id: '', title: '',
                                  )));
                    } else {
                      throw Exception('Failed to upload details.');
                    }
                  }                  
                },
                child: Text(
                  'UPLOAD',
                  style: TextStyle(
                    color: Colors.yellow[600],
                    fontSize: 22.sp,
                    fontWeight: FontWeight.w700,
                  ),
                ),
                style: ElevatedButton.styleFrom(
                  elevation: 5,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15.r),
                  ),
                  fixedSize: Size(150.w, 50.h),
                  primary: const Color(0xff261005),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

}

CodePudding user response:

use double.parse(value) to be able to assign value to the double declared values

CodePudding user response:

Here a quick example

 void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget { 

  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp>{
  
  final TextEditingController _controller = TextEditingController();
  double? fees;
  double? takeHome;
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Column(
            children: [
          TextFormField(
            decoration: const InputDecoration(
                labelText: 'Type the amount',
              ),
            controller: _controller,
          ),
          const SizedBox(height: 20),
          OutlinedButton(
            child:const Text('OK'),
            onPressed: () => _doTheMath(),
          ),
          const SizedBox(height: 20),
              if(fees != null)
               Text('fee: $fees'),
          const SizedBox(height: 20),
              if(takeHome != null)
               Text('takeHome: $takeHome'),
        ]),
      ),
    );
  }
  
   _doTheMath(){
     //perform validation then do the math
     double? amount = double.tryParse(_controller.text);
     if(amount != null) {
       setState((){
         final serviceFee = amount * 0.02;
         fees = serviceFee;
         takeHome = amount - serviceFee;
       });
     } else {
       print('Invalid input');
       setState((){
         fees = null;
         takeHome = null;
       });
     }
  }
}
  • Related