bosskmk / pluto_grid

PlutoGrid is a dataGrid for flutter that can be controlled by the keyboard on desktop and web. Of course, it works well on Android and IOS.

Home Page:https://pluto.weblaze.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

how to update the footer record when new row added into table

techttiru opened this issue · comments

Hi,

Question: 1
I am able to add the new row into table every time when user do some action but i have created footer record as below where i want to update the total count (number of rows), total amount (there is column in each row called amt and i want to sum up this amt column and show in footer). it seems to be footer is called only once (first time). whenever i add new row, how to update the footer record?

class TableFooter extends StatelessWidget {
  final EventAttendeeRegistrationController eventAttendeeRegistrationController;
  const TableFooter({
    Key? key,
    required this.eventAttendeeRegistrationController,
  }) : super(key: key);

  String totalCount() {
    return eventAttendeeRegistrationController.attendeeDataTableList.length
        .toString();
  }

  String totalAmt() {
    double totAmount = 0;
    for (var element
        in eventAttendeeRegistrationController.attendeeDataTableList) {
      totAmount = totAmount + num.parse(element.amt.toString());
    }
    return totAmount.toString();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: const Color(0xFFE3F2FC),
      height: 45,
      child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
        const VerticalDivider(),
        const Text('Total count:  ',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
        Text(totalCount(),
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
        const SizedBox(width: 50),
        const VerticalDivider(),
        const SizedBox(width: 20),
        const Text('Total Amt:  ',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
        Text(totalAmt(),
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
        const SizedBox(width: 150)
      ]),
    );
  }
}

Question:2
lets say i have only one row where i want to edit some column. i am able to edit it but if i press enter its not saved. i have to give tab to make this save but tab takes me to next cell in edit mode. i basically want to update the cell when hit enter. how to do it? this is happening when i have only one row or last row.

enterKeyAction: PlutoGridEnterKeyAction.editingAndMoveDown

i see this option but it takes me to next row when i hit enter but in my case, what if i have only one row or if i want to edit last row?

Question:3
is there a way to hide the entire column header row alone? i am able to hide the specific column but i want to hide the entire column header as i want to show only the rows and i dont want to show any column headers. is it possible?

Question: 4
how to auto size the row height? i see the row height parameter but i want to auto size the row height based on the content available in the cell? kind of text wrap. as of now i am using text overflow parameter in text widget to hide some of the additional data that goes beyond the cell size. but i want to show entire data in the cell by wrapping the text so that it can take multiple lines within the cell and row height also needs to adjusted accordingly. is there a way to do this?

also, is there a way to auto fit the column size according to the cell content size?

Question:5

is there a way to hide the menu icon for the one specific column?

Question:6

is there a way to give background color to the entire column header row? as of now i am giving column background color for each column.

Question: 7

what does mean rowRef? why are we reducing the length-1 here? this works fine but i dont understand the rowRef usage here?

    stateManager.appendRows([buildPlutoRow(widget.currentAttendee!)]);
      stateManager.moveScrollByRow(
        PlutoMoveDirection.down,
        stateManager.refRows.length - 1,
      );

Question:8

I am raising all these questions here so that others can make use of it in future. Is there a place where i can find out the good documentation for this package? as of now i am referring the demo example and go to code/debug to understand the usage. Atleast for me, its really hard to understand each functionality. it would be really helpful if its documented well so that it will be useful for junior developers like me. Package is really awesome but understanding the functionality and usage of it without documentation is really hard and need to spend lot of time to do research etc. Not many posts in google or any other forum about this package and related questions. i am sharing these information in a positive note.

Appreciate your response!.. Thanks.

@techttiru
I've looked into this, but it's too much to answer right now.
I will reply to you as soon as possible.
Thank you for your efforts.

Thanks for the response!. will really appreciate if you could respond soon.

Question: 9
I have one other additional question. Is there a way i can add new row when "enter key" pressed? basically, i need to create table (lets say two columns) where user can enter data in first row first cell then i will auto populate the first row second cell automatically based on the value that user entered in first row first cell. for example if user enter 1 in first cell, then in second cell i will auto populate 1 * 1000 = 1000. basically its denomination.

once user keyed in the data in the first cell on first row and if press "enter key" then need to open up the next row below and point to second row first cell to allow user to enter the next data. here also i need footer where number rows and total amt (amount will be in second column) to be shown.

i would like to listen the key board keys that user enters and i want do the action accordingly. for ex, sometimes if user enters "enter key" i want to open new row down. sometimes, i want to move to next cell in the same row when user enters "enter key" because it depends on the use case.

Thanks for responding!..

Answer Question 1 - How to update the widget of Footer according to the value change.

Check out the example code and comments below.

class _Footer extends StatefulWidget {
  const _Footer({
    required this.stateManager,
    Key? key,
  }) : super(key: key);

