Search code examples
flutterdartflutter-web

How to print listview in Flutter using data from List?


I have a stepper form which i am using to take input from the user. There are 3 steps, on each step the user provide input and the input is saved to a list on Save Button click. Now, the problem is, i am able to print the list on my console. but i don't know how to print it on the screen above the button or if any field is empty, i want to show the error message above the button. Can anyone please help me? I have the following code.

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Stepper Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Stepper Tutorial'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _currentStep = 0;
  TextEditingController nameController = TextEditingController();
  TextEditingController emailController = TextEditingController();
  TextEditingController addressController = TextEditingController();
  List<String> demoList = [];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: Column(
        children: <Widget>[
          Stepper(
            steps: _mySteps(),
            currentStep: this._currentStep,
            onStepTapped: (step) {
              setState(
                () {
                  this._currentStep = step;
                },
              );
            },
            onStepContinue: () {
              setState(
                () {
                  if (this._currentStep < this._mySteps().length - 1) {
                    this._currentStep = this._currentStep + 1;
                  } else {
                    //Logic to check if everything is completed
                    print('Completed, check fields.');
                  }
                },
              );
            },
            onStepCancel: () {
              setState(
                () {
                  if (this._currentStep > 0) {
                    this._currentStep = this._currentStep - 1;
                  } else {
                    this._currentStep = 0;
                  }
                },
              );
            },
          ),
          ElevatedButton(
            onPressed: viewList,
            child: Text("Click to see List"),
          ),
        ],
      ),
    );
  }

  viewList() {
    if (nameController.text.isEmpty ||
        emailController.text.isEmpty ||
        addressController.text.isEmpty) {
      // //// Print Error message display in the screen above the button //
    } else {
      demoList.add(nameController.text);
      demoList.add(emailController.text);
      demoList.add(addressController.text);
    }
    print(demoList);
  }

  List<Step> _mySteps() {
    List<Step> _steps = [
      Step(
        title: Text('Step 1'),
        content: TextField(
          controller: nameController,
        ),
        isActive: _currentStep >= 0,
      ),
      Step(
        title: Text('Step 2'),
        content: TextField(
          controller: emailController,
        ),
        isActive: _currentStep >= 1,
      ),
      Step(
        title: Text('Step 3'),
        content: TextField(
          controller: addressController,
        ),
        isActive: _currentStep >= 2,
      )
    ];
    return _steps;
  }
}

Solution

  • While I'm not sure if it can be done with the Step, I usually use Form with TextFormField where you can add a validator for the form to check if the value is empty or not and alert the user with a message. Example:

    TextFormField(
      validator: (value) {
        if (value.isEmpty) {
          return 'Please enter some text'; // the message which you alert the user that he needs to enter the value
        }
        return null;
      },
      keyboardType: TextInputType.text,
    ),
    

    enter image description here

    As part of the condition for the listView you can use some if/switch case or iterator. Place a widget(ListView.builder) above the button and, like a said use and if/switch case or iterator where you state:

    if (formIsEmpty){
    //logic when the form is empty
    } ? ListView.builder() : Cointainer()
    
    

    So, let me try to explain. At first, it will show an empty container or any other widget you like above the button, but when the logic for the ListView.builder is met, then you trigger the lisview and it displays the list as you wish.

    This is commonly used with login form, when you miss the password, a link appears that link to reset password etc.

    bool _forgotPassword = false;
    _forgotPassword
      ? TextButton(
        onPressed: () async {
        //await your logic for forgotton password
      },
        child: Text('Forgot Password'))
      : Container(),
    
      // ABOVE IS THE LOGIC FOR SHOWING THE WIDGET (IN YOUR CASE LISTVIEW.BUILDER) AFTER AN ACTION IS PERFORMED
      TextButton(
        onPressed: () async {
          //await your login logic, if it returns false\error\not authenticated, then you can change the state of _forgotPassword, and then shows 'forgot password TextButton'
          setState(() {
        _forgotPassword = true;
      });
                },
    child: Text('Login')
    )