1

I have created my text field which should only allow number input for the purpose of some computing i will later do after the value has been input. Its almost working fine but there is one issue though.

Here is the code for the field

var numberInputFormatters = [new FilteringTextInputFormatter.allow(RegExp("[0-9]")),];


  String _tip='2';
  Widget _buildOtherTipInput() {
    return TextFormField(
      style: inputTextStyle,
      inputFormatters: numberInputFormatters,
      keyboardType: TextInputType.number,
      decoration: formInputDecoration.copyWith(
          prefix: Text('\$'),
          labelText: 'Enter Custom Tip Amount ',
          hintStyle: TextStyle(fontWeight: FontWeight.w600)
      ),
      onChanged: (val){
       setState(() {
         val!=null?_tip=val:_tip='0';
       });
      },

    );
  }

So when you input a number then try to input a non number character, it will not take the input but if i try to input a character that is not a number as the first, i get this error thrown

Invalid double

I do know that it comes from this code below that converts the string input to a double. What i don't understand is why it receives the invalid double in the first place yet i have set blockers for invalid(non number) input in my text field.

  String getTotal(){
    String theTip=_tip??'0';
     double  newTip = double.parse(theTip).truncateToDouble();
    return newTip.toStringAsFixed(2);
  }
6
  • You error should tell you the lines of code the error is coming from. Cold you paste the full error message in the post? Commented Mar 4, 2021 at 15:17
  • Do you have the same problem on a first string character with FilteringTextInputFormatter.digitsOnly api.flutter.dev/flutter/services/FilteringTextInputFormatter/… ? Commented Mar 4, 2021 at 15:21
  • There's obviously some code missing as nowhere in the code you provided does it call getTotal(). It will be difficult for us to give you any help if the problem resides in another part of your code. Could you please add the relevant part where getTotal() is called ? Commented Mar 4, 2021 at 15:24
  • @BabC i haven't tried it Commented Mar 4, 2021 at 15:41
  • @Muldec i was calling it to render on Ui text , but it's all sorted now. Commented Mar 4, 2021 at 15:42

2 Answers 2

3

Quick answer

Your problem is that val is never null.

After inputting a wrong character, val is ''. You should check if it is empty:

onChanged: (val){
  setState(() {
    val.isNotEmpty ? _tip=val : _tip='0';
  });
},

Longer answer

enter image description here

Instead of defining your own numberInputFormatters, you should use FilteringTextInputFormatter.digitsOnly.

Also, your _tip is not a String, you could store its value as an int instead.

The, your onChanged callback becomes:

onChanged: (val) => setState(() => _tip = int.tryParse(val) ?? 0),

Full source code:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: MyWidget(price: 9.99),
    ),
  );
}

class MyWidget extends StatefulWidget {
  final double price;

  const MyWidget({Key key, this.price}) : super(key: key);

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

class _MyWidgetState extends State<MyWidget> {
  int _tip = 2;

  String get _total => (widget.price + _tip).toStringAsFixed(2);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        padding: EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Do you want to tip the waiter?'),
            const SizedBox(height: 16.0),
            TextFormField(
              initialValue: _tip.toString(),
              inputFormatters: [FilteringTextInputFormatter.digitsOnly],
              keyboardType: TextInputType.number,
              decoration: InputDecoration(
                  prefix: Text('\$'),
                  labelText: 'Enter Custom Tip Amount ',
                  hintStyle: TextStyle(fontWeight: FontWeight.w600)),
              onChanged: (val) => setState(() => _tip = int.tryParse(val) ?? 0),
            ),
            const SizedBox(height: 16.0),
            Text('TOTAL: $_total'),
          ],
        ),
      ),
    );
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Consider using String Validator it is easy and simple to use

https://pub.dev/packages/string_validator

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.