  final PlutoGridStateManager stateManager;

  @override
  State<_Footer> createState() => _FooterState();
}

class _FooterState extends State<_Footer> {
  int sum = 0;

  late final String Function(dynamic value) format;

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

    /// If the value is changed by registering a listener, call setState to update the value.
    widget.stateManager.addListener(listener);

    /// This is to use the format of the existing number column.
    /// You can use the Intl package to override this.
    format = widget.stateManager.columns
        .firstWhere(
          (element) => element.type is PlutoColumnTypeNumber,
        )
        .type
        .number!
        .applyFormat;
  }

  @override
  void dispose() {
    widget.stateManager.removeListener(listener);

    sum = calculateSum();

    super.dispose();
  }

  void listener() {
    int _sum = calculateSum();

    if (_sum != sum) {
      setState(() {
        sum = _sum;
      });
    }
  }

  int calculateSum() {
    final int length = widget.stateManager.refRows.length;

    int _sum = 0;

    for (int i = 0; i < length; i += 1) {
      final row = widget.stateManager.refRows[i];

      _sum += (row.cells['column2']!.value as int) +
          (row.cells['column3']!.value as int);
    }

    return _sum;
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: widget.stateManager.footerHeight,
      child: Center(
        child: Text('Total ${format(sum)}'),
      ),
    );
  }
}

Answer Question 2 - If you press Enter after changing the value in the last row, the value does not change.

I've tested it, the value changes even if there is only one row or the last row. It was confirmed that the event value is output by the print function of the onChanged callback.
Please check again and let me know if you still have problems.

child: PlutoGrid(
  columns: columns,
  rows: rows,
  onChanged: (PlutoGridOnChangedEvent event) {
    print(event);
  },
  onLoaded: (PlutoGridOnLoadedEvent event) {
    stateManager = event.stateManager;
  },
  createFooter: (stateManager) {
    stateManager.footerHeight = 45;
    return _Footer(
      stateManager: stateManager,
    );
  },
  configuration: const PlutoGridConfiguration(
    enterKeyAction: PlutoGridEnterKeyAction.editingAndMoveDown,
  ),
),

Wow. Thank you for the response!. i was really waiting for your response.. Let me try this and will update you.. I would really appreciate if you are able to respond the other questions as well as i understand for now, you answer the first question.Priority would be question #9.

Answer Question 3 - Hide the entire column area

There is no function to hide the column area.

The version to be updated is being improved so that there is no performance problem even when many rows are loaded.
This part is related to the column area.

Of course, adding the ability to hide the column area is an easy task.
However, if there is no other idea to improve performance, it is difficult to add the function to hide the column area.

However, I think the function to hide the column area is a necessary function.
Not right now, but I plan to find other ideas for performance improvements and add them.

Answer Question 4 - Change row height

You can change the row height with PlutoGridConfiguration(rowHeight: 40) ,
but you cannot change the height of each row.
Multiple lines of text can be displayed in cells with the same row height.

multiline

PlutoColumn(
  title: 'column1',
  field: 'column1',
  type: PlutoColumnType.text(),
  renderer: (rendererContext) {
    return Text(
      rendererContext.cell.value,
      maxLines: 2,
    );
  },
),

Answer Question 5 - Is there a way to hide the menu icon for the one specific column?

Yes it is possible

PlutoColumn(
  title: 'column2',
  field: 'column2',
  type: PlutoColumnType.number(),
  enableContextMenu: false,
),

Answer Question 6 - How to set the entire background color of column titles at once.

