多行编辑表Flutter

ykejflvf  于 2023-04-13  发布在  Flutter
关注(0)|答案(1)|浏览(182)

我在Flutter中对一个表进行多行编辑,我找到了我需要的东西,但它是在JS中,我想知道在Flutter中做同样的事情是否是一种“简单”的方法

我在js中的例子:https://editor.datatables.net/examples/simple/multiRow
如果有人知道我如何开始这样的事情,谢谢!

ztyzrc3y

ztyzrc3y1#

我做了这个代码,这是工作:),我不知道如果它的丑陋与否,但这可以帮助别人.我给予没有细节,但如果有人有一个问题,我会尝试awnser它:

class EditableTable extends StatefulWidget {
  EditableTable({
    required this.rapport,
    required this.rapportIndex,
  });

  final rapport;
  final rapportIndex;

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

class _EditableTableState extends State<EditableTable> {
  List<DataRow> rows = [];
  final ScrollController _scrollController = ScrollController();
  List<int> selectedLignes = [];
  bool tableauModifie = false;
  late List<Map<String, dynamic>> _tableau;

  void saveTable(List<Map<String, dynamic>> newTable, int rapportIndex) async {
    try {
      final String rapportId = globals.gRapportEnCours![rapportIndex]['id'];
      await FirebaseFirestore.instance
          .collection("rapports")
          .doc(rapportId)
          .update({
        'tableau': newTable,
        'date_modification': DateTime.now(),
      });

      globals.gRapportEnCours![rapportIndex]['tableau'] = newTable;
    } catch (e) {
      print("Erreur lors de la sauvegarde du tableau: $e");
    }
  }

  @override
  void initState() {
    super.initState();
    _tableau = List<Map<String, dynamic>>.from(widget.rapport['tableau']);
    rows = _tableau.asMap().entries.map<DataRow>((entry) {
      int index = entry.key;
      Map<String, dynamic> ligne = entry.value;

      return DataRow(cells: [
        DataCell(Text(ligne['N° trou'].toString())),
        DataCell(TextFormField(
          readOnly: widget.rapport['is_valid'],
          initialValue: ligne['Profondeur'],
          onChanged: (value) {
            setState(() {
              _tableau[index]['Profondeur'] = value;
              tableauModifie = true;
            });
            saveTable(_tableau, widget.rapportIndex);
          },
        )),
        DataCell(TextFormField(
          readOnly: widget.rapport['is_valid'],
          initialValue: ligne['Inclinaison'],
          onChanged: (value) {
            setState(() {
              _tableau[index]['Inclinaison'] = value;
              tableauModifie = true;
            });
            saveTable(_tableau, widget.rapportIndex);
          },
        )),
        DataCell(TextFormField(
          readOnly: widget.rapport['is_valid'],
          initialValue: ligne['N° taillant'],
          onChanged: (value) {
            setState(() {
              _tableau[index]['N° taillant'] = value;
              tableauModifie = true;
            });
            saveTable(_tableau, widget.rapportIndex);
          },
        )),
        DataCell(
          TextFormField(
            readOnly: widget.rapport['is_valid'],
            initialValue: ligne['Observation'],
            onChanged: (value) {
              setState(() {
                _tableau[index]['Observation'] = value;
                tableauModifie = true;
              });
              saveTable(_tableau, widget.rapportIndex);
            },
          ),
        ),
      ]);
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        SingleChildScrollView(
          controller: _scrollController,
          child: Column(
            children: [
              SizedBox(
                width: 800,
                height: 540,
                child: SingleChildScrollView(
                  child: Column(children: [
                    DataTable(
                      columns: [
                        DataColumn(
                          label: Text('N° trou'),
                        ),
                        DataColumn(
                          label: Text('Profondeur'),
                        ),
                        DataColumn(
                          label: Text('Inclinaison'),
                        ),
                        DataColumn(
                          label: Text('N° taillant'),
                        ),
                        DataColumn(
                          label: Text('Observation'),
                        ),
                      ],
                      rows: rows.map<DataRow>((row) {
                        final index = rows.indexOf(row);
                        return DataRow(
                          selected: widget.rapport['is_valid']
                              ? false
                              : selectedLignes.contains(index),
                          onSelectChanged: widget.rapport['is_valid']
                              ? null
                              : (value) {
                                  setState(() {
                                    if (value!) {
                                      selectedLignes.add(index);
                                    } else {
                                      selectedLignes.remove(index);
                                    }
                                  });
                                },
                          cells: row.cells,
                        );
                      }).toList(),
                    ),
                    if (!widget.rapport['is_valid'])
                      ElevatedButton(
                        onPressed: () => setState(() {
                          int newNumTrou = widget.rapport['tableau']
                                      [widget.rapport['tableau'].length - 1]
                                  ['N° trou'] +
                              1;
                          widget.rapport['tableau'].add({
                            'N° trou': newNumTrou,
                            'Profondeur': '',
                            'Inclinaison': '',
                            'N° taillant': '',
                            'Observation': '',
                          });
                          rows.add(
                            DataRow(
                              cells: List.generate(
                                5,
                                (index) => DataCell(
                                  index == 0
                                      ? Text('$newNumTrou')
                                      : TextFormField(
                                          readOnly: widget.rapport['is_valid'],
                                          initialValue: '',
                                        ),
                                ),
                              ),
                            ),
                          );
                        }),
                        child: Text('Ajouter une ligne'),
                      ),
                  ]),
                ),
              ),
            ],
          ),
        ),
        if (!widget.rapport['is_valid'])
          Positioned(
            right: 5.0,
            child: FloatingActionButton(
              onPressed: selectedLignes.isEmpty ? null : editSelectedLignes,
              child: Icon(Icons.edit),
            ),
          ),
      ],
    );
  }

