3

Can anyone please tell me how do I select multiple options in checkboxlisttile. Here I am able to click only one option. I want to set the status column in note table in database as completed when i check the particular item. (Actually I want to select the item as completed and display it under another tab called completed. checkboxlisttile is created dynamically i.e from database. When a new note is added it is displayed in this listview.)

note_info.dart //this is the screen where notes are displayed i.e listview

import 'dart:io';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/db_helper.dart';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';

import 'new_note.dart';


class Note_Info extends StatefulWidget{
  final String appBarTitle;
  final CustomerModel customer;

  //Note_Info();
  Note_Info(this. customer, this.appBarTitle);

  @override
  State<StatefulWidget> createState() {
    //return Note_InfoState();
   return Note_InfoState(this. customer,this.appBarTitle);
  }

}

class Note_InfoState extends State<Note_Info> {
  DBService dbService = DBService();
  List<NoteModel> noteList;
  int count = 0;

  static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
  NoteModel note=NoteModel();
  String appBarTitle;
  CustomerModel customer=new CustomerModel();
  Note_InfoState(this.customer, this.appBarTitle);
 

  bool rememberMe = false;
  DateTime _date = DateTime.now();
  TextEditingController custfNameController = TextEditingController();

  @override
  void initState() {
    super.initState();
  }