Each column must be set.
It would be nice to add it so that the color of the entire column can be set.
I will consider it for the next version.

/// Currently, you need to designate the background color of each column like this.
PlutoColumn(
  title: 'column2',
  field: 'column2',
  type: PlutoColumnType.number(),
  enableContextMenu: false,
  backgroundColor: Colors.blue,
),

Replying to answer to question #1 asking additional clarification.

Hi, Where should i call this _Footer class?

currently i am calling my footer class in configuration of my main class as below.


class DataTableView extends StatefulWidget {
  final AttendeeDataModel? currentAttendee;
  const DataTableView({
    Key? key,
    required this.currentAttendee,
  }) : super(key: key);

  @override
  State<DataTableView> createState() => _DataTableViewState();
}

class _DataTableViewState extends State<DataTableView> {
  late PlutoGridStateManager stateManager;
  final List<PlutoColumn> localColumns = [];
  final List<PlutoRow> localRows = [];
  late bool firsTimeTableBuilt;

  @override
  void initState() {
    super.initState();
    localColumns.addAll(buildPlutoColumn());
    firsTimeTableBuilt = true;
  }

  final EventAttendeeRegistrationController
      eventAttendeeRegistrationController = Get.find();

  // final p1 = [
  @override
  Widget build(BuildContext context) {
    if (!firsTimeTableBuilt) {
      stateManager.appendRows([buildPlutoRow(widget.currentAttendee!)]);
      stateManager.moveScrollByRow(
        PlutoMoveDirection.down,
        stateManager.refRows.length - 1,
      );
    }

    return SizedBox(
        height: 200,
        child: PlutoGrid(
          columns: localColumns,
          rows: localRows,
          createFooter: (PlutoGridStateManager pgsm) => TableFooter(
              eventAttendeeRegistrationController:
                  eventAttendeeRegistrationController),
          onChanged: (PlutoGridOnChangedEvent event) {
            updateattendeeDataTableList(event);
          },
          onLoaded: (PlutoGridOnLoadedEvent event) {
            stateManager = event.stateManager;
            firsTimeTableBuilt = false;
          },
          configuration: const PlutoGridConfiguration(
            // rowHeight: 60.0,
            enableColumnBorder: true,
            enableGridBorderShadow: true,
            //    enterKeyAction: PlutoGridEnterKeyAction.editingAndMoveDown
          ),
        ));
    ;
  }

please refer my footer class in my original question.

@techttiru

Where should i call this _Footer class?

Just pass it to createFooter.

createFooter: (stateManager) {
  stateManager.footerHeight = 45;
  return _Footer(
    stateManager: stateManager,
  );
},

Answer Question 4 - Change row height

You can change the row height with PlutoGridConfiguration(rowHeight: 40) , but you cannot change the height of each row. Multiple lines of text can be displayed in cells with the same row height.

multiline

PlutoColumn(
  title: 'column1',
  field: 'column1',
  type: PlutoColumnType.text(),
  renderer: (rendererContext) {
    return Text(
      rendererContext.cell.value,
      maxLines: 2,
    );
  },
),

Thank you!. actually i tried this option already but it becomes static and as you said, this hight apply for all rows and not specific the row where we need more height. but i understood your answer. do we have any option of auto size the row or auto fit the row or cell depends on the content of the cell?

Answer Question 7 - What does mean rowRef?

This is the reference value of rows .
rows returns a list with a spread operator.
refRows immediately returns the referenced value.
The two values are the same, but the difference is whether they are referenced or not.
Accessing the referenced value directly is faster than accessing the spread value, but should reduce the risk of value tampering.
refRows is good for reading values only.

Also in refRows is a FilteredList . This is a variant of the list I developed.
This returns the filtered list, keeping the entire list when the rows are filtered.
If you want to get the entire list in a filtered state, you can use refRows.originalList.
Also, it returns only the paged list, preserving the paginated values.
In a paged state, the value of refRows returns only a list of paged pages.
You can access refRows.filteredList to get a list of all filtered pages in a filtered + paged state.

In short,
refRows : Returns a list of filtered + paging states
refRows.filteredList : returns only a list of filtered states (whether paging or not)
refRows.originalList : Returns all lists regardless of filtering and paging status.

Answer Question 8 - Need for detailed documentation

Of course I agree with your opinion.

Writing documents in English is difficult.
Even if I use a translator.
If I write the documentation in Korean, maybe I can provide a little richer documentation.
And if I use a tool like Notion to write the documentation, it seems to be faster.
I am not familiar with Markdown and it is inconvenient to have to upload it as a file.
Edit, upload file, edit again, upload file...
Consider using a tool like Notion to create your documentation.

@techttiru

Where should i call this _Footer class?

Just pass it to createFooter.

createFooter: (stateManager) {
  stateManager.footerHeight = 45;
  return _Footer(
    stateManager: stateManager,
  );
},

Awesome. this works nicely. so basically add listener method within state class helps to call the footer class every-time whenever change occurs. thats exactly i was missing. because earlier when i was working, footer class was called only once (first time) and thats the reason for total amt was not updated. but after your sample code, changing the stateless to state and adding listener to init method makes to call the footer class again and again whenever there is some edit occur in the table. its nice and good to know. Thank you for you response!.. Really appreciated!.

Thanks for the response!. will really appreciate if you could respond soon.

Question: 9 I have one other additional question. Is there a way i can add new row when "enter key" pressed? basically, i need to create table (lets say two columns) where user can enter data in first row first cell then i will auto populate the first row second cell automatically based on the value that user entered in first row first cell. for example if user enter 1 in first cell, then in second cell i will auto populate 1 * 1000 = 1000. basically its denomination.

once user keyed in the data in the first cell on first row and if press "enter key" then need to open up the next row below and point to second row first cell to allow user to enter the next data. here also i need footer where number rows and total amt (amount will be in second column) to be shown.

i would like to listen the key board keys that user enters and i want do the action accordingly. for ex, sometimes if user enters "enter key" i want to open new row down. sometimes, i want to move to next cell in the same row when user enters "enter key" because it depends on the use case.

Thanks for responding!..

This is the last open question. Would you able to share your thought for this question? i have given details with example and happy to share more details if you want. Thanks..

@techttiru
Last question next... I'm having a hard time right now. 😴

Answer Question 9 - Custom enter key behavior.

Please refer to the example below.

class EmptyScreen extends StatefulWidget {
  static const routeName = 'empty';

