Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help] How to add children of Group row programmatically? #689

Closed
delphi007 opened this issue Dec 19, 2022 · 5 comments
Closed

[Help] How to add children of Group row programmatically? #689

delphi007 opened this issue Dec 19, 2022 · 5 comments
Labels
question Further information is requested stale This issue is stale because it has been open for 30 days with no activity.

Comments

@delphi007
Copy link

When setting Grid row group as PlutoRowGroupTreeDelegate, how to add a child row under a group type row programmatically? The stateManager insertRows can only add sibling rows not child row.

@delphi007 delphi007 added the question Further information is requested label Dec 19, 2022
@bosskmk
Copy link
Owner

bosskmk commented Dec 19, 2022

You can add them with insertRows.
If the row of rowIdx in insertRows is a child of a group, the row is inserted as a child of the parent row.

The example below adds a new row before the current row.
If the current row is a child of a group, inserts the row into that group as a child.
The row's child rows must be expanded for this to be added.

pluto_grid_insert_rows

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

import '../dummy_data/development.dart';

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;

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

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

    rows = DummyData.treeRowsByColumn(columns: columns, count: 1, depth: 3);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.all(15),
          child: PlutoGrid(
            columns: columns,
            rows: rows,
            onChanged: (PlutoGridOnChangedEvent event) {
              print(event);
            },
            onLoaded: (PlutoGridOnLoadedEvent event) {
              stateManager = event.stateManager;
              stateManager.setRowGroup(
                PlutoRowGroupTreeDelegate(
                  resolveColumnDepth: (c) => stateManager.columnIndex(c),
                  showFirstExpandableIcon: true,
                  showText: (c) => true,
                ),
              );
            },
            createHeader: (c) {
              return TextButton(
                onPressed: () {
                  final rowIdx = stateManager.currentCellPosition?.rowIdx;

                  if (rowIdx == null) return;

                  final newRow = PlutoRow(
                    cells: {
                      'column1': PlutoCell(value: '1'),
                      'column2': PlutoCell(value: '2'),
                      'column3': PlutoCell(value: '3'),
                    },
                  );

                  stateManager.insertRows(rowIdx, [newRow]);
                },
                child: const Text('Insert'),
              );
            },
            configuration: const PlutoGridConfiguration(),
          ),
        ),
      ),
    );
  }
}

@delphi007
Copy link
Author

Thank you for the prompt answer. But the solution does not cover all the scenarios. What if there exists a group row with no children and I want to add the first child for this empty group row? InsertRows can not express this kind of action.

@github-actions
Copy link

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

@github-actions github-actions bot added the stale This issue is stale because it has been open for 30 days with no activity. label Jan 19, 2023
@github-actions
Copy link

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

@liamssi
Copy link

liamssi commented Oct 16, 2023

Thank you for the prompt answer. But the solution does not cover all the scenarios. What if there exists a group row with no children and I want to add the first child for this empty group row? InsertRows can not express this kind of action.

I had the same issues and after a lot of research without any results, I ended up creating my own extension function (THIS IS HEAVLY INSPIRED FROM THE ORIGINAL FUNCTIONS FOUND IN THE SOURCE CODE), here is how I did it :

//this only works when enabledRowGroups && rowGroupDelegate!.type == PlutoRowGroupDelegateType.tree
extension GroupRowsInsetGroupRows on RowGroupState {
  void insertTreeRowGroupRows2(
      int parentIndex, int childIndex, List<PlutoRow> rows) {
    
    
    //if rows is empty return
    if (rows.isEmpty) {
      return;
    }

    //ensure row groups are enabled and the group type is correct (tree)
    assert(enabledRowGroups &&
        rowGroupDelegate!.type == PlutoRowGroupDelegateType.tree);

    //ensure the parent index is a valid row group
    assert(refRows.length > parentIndex && refRows[parentIndex].type.isGroup);

    //intialize the rows if they are not initialized
    if (!rows.first.initialized) {
      PlutoGridStateManager.initializeRows(
        refColumns.originalList,
        rows,
        forceApplySortIdx: false,
      );
    }


    final targetParent = refRows[parentIndex];
    final grouped = rowGroupDelegate!.toGroup(rows: rows);

    // update the sort index of the rows
    void updateSortIdx({
      required List<PlutoRow> rows,
      required int start,
      required int compare,
      required int increase,
    }) {
      if (hasSortedColumn) {
        for (final row in rows) {
          if (compare >= row.sortIdx) {
            row.sortIdx += increase;
          }
        }
      } else {
        final length = rows.length;
        for (int i = start; i < length; i += 1) {
          rows[i].sortIdx += increase;
        }
      }
    }


    void updateAddedRow(PlutoRow row) {
      row.setState(PlutoRowState.added);
      if (row.type.isGroup) {
        updateChild(PlutoRow e) {
          e.setParent(row);
          updateAddedRow(e);
        }

        row.type.group.children.originalList.forEach(updateChild);
      }
    }

    void updateAddedChildren(PlutoRow parent, List<PlutoRow> children) {
      parent.setState(PlutoRowState.updated);
      updateChild(PlutoRow e) {
        e.setParent(parent);
        updateAddedRow(e);
      }

      children.forEach(updateChild);
    }

    void addAllGroupTree() {
      final siblings = targetParent.type.group.children;

      assert(childIndex > -1);
      final insertIndex =
          childIndex > siblings.length ? siblings.length : childIndex;

      updateAddedChildren(targetParent, grouped);

      final target = siblings.isEmpty || insertIndex == siblings.length
          ? null
          : siblings[insertIndex];

      //set the sort index for the added rows
      final length = grouped.length;
      for (int i = 0; i < length; i += 1) {
        grouped[i].sortIdx = (target?.sortIdx ?? 0) + i;
      }

      updateSortIdx(
        rows: siblings.originalList,
        start: target == null ? 0 : siblings.originalList.indexOf(target),
        compare: target?.sortIdx ?? 0,
        increase: grouped.length,
      );

      siblings.insertAll(insertIndex, grouped);
    }

    _ensureRowGroups(() {
    
          addAllGroupTree();
  
      
    });

    refRows.update();
  }

  void _ensureRowGroups(void Function() callback) {
    assert(enabledRowGroups);
    _collapseAllRowGroup();

    callback();

    _restoreExpandedRowGroup();
  }

  void _collapseAllRowGroup() {
    refRows.removeWhereFromOriginal(isNotMainGroupedRow);
  }

  void _restoreExpandedRowGroup({bool resetCurrentState = false}) {
    final Iterable<PlutoRow> expandedRows = refRows.filterOrOriginalList
        .where(isExpandedGroupedRow)
        .toList(growable: false);

    bool toResetPage = false;

    if (isPaginated) {
      refRows.setFilterRange(null);
      toResetPage = true;
    }

    for (final rowGroup in expandedRows) {
      final Iterable<PlutoRow> children = PlutoRowGroupHelper.iterateWithFilter(
        rowGroup.type.group.children,
        filter: (r) => true,
        childrenFilter: (r) => r.type.isGroup && r.type.group.expanded
            ? r.type.group.children.iterator
            : null,
      );

      final idx = refRows.filterOrOriginalList.indexOf(rowGroup);

      refRows.insertAll(idx + 1, children);
    }

    if (toResetPage) {
      resetPage(resetCurrentState: resetCurrentState, notify: false);
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested stale This issue is stale because it has been open for 30 days with no activity.
Projects
None yet
Development

No branches or pull requests

3 participants