  @override
  Widget build(BuildContext context) {
  updateListView();
    if (noteList == null) {
      noteList = List<NoteModel>();
      updateListView();
    }

    TextStyle titleStyle = Theme.of(context).textTheme.subhead;
    var height = MediaQuery.of(context).size.height;
    var name=customer.first_name+" "+customer.last_name;
    custfNameController.text = name;

    return DefaultTabController(
        length: 4,
        child: Scaffold(
            appBar: AppBar(
              actions: [
                IconButton(
                  icon: Icon(
                    Icons.add,

                  ),
                  onPressed: () {
                    Navigator.of(context).push(MaterialPageRoute(
                        builder: (BuildContext context) => NewNote(customer,note)));
                  },
                )
              ],
            ),
            body: Container(
              child: Column(
                  children: <Widget>[
                    TextField(controller: custfNameController,
                        style: TextStyle(
                            fontSize: 20.0, fontWeight: FontWeight.bold),

                        textAlign: TextAlign.center),
                    Padding(
                      padding: const EdgeInsets.all(15.0),
                      child: Row(children: [
                        ImageProfile(customer.cust_photo),
                        Padding(
                          padding: const EdgeInsets.only(left: 30.0),
                          child: IconButton(
                            icon: Icon(
                              Icons.call,
                              color: Colors.green,
                              size: 45,
                            ),
                            onPressed: () {

                            },
                          ),
                        ),

                      ],),
                    ),

                    SizedBox(
                      height: 50,
                      child: AppBar(
                        bottom: TabBar(
                          tabs: [
                            Tab(
                              text: "All",
                              
                            ),
                            Tab(
                              text: "Pending",
                             
                            ),
                            Tab(
                              text: "Cancelled",
                              
                            ),
                            Tab(
                              text: "Completed",
                              
                            ),
                          ],
                        ),
                      ),
                    ),

                    // create widgets for each tab bar here
                    Expanded(
                      child: TabBarView(
                        children: [
                          // first tab bar view widget
                          Container(
                              child: getNotecheckList()
                          ),

                          // second tab bar view widget
                          Container(

                          ),


                          Container(
                            child: Center(
                              child: Text(
                                'Cancelled',
                              ),
                            ),
                          ),
                          Container(

                            child: Center(
                              child: Text(
                                'Completed',
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Container(
                        height: 55.0,
                        width: 200,
                        child: RaisedButton(
                          elevation: 2,

                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(20)),
                          color: Theme
                              .of(context)
                              .primaryColorDark,
                          textColor: Colors.white,
                          child: Text('Save', textScaleFactor: 1.5,),
                          onPressed: () {
                            setState(() {
                              //_reset();
                            });
                          },
                        ),
                      ),
                    ),
                  ]
              ),
            )
        ));
  }

  Widget ImageProfile(String fileName) {
    return Center(
      child: CircleAvatar(
          radius: 80.0,
          backgroundImage:  fileName == null
              ?AssetImage('images/person_icon.jpg')
              :FileImage(File(customer.cust_photo))),

    );

  }
  Future<void> updateListView() {
    final Future<Database> dbFuture = DB.init();
    dbFuture.then((database) {
      int cid=customer.cust_id;

      Future<List<NoteModel>> noteListFuture = dbService.getCustomerNotes(cid);
      noteListFuture.then((noteList) {

        setState(() {
          this.noteList = noteList;
          this.count = noteList.length;
        });
      });
    });
  }
  int _isChecked=-1;

  ListView getNotecheckList() {

    return ListView.builder(
        itemCount: count,
        itemBuilder: (BuildContext context, int position) {



        return Card(
          color: Colors.white,
          elevation: 2.0,
          child: CheckboxListTile(
            title: Text(this.noteList[position].note),
            subtitle: Text(this.noteList[position].actn_on),
            //secondary: const Icon(Icons.web),
            
            value: position== _isChecked,
            onChanged: (bool value) {
              setState(() {
               _isChecked = value?position:-1;

              });
            },

            controlAffinity: ListTileControlAffinity.leading,
                ),
            );
          },
         );
        }
  }

new_note.dart //this is where new note is added.

import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
import 'package:intl/intl.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/form_helper.dart';

class NewNote extends StatefulWidget{
  final NoteModel note;
  final CustomerModel customer;

  NewNote(this.customer,this. note);
//Dropdown
/*
 final String label;
   final Function(Color) onChanged;
  final double height;
  final double width;

  NewNote.fordropdwn({
    Key key,
    this.onChanged,
    this.height = 25,
    this.width = 150,
    this.label,
  }) : super(key: key);*/
  @override
  State<StatefulWidget> createState() {
    //return New_NoteState(this.customer);
    return New_NoteState(this.customer,this.note);
  }

}
class New_NoteState extends State<NewNote> with SingleTickerProviderStateMixin{
  New_NoteState(this.customer,this.note);
  NoteModel note=new NoteModel();
  CustomerModel customer=new CustomerModel();
  TextEditingController NoteController=TextEditingController();
  TextEditingController custfNameController = TextEditingController();
  DateTime _reminderDate = DateTime.now();
  DBService dbService=new DBService();

  SpeedDial _speedDial(){
    return SpeedDial(
      // child: Icon(Icons.add),
      animatedIcon: AnimatedIcons.add_event,

      animatedIconTheme: IconThemeData(size: 24.0),
      backgroundColor: Colors.yellow,
      curve: Curves.easeInCirc,
      children: [
        SpeedDialChild(
          child: Icon(Icons.location_on,color: Colors.yellow,),
          //backgroundColor: Theme.of(context).primaryColor,
          label: 'Add Location',
          //labelBackgroundColor:Theme.of(context).primaryColor,

        ),
        SpeedDialChild(
          child: Icon(Icons.keyboard_voice),
          //backgroundColor: Colors.yellow,
          label: 'Add voice',
          //labelBackgroundColor: Colors.yellow

        ),
        SpeedDialChild(
          child: Icon(Icons.attachment_outlined,color :Colors.redAccent),
          //backgroundColor:Theme.of(context).primaryColorLight,
          label: 'Add File',
          // labelBackgroundColor: Theme.of(context).primaryColorLight

        ),
        SpeedDialChild(
          child: Icon(Icons.image,color: Colors.lightBlue,),
          //backgroundColor: Colors.yellow,
          label: 'Add Image',
          // labelBackgroundColor: Colors.yellow,

        ),
      ],
    );
  }

  //for DropDownMenu
  Color value=Colors.red;
  final List<Color> colors = [
    Colors.red,
    Colors.blue,
    Colors.green,
    Colors.yellow,
    Colors.pink,
    Colors.purple,
    Colors.brown,
  ];

  //for Switch
  bool isSwitched = false;
  var textValue = 'Switch is OFF';

  void toggleSwitch(bool value) {

    if(isSwitched == false)
    {
      setState(() {
        isSwitched = true;
        note.rmnd_ind=1;
        //this.note.remindOn = _reminderDate.toString();

      });
    }
    else
    {
      setState(() {
        isSwitched = false;
        note.rmnd_ind=0;
      });
    }
  }
  @override
  Widget build(BuildContext context) {
    var height = MediaQuery.of(context).size.height;
    var width = MediaQuery.of(context).size.width;
    var name=customer.first_name+customer.last_name;
    custfNameController.text = name;

    return WillPopScope(

        onWillPop: () {
          // Write some code to control things, when user press Back navigation button in device navigationBar
          moveToLastScreen();
        },
        child: Scaffold(
          appBar:AppBar(),
          body:ListView(
            children: <Widget>[
              SizedBox(
                height: 2.0,
              ),
              TextField(controller: custfNameController,
                  style: TextStyle(
                      fontSize: 20.0, fontWeight: FontWeight.bold),

                  textAlign: TextAlign.center),
              Align(
                alignment: Alignment.centerLeft,
                child: Text("Add New",textAlign: TextAlign.left,
                  style: TextStyle(fontSize: 22,fontWeight: FontWeight.bold),),
              ),

              SizedBox(
                height: 2.0,
              ),
              Divider(),
              SizedBox(
                height: 2.0,
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  controller: NoteController,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(
                        borderSide: const BorderSide(width: 2.0),)),
                  keyboardType: TextInputType.multiline,
                  minLines: 5,//Normal textInputField will be displayed
                  maxLines: 5, // when user presses enter it will adapt to it
                  onChanged: (value) {
                    this.note.note = value;
                  },

                ),
              ),
              TableCalendar(
                selectedDayPredicate: (day) {
                  return isSameDay(_reminderDate, day);
                },
                onDaySelected: (selectedDay, focusedDay) {
                  setState(() {
                    String _reminderDate = DateFormat('dd-MM-yyyy').format(selectedDay);
                    note.actn_on=_reminderDate.toString();

                  });
                },// Set initial date

                focusedDay: DateTime.now(),
                firstDay: DateTime.utc(2010, 10, 16),
                lastDay: DateTime.utc(2030, 3, 14),),

              SizedBox(
                height: height*0.03,
              ),
              Padding(
                padding: const EdgeInsets.all(10.0),
                child: Row(//mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Text("Remind me",style: TextStyle(fontSize: 20),),

                    Padding(
                      padding: const EdgeInsets.only(left:80.0),
                      child: Container(
                        child: Switch(
                          onChanged: toggleSwitch,
                          value: isSwitched,

                          //activeColor: Colors.blue,
                          //activeTrackColor: Colors.yellow,
                          //inactiveThumbColor: Colors.redAccent,
                          //inactiveTrackColor: Colors.orange,
                        ),
                      ),
                    ),

                  ],),
              ),
              Padding(
                padding: const EdgeInsets.all(10.0),
                child: Row(mainAxisAlignment: MainAxisAlignment.start,
                    children:<Widget>[
                      Text("Priority",style: TextStyle(fontSize: 20.0),),
                      Padding(
                        padding: const EdgeInsets.only(left:20.0),
                        child: Container(
                          child: SmoothStarRating(
                            size: height=50.0,
                            allowHalfRating: false,
                            onRated: (value) {
                              this.note.prty=value;
                              print("rating value -> $value");

                            },
                          ),
                        ),
                      )]),
              ),

              Padding(
                padding: const EdgeInsets.all(10.0),
                child: Row(mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[

                    Text("Color",style: TextStyle(fontSize: 20),),
                    Padding(
                      padding: const EdgeInsets.only(left:80.0),
                      child: Container(
                        child: DropdownButton<Color>(
                          value: value,
                          //hint: Text(widget.label ?? ''),
                          onChanged: (color) {
                            setState(() => value = color);
                            //widget.onChanged(color);
                          },
                          items: colors.map((e) => DropdownMenuItem(
                            value: e,
                            child: Container(
                              // width: 60.0,
                              //height: 10.0,
                              width: 60.0,
                              // height: widget.height,
                              color: e,
                            ),
                          ),
                          )
                              .toList(),
                        ),
                      ),
                    ),

                  ],),
              ),

              SizedBox(
                height: height*0.08,
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(
                  height: 55.0,
                  width: 200,
                  child: RaisedButton(
                    elevation: 2,

                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20)),
                    color: Theme.of(context).primaryColorDark,
                    textColor: Colors.white,
                    child: Text('Save',textScaleFactor: 1.5,),
                    onPressed: (){
                      setState(() {
                        _save();
                      });
                    },
                  ),
                ),
              ),



            ],



          ),
          floatingActionButton:_speedDial(),
          
        ));

  }
  void moveToLastScreen() {
    Navigator.pop(context, true);
  }

  void _save() async {
    moveToLastScreen();
    note.cust_id=customer.cust_id;
    print(customer.cust_id);
    print(note.cust_id);
  
    int result;
    if (note.note_id != null) {  // Case 1: Update operation
      result = await dbService.updateNote(note);
    } else { // Case 2: Insert Operation
      result = await dbService.insertNote(note);
    }

    if (result != 0) {  // Success
      FormHelper.showAlertDialog(context,'Status', 'Note Saved Successfully');
    } else {  // Failure
      FormHelper.showAlertDialog(context,'Status', 'Problem Saving Note');
    }

  }
}