  Map<String, dynamic> getCommonValues(List<int> selectedLignes) {
    Map<String, dynamic> commonValues =
        Map.from(_tableau[selectedLignes.first]);

    for (int i = 1; i < selectedLignes.length; i++) {
      Map<String, dynamic> currentLigne = _tableau[selectedLignes[i]];

      for (String key in commonValues.keys.toList()) {
        if (commonValues[key] != currentLigne[key]) {
          commonValues[key] = 'Valeurs multiples';
        }
      }
    }

    return commonValues;
  }

  void editSelectedLignes() {
    // Vérifie si des lignes sont sélectionnées
    if (selectedLignes.isEmpty) {
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: Text('Aucune ligne sélectionnée'),
          content: Text('Veuillez sélectionner au moins une ligne à éditer.'),
          actions: [
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              child: Text('OK'),
            ),
          ],
        ),
      );
    } else {
      Map<String, dynamic> commonValues = getCommonValues(selectedLignes) ??
          {
            'Profondeur': '',
            'Inclinaison': '',
            'N° taillant': '',
            'Observation': '',
          };

      // Ouvre la pop-up d'édition
      showDialog(
        context: context,
        builder: (context) => EditLignesDialog(
          selectedLignes: selectedLignes,
          tableau: _tableau,
          saveTable: saveTable,
          selectedLigneValues: commonValues,
          rapportIndex: widget.rapportIndex,
        ),
      ).then((value) {
        if (value != null && value) {
          // Vérifiez si 'value' est 'true'
          setState(() {
            updateRows();
          });
        }
      });
    }
  }

  void updateRows() {
    rows = List<DataRow>.generate(
      _tableau.length,
      (index) {
        Map<String, dynamic> ligne = _tableau[index];
        return DataRow(
          cells: [
            DataCell(
              Text('${ligne['N° trou']}'),
            ),
            DataCell(TextField(
                enabled: !widget.rapport['is_valid'],
                controller:
                    TextEditingController(text: '${ligne['Profondeur']}'),
                onChanged: (value) => ligne['Profondeur'] = value)),
            DataCell(TextField(
                enabled: !widget.rapport['is_valid'],
                controller:
                    TextEditingController(text: '${ligne['Inclinaison']}'),
                onChanged: (value) => ligne['Inclinaison'] = value)),
            DataCell(TextField(
                enabled: !widget.rapport['is_valid'],
                controller:
                    TextEditingController(text: '${ligne['N° taillant']}'),
                onChanged: (value) => ligne['N° taillant'] = value)),
            DataCell(TextField(
                enabled: !widget.rapport['is_valid'],
                controller:
                    TextEditingController(text: '${ligne['Observation']}'),
                onChanged: (value) => ligne['Observation'] = value)),
          ],
          onSelectChanged: (bool? value) {
            setState(() {
              selectedLignes.contains(index)
                  ? selectedLignes.remove(index)
                  : selectedLignes.add(index);
            });
          },
        );
      },
    );
  }
}

class EditLignesDialog extends StatefulWidget {
  final List<int> selectedLignes;
  final List<Map<String, dynamic>> tableau;
  final Function(List<Map<String, dynamic>>, int) saveTable;
  final Map<String, dynamic> selectedLigneValues;
  final int rapportIndex;

  EditLignesDialog({
    required this.selectedLignes,
    required this.tableau,
    required this.saveTable,
    required this.selectedLigneValues,
    required this.rapportIndex,
  });

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

class _EditLignesDialogState extends State<EditLignesDialog> {
  final _formKey = GlobalKey<FormState>();

  late TextEditingController profondeurController;
  late TextEditingController inclinaisonController;
  late TextEditingController numTaillantController;
  late TextEditingController observationController;

