Saving a list of values from TextFields generated dynamically using PaginatedDataTable to the Cloud Firestore in Flutter

29 views Asked by At

I am developing a Flutter app which requires the user to enter a list of scores. In order to improve performance I decided to use PaginatedDataTable which requires the datasource from another class(ie the class which extends the DataTableSource). Now, in the class which extends the DataTableSource there is a DataCell which has a TextField for entering the scores. How do I fetch all the data entered in the TextFields and then pass them to the Stateful class and save the data to the Firestore on pressing the button? In the code below I tried but still I couldn't achieve that. Kindly help me

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


class ResultsAddList extends StatefulWidget {
  const ResultsAddList({super.key});

  @override
  State<ResultsAddList> createState() => _ResultsAddListState();
}

class _ResultsAddListState extends State<ResultsAddList> {

void saveData(String name,double score, String subject) async{
    await FirebaseFirestore.instance.collection('results').add({
      'name':name,
      'score':score,
      'subject':subject
    });
}

  @override
  Widget build(BuildContext context) {

  final routeArgs=ModalRoute.of(context)?.settings.arguments as Map<String, String>;

  final selectedClass=routeArgs['class'];
  final subject=routeArgs['subject'];

    return Scaffold(
      backgroundColor: Colors.green[200],
      appBar: AppBar(backgroundColor: Colors.green[200]),
    body: StreamBuilder<QuerySnapshot>(
     stream: FirebaseFirestore.instance.collection('students').where("class", isEqualTo: selectedClass).snapshots(),
     builder: (context,snapshot){
       if(snapshot.connectionState==ConnectionState.waiting){
         return const CircularProgressIndicator(color: Colors.green,);
       }
       final List studentsList=[];
        List<int> scoresList=[];
        var i=0;
        i++;
       snapshot.data!.docs.map((DocumentSnapshot document){
         Map a=document.data() as Map<String,dynamic>;
         studentsList.add(a);
         a['i']=i;
       }).toList();

    
       DataTableSource students=MyStudents(studentsList,scoresList);
       return SingleChildScrollView(
         child: Stack(
           children:[ 
            PaginatedDataTable(
               source: students,
               columns: const [
                 DataColumn(label: Text('No')),
                 DataColumn(label: Text('Name',textAlign:TextAlign.center)),
                 DataColumn(label: Text('Score'))
               ],
               header: Text('${subject!.toUpperCase()}${'  '}${'RESULTS'}',
               textAlign: TextAlign.center,
               style: const TextStyle(fontWeight: FontWeight.bold),
               ),
           ),
           Positioned(
            top: MediaQuery.of(context).size.width,
            left: MediaQuery.of(context).size.width*0.4,
             child: ElevatedButton(
              style:ElevatedButton.styleFrom(backgroundColor: Colors.green),
              child: const Text('Submit',style:TextStyle(color: Colors.white)),
             onPressed:(){
              for(var score in scoresList){
                  saveData('Vini',double.parse(score.toString()),subject); 
                  
              }
             }
             ),
           )
           ]
         ),
       );
     },
    ),
    );
  }
}


class MyStudents extends DataTableSource{

  MyStudents(this.studentsList,this.scoresList);
  
  List studentsList=[];
  List<int?> scoresList=[];

  @override
  DataRow? getRow(int index) {
    var score=TextEditingController();
    return DataRow.byIndex(
      index:index,
      cells: [
        DataCell(Text((index+1).toString())),
         DataCell(Text('${studentsList[index]['firstname']}${' '}${studentsList[index]['lastname']}')),
         DataCell(
            TextField(
              controller: score,
              onEditingComplete:(){
               for(var i=1;i<=index;i++){
                scoresList.insert(i,int.parse(score.text));
                
               }
               
              },
            keyboardType: TextInputType.number,
            decoration: const InputDecoration(border: OutlineInputBorder()),
                      ),
          ),
      ]);
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => studentsList.length;

  @override
  int get selectedRowCount => 0;

}

This is the output

I tried fetching all the data entered in the TextFields and then pass them to the Stateful class and save the data to the Firestore on pressing the button? In the code below I tried but still I couldn't achieve that. Kindly help me

0

There are 0 answers