db_service.dart

import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/languages_model.dart';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/models/user_model.dart';
import 'package:vers2cts/utils/db_helper.dart';

class DBService {
  Future<int> insertNote(NoteModel note) async {
    await DB.init();
    var result = await DB.insert(NoteModel.table, note);
    return result;
  }
  Future<List<NoteModel>> getCustomerNotes(int customer) async {
    await DB.init();
    var res = await DB.rawQuery("note WHERE cust_id = '$customer'");
    int count = res.length;
    List<NoteModel> notelist = List<NoteModel>();
    // For loop to create a 'Note List' from a 'Map List'
    for (int i = 0; i < count; i++) {
      notelist.add(NoteModel.fromMap(res[i]));
    }
    return notelist;
  }
}

note_model.dart

import 'model.dart';

class NoteModel extends Model {
  static String table = 'note';
  bool isSelected=false;
  int note_id;
  int cust_id;
  String note;
  String actn_on;
  int rmnd_ind;
  double prty;
  String colr;
  String sts;

  int id;
  String cre_date;
  String cre_by;
  String mod_date;
  String mod_by;
  int txn_id;
  int delete_ind;

  NoteModel({
    this.note_id,
    this.cust_id,
    this.note,
    this.actn_on,
    this.rmnd_ind,
    this.prty,
    this.colr,
    this.sts,

    this.id,
    this.cre_date,
    this.cre_by,
    this.mod_date,
    this.mod_by,
    this.txn_id,
    this.delete_ind
  });