  const EmptyScreen({Key? key}) : super(key: key);

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

class _EmptyScreenState extends State<EmptyScreen> {
  late List<PlutoColumn> columns;

  late List<PlutoRow> rows;

  late PlutoGridStateManager stateManager;

  late StreamSubscription<PlutoKeyManagerEvent> stream;

  @override
  dispose() {
    stream.cancel();

    super.dispose();
  }

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

    columns = [
      PlutoColumn(
        title: 'column1',
        field: 'column1',
        type: PlutoColumnType.number(),
      ),
    ];

    rows = DummyData.rowsByColumns(length: 10, columns: columns);
  }

  void streamListener(PlutoKeyManagerEvent event) {
    if (event.isEnter == false) {
      return;
    }

    if (stateManager.isEditing == false) {
      stateManager.setEditing(true);
      return;
    }

    /// When the enter key is pressed
    /// If the current cell value is even, the cell is moved up,
    /// and if the current cell value is odd, the cell is moved down.
    /// If the current cell value is an even number,
    /// it moves up and changes the value of the cell being moved at the same time.
    if (stateManager.currentCell!.value % 2 == 0) {
      if (stateManager.currentRowIdx == null ||
          stateManager.currentRowIdx == 0) {
        return;
      }

      final PlutoCell targetCell = stateManager
          .refRows[stateManager.currentRowIdx! - 1]
          .cells[stateManager.currentColumnField]!;

      stateManager.changeCellValue(
        targetCell,
        stateManager.currentCell!.value + targetCell.value,

        /// When multiple methods of stateManager are called,
        /// Methods except the last can avoid unnecessary updates via notify : false.
        notify: false,

        /// If the cell is readOnly, you can force change the value.
        /// If not readOnly, this is unnecessary.
        force: true,

        /// When the cell value changes, the onChanged callback of PlutoGrid is called.
        /// If the onChanged callback should not handle any other action,
        /// you may not call the callback with false.
        callOnChangedEvent: false,
      );

      /// The default value of notify is true.
      /// It only needs to be called once in the last method.
      stateManager.moveCurrentCell(PlutoMoveDirection.up);
    } else {
      stateManager.moveCurrentCell(PlutoMoveDirection.down);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        padding: const EdgeInsets.all(15),
        child: PlutoGrid(
          columns: columns,
          rows: rows,
          onChanged: (PlutoGridOnChangedEvent event) {
            print(event);
          },
          onLoaded: (PlutoGridOnLoadedEvent event) {
            stateManager = event.stateManager;

            stream = stateManager.keyManager!.subject.listen(streamListener);
          },
          configuration: const PlutoGridConfiguration(
            /// Disable the action of the enter key and handle it in listener.
            enterKeyAction: PlutoGridEnterKeyAction.none,
          ),
        ),
      ),
    );
  }
}

