Carter
Carter

Reputation: 179

Whats the best possible way to have labelTexts change based on the text being put in a Text Field?

I am working on making some label texts for Text Fields respond to if certain text fields have text in them. Example being if fields B and C are blank, the labelText for field A will have an asterisk before it ("* Label"). Or if field A is blank the labelText for B and C will have an asterisk before it ("* Label"). I have it sort of working currently, but to have the correct asterisk appear after I type in a field I have to swipe the drawer away Im doing this in and reopen it. Kinda like setting the state so it knows that theres new stuff to display. How would I get it to change the correct label right when I type instead of having to do it manually? Thanks!

Field A

                           TextField(
                              controller: Data.NumberEditingController,
                              obscureText: false,
                              decoration: InputDecoration(
                                  fillColor: Colors.white,
                                  border: OutlineInputBorder(
                                    borderRadius: BorderRadius.all(Radius.circular(12.0)),
                                  ),
                                  labelText: requiredNumber(),
                                  labelStyle: TextStyle(
                                    color: Color.fromRGBO(105, 105, 105, 10),
                                  )),
                            ),

Field B

                           TextField(
                              controller: Data.NameEditingController,
                              obscureText: false,
                              decoration: InputDecoration(
                                  fillColor: Colors.white,
                                  border: OutlineInputBorder(
                                    borderRadius:
                                    BorderRadius.all(Radius.circular(12.0)),
                                  ),
                                  labelText: requiredName(),
                                  labelStyle: TextStyle(
                                    color: Color.fromRGBO(105, 105, 105, 10),
                                  )),
                            ),

Field C

TextField(
                              controller: Data.addressEditingController,
                              obscureText: false,
                              decoration: InputDecoration(
                                  fillColor: Colors.white,
                                  border: OutlineInputBorder(
                                    borderRadius:
                                    BorderRadius.all(Radius.circular(12.0)),
                                  ),
                                  labelText: requiredAddress(),
                                  labelStyle: TextStyle(
                                    color: Color.fromRGBO(105, 105, 105, 10),
                                  )),
                            ),

These are the functions I use to check for any text in the controllers so they can return the correct label to use. As stated above they work correctly but only upon dismissing the drawer and opening it again so everything is refreshed and I want it to be automatic

  requiredNumber() {
    if (Data.addressEditingController.text == "") {
      return "* Number";
    }
    else if (Data.nameEditingController.text == "") {
      return "* Number";
    }
    else {
      return "Number";

    }
  }

  requiredName() {
    if (Data.numberEditingController.text == "") {
      return "* Name";
    }
    else {
      return "Name";
    }
  }

  requiredAddress() {
    if (Data.numberEditingController.text == "") {
      return "* Address";
    }
    else {
      return "Address";
    }
  }

Upvotes: 0

Views: 113

Answers (2)

Simon Sot
Simon Sot

Reputation: 3136

  • define String variables for all your labels in your stateful widget:
    String numberLabel = '';
  • Add listeners on all your textControllers during initState like so:
  @override
  void initState() {
    super.initState();

    // Start listening to changes.
    addressEditingController.addListener(setState((){numberLabel=requiredNumber()})); // Im not sure here callback may be wrapped in () {}
  }
  • Then use this variables in your labelText properties:
     labelText: numberLabel,
  • Remove registered listeners before dispose method:
 @override
  void dispose() {
    addressEditingController.removeListener(setState((){numberLabel=requiredNumber()}));
    addressEditingController.dispose();
    super.dispose();
  }

Upvotes: 0

Huthaifa Muayyad
Huthaifa Muayyad

Reputation: 12363

Best solution and cleanest for your case would be to put the logic inside the onChanged property of the TextField. I'll give an example using your first function:

Change this:

 requiredName() {
    if (Data.numberEditingController.text == "") {
      return "* Name";
    }
    else {
      return "Name";
    }
  }

into this:

String requiredNumber = "Number";
String requiredName = "Name";
String Address = "Address";

//and inside your TextField for the Number for example, use onChanged

 onChanged: (value) {
                if (value == '') {
                  setState(() {
                    requiredName = '* Name';
                  });
                } else {
                   setState(() {
                    requiredName = 'Name';
                  });
                }
              }

Upvotes: 1

Related Questions