  static NoteModel fromMap(Map<String, dynamic> map) {
    return NoteModel(
      note_id: map["note_id"],
      cust_id: map['cust_id'],
      note: map['note'].toString(),
      actn_on: map['actn_on'].toString(),
      rmnd_ind: map['rmnd_ind'],
      prty: map['prty'],
      colr: map['colr'].toString(),
      sts: map['sts'].toString(),


      id: map['id'],
      cre_date: map['cre_date'].toString(),
      cre_by: map['cre_by'].toString(),
      mod_date: map['mod_date'].toString(),
      mod_by: map['mod_by'].toString(),
      txn_id: map['txn_id'],
      delete_ind: map['delete_ind'],
    );
  }

  Map<String, dynamic> toMap() {
    Map<String, dynamic> map = {
      'note_id': note_id,
      'cust_id': cust_id,
      'note':note,
      'actn_on': actn_on,
      'rmnd_ind': rmnd_ind,
      'prty': prty,
      'colr': colr,
      'sts':sts,


      'id': id,
      'cre_date': cre_date,
      'cre_by': cre_by,
      'mod_date':mod_date,
      'mod_by':mod_by,
      'txn_id':txn_id,
      'delete_ind': delete_ind

    };

    if (note_id != null) {
      map['note_id'] = note_id;
    }
    return map;
  }
}

db_helper.dart

import 'dart:async';
import 'package:vers2cts/models/model.dart';
import 'package:path/path.dart' as p;
import 'package:sqflite/sqflite.dart';

abstract class DB {
  static Database _db;

