flutterdart

Getting values of previous rows in the latest inserted row in flutter, instead of empty rows


In my code shown here, I am trying to insert the row at the top. When I try to add the row at the bottom, I don't face any difficulty but when I try to insert the empty row at the top, it does create a row but it also has the data from the previous row. Here, I have tried to pass a local key and a uniqueKey().

Now, when I pass the inputFieldKey, it creates a new row but it has the data from the previous row, although I am able to edit and enter data into the textfield normally.

When I pass uniqueKey(), I am getting an empty row at the top as required but here the problem is, whenever I try to edit or enter any text into the textfield, it rebuilds the widget(which is correct) and with that is creates a new uniqueKey() every time, so because of that the cursor gets disappear from textfield after every letter.

Like if I enter 's', the cursor will disappear and I'll have to go to the textfield and again point in textfield for next entering next letter.

What I want is, to create an empty row with normal behaviour (where I can add/edit text normally). So, as soon as I click the button, it will run the function addEmptyRow, this will check for position, for top it will insert the row at the top. I have checked thoroughly, it is adding empty data properly.

This line is responsible for the behavior (I think) key:

widget.mode == FormType.add ? inputFieldKey : UniqueKey(),

Full code:

void addEmptyRow() {
    int indexOfRow = rows.length; // Get the index of the new row
    Map<String, dynamic> emptyData = {};
    List<dynamic> columns = tableFieldDetails
        .otherFieldProperties['table_configuration']['columns'];
    String columnName = '';
    for (int columnDetails = 0;
        columnDetails < columns.length;
        columnDetails++) {
      var column = columns[columnDetails];
      columnName = column['name'];

      // Check if columnName exists in emptyData
      if (!emptyData.containsKey(columnName)) {
        emptyData[columnName] = ''; // Add columnName with empty value
      }
    }

     if (newRowPosition == 'top') {
      //need to come back to this logic, may be some other way
      tableRecords.insert(0, emptyData);
      rows.insert(0, buildSingleRow(0));
      if (indexOfRow == 0) {
        buildRows();
      }
    }
  }

  DataRow buildSingleRow(int tableRow) {
    Map<String, dynamic> record = tableRecords[tableRow];
    List<DataCell> cells = tableColumn.map<DataCell>((column) {
      String columnName = column['name'];
      String dataType = column['type'];
      dynamic cellValue = record[columnName];
      Map<String, dynamic> columnAccess = column['access'];
      
        return DataCell(
          SizedBox(
            child: buildDataCell(
                tableRow, dataTypecolumn, true,
                cellValue: cellValue),
          ),
        );
      
    }).toList();

    return DataRow(
      cells: cells,
    );
  }

Widget buildDataCell(int indexOfRow, String dataType, key, columnAccess,
      Map<String, dynamic> column, bool inputField,
      {dynamic cellValue = ''}) {
    Key inputFieldKey = Key('${column['name']}-$indexOfRow');
    //Key inputFieldKeyForEdit = Key('${column['name']}-$indexOfRow' 'edit');
    //if inputField is false, display row value as text
    if (!inputField) {
      return Center(child: Text(cellValue.toString()));
    } else {
       if (dataType == 'string') {
        return Padding(
          padding: const EdgeInsets.all(0.0),
          child: TableTextInputFieldComponent(
              column: column,
              indexOfRow: indexOfRow,
              value: cellValue,
              isStrikeThrough: isStrikeThrough,
              key: widget.mode == FormType.add ? inputFieldKey : UniqueKey(),
        );
      } else {
        return const Center(child: Text('Not supported'));
      }
    }
  }

Solution

  • inputFieldKey needs to be unique for every row in this case.

    Initially, inputFieldKey will be let's say 0, then after inserting 1 more row to it, the inputFieldKey for 1st row will be again 0 and for 2nd row it'll be 1. So, even though the rows have distinct keys the problem is, apart from adding to row, the inputFieldKey is also shifting, like, 0 then 0,1, then 0,1,2, and so it is also taking the values along with it.

    to resolve the problem the solution is to have distinct inputFieldKey

    Key inputFieldKey = Key('${column['name']}-${tableRecords.length}');

    instead of using both uniqueKey and inputFieldKey, it can be passed simply as key

    key: inputFieldKey