Answer Question 9 - Custom enter key behavior.

Please refer to the example below.

class EmptyScreen extends StatefulWidget {
  static const routeName = 'empty';

  const EmptyScreen({Key? key}) : super(key: key);

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

class _EmptyScreenState extends State<EmptyScreen> {
  late List<PlutoColumn> columns;

  late List<PlutoRow> rows;

  late PlutoGridStateManager stateManager;

  late StreamSubscription<PlutoKeyManagerEvent> stream;

  @override
  dispose() {
    stream.cancel();

    super.dispose();
  }

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

    columns = [
      PlutoColumn(
        title: 'column1',
        field: 'column1',
        type: PlutoColumnType.number(),
      ),
    ];

    rows = DummyData.rowsByColumns(length: 10, columns: columns);
  }

  void streamListener(PlutoKeyManagerEvent event) {
    if (event.isEnter == false) {
      return;
    }

    if (stateManager.isEditing == false) {
      stateManager.setEditing(true);
      return;
    }

    /// When the enter key is pressed
    /// If the current cell value is even, the cell is moved up,
    /// and if the current cell value is odd, the cell is moved down.
    /// If the current cell value is an even number,
    /// it moves up and changes the value of the cell being moved at the same time.
    if (stateManager.currentCell!.value % 2 == 0) {
      if (stateManager.currentRowIdx == null ||
          stateManager.currentRowIdx == 0) {
        return;
      }

      final PlutoCell targetCell = stateManager
          .refRows[stateManager.currentRowIdx! - 1]
          .cells[stateManager.currentColumnField]!;

      stateManager.changeCellValue(
        targetCell,
        stateManager.currentCell!.value + targetCell.value,

        /// When multiple methods of stateManager are called,
        /// Methods except the last can avoid unnecessary updates via notify : false.
        notify: false,

        /// If the cell is readOnly, you can force change the value.
        /// If not readOnly, this is unnecessary.
        force: true,

        /// When the cell value changes, the onChanged callback of PlutoGrid is called.
        /// If the onChanged callback should not handle any other action,
        /// you may not call the callback with false.
        callOnChangedEvent: false,
      );

      /// The default value of notify is true.
      /// It only needs to be called once in the last method.
      stateManager.moveCurrentCell(PlutoMoveDirection.up);
    } else {
      stateManager.moveCurrentCell(PlutoMoveDirection.down);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        padding: const EdgeInsets.all(15),
        child: PlutoGrid(
          columns: columns,
          rows: rows,
          onChanged: (PlutoGridOnChangedEvent event) {
            print(event);
          },
          onLoaded: (PlutoGridOnLoadedEvent event) {
            stateManager = event.stateManager;

            stream = stateManager.keyManager!.subject.listen(streamListener);
          },
          configuration: const PlutoGridConfiguration(
            /// Disable the action of the enter key and handle it in listener.
            enterKeyAction: PlutoGridEnterKeyAction.none,
          ),
        ),
      ),
    );
  }
}

Thank you for responding!. i am going to test this to see how it goes for my use case and will update you!.. Appreciate your time for sharing this example.

Thank you!. Now I am able to listen the key board events based on your example and i am able to solve some extend of my use case but not 100% as i stuck up with few issues.