  bool profondeurMultipleValues = false;
  bool inclinaisonMultipleValues = false;
  bool numTaillantMultipleValues = false;
  bool observationMultipleValues = false;

  @override
  void initState() {
    super.initState();
    profondeurController = TextEditingController(
        text: widget.selectedLigneValues['Profondeur'] == 'Valeurs multiples'
            ? ''
            : widget.selectedLigneValues['Profondeur']);
    inclinaisonController = TextEditingController(
        text: widget.selectedLigneValues['Inclinaison'] == 'Valeurs multiples'
            ? ''
            : widget.selectedLigneValues['Inclinaison']);
    numTaillantController = TextEditingController(
        text: widget.selectedLigneValues['N° taillant'] == 'Valeurs multiples'
            ? ''
            : widget.selectedLigneValues['N° taillant']);
    observationController = TextEditingController(
        text: widget.selectedLigneValues['Observation'] == 'Valeurs multiples'
            ? ''
            : widget.selectedLigneValues['Observation']);

    profondeurMultipleValues = hasMultipleValues("Profondeur");
    inclinaisonMultipleValues = hasMultipleValues("Inclinaison");
    numTaillantMultipleValues = hasMultipleValues("N° taillant");
    observationMultipleValues = hasMultipleValues("Observation");
  }

  bool hasMultipleValues(String key) {
    String? firstValue;
    for (int index in widget.selectedLignes) {
      Map<String, dynamic> ligne = widget.tableau[index];
      if (firstValue == null) {
        firstValue = ligne[key];
      } else if (ligne[key] != firstValue) {
        return true;
      }
    }
    return false;
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Editer Ligne'),
      content: SingleChildScrollView(
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              TextFormField(
                controller: profondeurController,
                decoration: InputDecoration(
                  labelText: 'Profondeur',
                  hintText: widget.selectedLigneValues['Profondeur'] ==
                          'Valeurs multiples'
                      ? 'Valeurs multiples'
                      : null,
                ),
                validator: (value) {
                  if (!profondeurMultipleValues && (value == null)) {
                    return 'Merci de rentrer une profondeur';
                  }
                  return null;
                },
              ),
              TextFormField(
                controller: inclinaisonController,
                decoration: InputDecoration(
                  labelText: 'Inclinaison',
                  hintText: widget.selectedLigneValues['Inclinaison'] ==
                          'Valeurs multiples'
                      ? 'Valeurs multiples'
                      : null,
                ),
                validator: (value) {
                  if (!inclinaisonMultipleValues && (value == null)) {
                    return 'Merci d\'entrer une inclinaison';
                  }
                  return null;
                },
              ),
              TextFormField(
                controller: numTaillantController,
                decoration: InputDecoration(
                  labelText: 'N° taillant',
                  hintText: widget.selectedLigneValues['N° taillant'] ==
                          'Valeurs multiples'
                      ? 'Valeurs multiples'
                      : null,
                ),
                validator: (value) {
                  if (!numTaillantMultipleValues && (value == null)) {
                    return 'Merci d\'entrer un numéro de taillant';
                  }
                  return null;
                },
              ),
              TextFormField(
                controller: observationController,
                decoration: InputDecoration(
                  labelText: 'Observation',
                  hintText: widget.selectedLigneValues['Observation'] ==
                          'Valeurs multiples'
                      ? 'Valeurs multiples'
                      : null,
                ),
                validator: (value) {
                  if (!observationMultipleValues && (value == null)) {
                    return 'Merci de rentrer une observation';
                  }
                  return null;
                },
              ),
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Annuler'),
        ),
        ElevatedButton(
          onPressed: () {
            if (_formKey.currentState!.validate()) {
              bool updated = editLignes();
              Navigator.pop(context,
                  updated); // Renvoie 'true' si les modifications ont été effectuées
            }
          },
          child: Text('Sauvegarder'),
        ),
      ],
    );
  }

  bool editLignes() {
    for (int index in widget.selectedLignes) {
      Map<String, dynamic> ligne = widget.tableau[index];
      ligne['Profondeur'] =
          profondeurMultipleValues && profondeurController.text.isEmpty
              ? ligne['Profondeur']
              : profondeurController.text;
      ligne['Inclinaison'] =
          inclinaisonMultipleValues && inclinaisonController.text.isEmpty
              ? ligne['Inclinaison']
              : inclinaisonController.text;
      ligne['N° taillant'] =
          numTaillantMultipleValues && numTaillantController.text.isEmpty
              ? ligne['N° taillant']
              : numTaillantController.text;
      ligne['Observation'] =
          observationMultipleValues && observationController.text.isEmpty
              ? ligne['Observation']
              : observationController.text;
    }
    widget.saveTable(widget.tableau, widget.rapportIndex);
    return true; // Retourne 'true' pour indiquer que les modifications ont été effectuées
  }
}

相关问题