  static int get _version => 1;

  static Future<Database> init() async {
    if (_db != null) {
      return _db;
    }

    try {
      var databasesPath = await getDatabasesPath();
      String _path = p.join(databasesPath, 'CTS.db');
      _db = await openDatabase(_path, version: _version, onCreate: onCreate);
      print('db location:'+_path);

    } catch (ex) {
      print(ex);
    }
  }

  static void onCreate(Database db, int version) async {

    await db.execute(
        'CREATE TABLE note (note_id INTEGER PRIMARY KEY,cust_id INTEGER, '
            'note TEXT, '
            'actn_on TEXT, rmnd_ind INTEGER, prty REAL, colr TEXT,'
            'sts TEXT,'
            'id INTEGER, cre_date TEXT,cre_by TEXT, mod_date TEXT,mod_by TEXT, txn_id INTEGER, delete_ind INTEGER)');

  }

  static Future<List<Map<String, dynamic>>> query(String table) async =>
      _db.query(table);

  static Future<int> insert(String table, Model model) async =>
      await _db.insert(table, model.toMap());
  static Future<Batch> batch() async => _db.batch();
  static Future<List<Map<String, dynamic>>> rawQuery(String table) async =>
      _db.query(table);
}

2 Answers 2

13

You need to store what all values are selected from user and then play with it. For example -

var selectedIndexes = [];

  ListView getNotecheckList() {
    return ListView.builder(
        itemCount: count,
        itemBuilder: (_, int index) {
        return Card(
          color: Colors.white,
          elevation: 2.0,
          child: CheckboxListTile(
            title: Text(this.noteList[position].note),
            subtitle: Text(this.noteList[position].actn_on),            
            value: selectedIndexes.contains(index),
            onChanged: (_) {
             if (selectedIndexes.contains(index)) {
              selectedIndexes.remove(index);   // unselect
             } else {
              selectedIndexes.add(index);  // select
              }
            },
            controlAffinity: ListTileControlAffinity.leading,
          ),
        );
      },
    );
  }
Sign up to request clarification or add additional context in comments.

Comments

5

store only index or whole array and play around

Output :-

enter image description here

Code :-

import 'package:flutter/material.dart';

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

  @override
  State<CheckBoxExample> createState() => _CheckBoxExampleState();
}

class _CheckBoxExampleState extends State<CheckBoxExample> {
  List multipleSelected = [];
  List checkListItems = [
    {
      "id": 0,
      "value": false,
      "title": "Sunday",
    },
    {
      "id": 1,
      "value": false,
      "title": "Monday",
    },
    {
      "id": 2,
      "value": false,
      "title": "Tuesday",
    },
    {
      "id": 3,
      "value": false,
      "title": "Wednesday",
    },
    {
      "id": 4,
      "value": false,
      "title": "Thursday",
    },
    {
      "id": 5,
      "value": false,
      "title": "Friday",
    },
    {
      "id": 6,
      "value": false,
      "title": "Saturday",
    },
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 64.0),
        child: Column(
          children: [
            Column(
              children: List.generate(
                checkListItems.length,
                (index) => CheckboxListTile(
                  controlAffinity: ListTileControlAffinity.leading,
                  contentPadding: EdgeInsets.zero,
                  dense: true,
                  title: Text(
                    checkListItems[index]["title"],
                    style: const TextStyle(
                      fontSize: 16.0,
                      color: Colors.black,
                    ),
                  ),
                  value: checkListItems[index]["value"],
                  onChanged: (value) {
                    setState(() {
                      checkListItems[index]["value"] = value;
                      if (multipleSelected.contains(checkListItems[index])) {
                        multipleSelected.remove(checkListItems[index]);
                      } else {
                        multipleSelected.add(checkListItems[index]);
                      }
                    });
                  },
                ),
              ),
            ),
            const SizedBox(height: 64.0),
            Text(
              multipleSelected.isEmpty ? "" : multipleSelected.toString(),
              style: const TextStyle(
                fontSize: 22.0,
                color: Colors.black,
                fontWeight: FontWeight.bold,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

1 Comment

What if instead of checkkboxes there are textFormFields then How can we get those text field values with id and title ??

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.