In my use case, i will have 3 columns.

  1. Denomination amt (ex, 1000, 500, 100, 10),
  2. count of the denomination (ex: 1, 2, 3, 4). Basically how many 1000, how may 500, how may 100 etc.
  3. Total amt - this is basically auto populated by auto calculating denomination amt * count of the denomination. for ex, if denomination is 1000 and count is 5 then i should show 5000 in total amt column.

Here, top row (row index - 0) needs to be always allow to user to key in denomination amt, count and when user press "enter key" when user is in count cell then need to open up the new row down. for ex, 1000 is denomination, count is 5 entered in top (first row) then new row to be opened down where 1000, 5, 5000 to be populated. in the mean time, top row must be empty and need to auto focus the cursor to top row first cell so that user can enter the next denomination. User will continue this process. so whenever new row is added down, need to sort the all the rows based on denomination column but this sorting should exclude the first row because first row will be empty in this case (i understand the type of the field in number here so it can't be empty but i dont know how to make it is empty because populating 0 here is not seems to be good).

apart from this i need to do some validation whether user really enters > 0 in first row cell1 and cell2. i think i can do this.

Below are the problems i am facing.

  1. unable to clear the first row but i am able to populate 0 for all the cells in first row.
  2. unable to auto sort all the rows based on denomination column. not sure what i am missing here because i have setup sort attribute in denomination column but not seeing auto sort happening when new row is added.
  3. unable to focus the cursor to first row first cell after user press "enter key". just note that, user press enter key when user is in first row second cell.
  4. is there a way to give suggestion in first row cell 1 with the value of 1000,500,100,10 etc so that user can easily pick up the value. Selection input type not seems to be good for this use case because selecting from this is not easy rather than typing the actual value.
  5. first time when the table shows, need to have empty values in first row because first row will act as input field for user to key in denomination and count.

Here is the code so far i tried. you can jus copy and run to see what i have tried so far.


import 'dart:async';

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

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

  @override
  State<ReceivedAmtTableData> createState() => _ReceivedAmtTableDataState();
}

class _ReceivedAmtTableDataState extends State<ReceivedAmtTableData> {
  late PlutoGridStateManager stateManager;

  final List<PlutoColumn> localColumns = [];
  final List<PlutoRow> localRows = [];
  late bool firsTimeTableBuilt;

  late StreamSubscription<PlutoKeyManagerEvent> stream;

  @override
  void initState() {
    super.initState();
    localColumns.addAll(buildPlutoRecievedAmtColumn());
    firsTimeTableBuilt = true;
  }

  @override
  dispose() {
    stream.cancel();
    super.dispose();
  }

  void streamListener(PlutoKeyManagerEvent event) {
    if (event.isEnter == true &&
        stateManager.currentCell?.column.field == 'input_cnt') {
      // stateManager.sortDescending(
      //   PlutoColumn(
      //     title: 'Deno',
      //     field: 'received_denomination',
      //     type: PlutoColumnType.number(negative: false),
      //     //  type: PlutoColumnType.select(['1000', '500', '200']),
      //     backgroundColor: const Color(0xFFE3F2FC),
      //     width: 80,
      //     enableContextMenu: false,
      //   ),
      // );

      final donominationValue =
          stateManager.currentRow?.cells['input_denomination']?.value;
      final countValue = stateManager.currentRow?.cells['input_cnt']?.value;
      final totalAmt = donominationValue * countValue;

      stateManager.appendRows(
          [buildPlutoReceivedAmtRow(donominationValue, countValue, totalAmt)]);

      stateManager.currentRow?.cells['input_denomination']?.value = 0;
      stateManager.currentRow?.cells['input_cnt']?.value = 0;
      stateManager.currentRow?.cells['calculated_amt']?.value = 0;

      // stateManager.setGridFocusNode(focusNode)

      //stateManager.currentRow?.cells.clear();
    }
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 500,
      child: PlutoGrid(
        columns: localColumns,
        rows: [buildPlutoReceivedAmtRow(100, 1, 0)],
        // createFooter: (PlutoGridStateManager pgsm) => TableFooter(
        //   eventAttendeeRegistrationController:
        //       eventAttendeeRegistrationController,
        //   stateManager: pgsm,
        // ),
        onChanged: (PlutoGridOnChangedEvent event) {},
        onLoaded: (PlutoGridOnLoadedEvent event) {
          stateManager = event.stateManager;
          firsTimeTableBuilt = false;
          stream = stateManager.keyManager!.subject.listen(streamListener);
        },
        configuration: const PlutoGridConfiguration(
          rowHeight: 30.0,
          enableColumnBorder: true,
          enableGridBorderShadow: true,
          enterKeyAction: PlutoGridEnterKeyAction.none,
        ),
      ),
    );
  }

  List<PlutoColumn> buildPlutoRecievedAmtColumn() {
    final List<PlutoColumn> columns = [
      PlutoColumn(
        title: 'Deno',
        field: 'input_denomination',
        type: PlutoColumnType.number(negative: false),
        //  type: PlutoColumnType.select(['1000', '500', '200']),
        backgroundColor: const Color(0xFFE3F2FC),
        width: 80,
        enableContextMenu: false,
        sort: PlutoColumnSort.descending,
      ),
      PlutoColumn(
        title: 'Cnt',
        field: 'input_cnt',
        type: PlutoColumnType.number(negative: false),
        backgroundColor: const Color(0xFFE3F2FC),
        width: 60,
        enableContextMenu: false,
      ),
      PlutoColumn(
        title: 'Total',
        field: 'calculated_total',
        // minWidth: 10,
        //width: 50,
        type: PlutoColumnType.number(negative: false),
        backgroundColor: const Color(0xFFE3F2FC),
        width: 100,
        enableContextMenu: false,
      ),
    ];
    return columns;
  }
}

PlutoRow buildPlutoReceivedAmtRow(int denomination, int cnt, int totalAmount) {
  return PlutoRow(
    cells: {
      "input_denomination": PlutoCell(value: denomination),
      "input_cnt": PlutoCell(value: cnt),
      "calculated_total": PlutoCell(value: totalAmount),
    },
  );
}

Appreciate your response!. Thanks again.

Just to give some additional note on this. as a work around, i am using textfield to get the input values and hiding the column by using column height to 0. by this way, table is being used to display the rows. instead of column, i created textfields similar to column and fit in top of the table.

@bosskmk , Hi.. i see an unexpected behavior in PlutoGrid when i upgrade from 3.1.2 version to either 4.0.0 or 4.0.1. Here is what happened.
In the below code, i am passing rows to pluto grid dynamically and rebuilding this grid using state management. this is working fine till 3.1.2.

 PlutoGrid(
            columns: localColumns,
            rows: receivedAmtTableStateController
                .receivedAmtTableStateManager.refRows.originalList,
            createFooter: (stateManager) => ReceivedAmtTableFooterData(
              stateManager: stateManager,
            ),

but when i change the version from 3.1.2 to 4.0.0 (no other code changes. only version change for pluto grid), data that is in the refRow.originalList is not showing in pluto rows. When i debug, i see the rows and data available in this field but some how within pluto grid, row data is not showing in grid. for ex, if i have 2 rows with valid data available in the refRows.oringinalList, grid displays 2 empty rows and its not showing the actual data in the row.

It is difficult to identify this problem without code that can reproduce the error.

Below is version 4.1 under development. Can you please check if the same problem occurs in this version as well?

Perhaps this problem only occurs in version 4.0.x.

The links below should be used for testing purposes only. Actual use is possible after it is released into the official version.

dependencies:
  pluto_grid:
    git:
      url: https://github.com/bosskmk/pluto_grid.git
      ref: develop

@bosskmk Hey, sorry for delay in response. Yes, this dependency is working fine. I just commented out 3.1.2 version from my pubspec.yml file in dependencies section and added your develop branch dependency and everything works fine. but if i use anything from 4.0.0 then its not working.

Additionally, JFYI - if i use this develop branch, the below parameter was not been recognized.

     defaultColumnTitlePadding: 0,
     defaultCellPadding: 10,

let me know if you need any additional information. Thanks for your continuous support.. Appreciated..

@techttiru
In the next version (development version), both values are changed to EdgeInsets.

Thanks for confirming the development version.

This issue is stale because it has been open for 30 days with no activity.

This issue was closed because it has been inactive for 14 days since being marked as stale.