PlutoGrid Documentation

repository·master·Indexed 20 days ago

https://github.com/bosskmk/pluto_grid

A high-performance DataGrid for Flutter optimized for web and desktop. Features include advanced keyboard navigation, cell manipulation, hierarchical data support via group rows, and various column types (text, number, select, date, time). Includes the pluto_grid_export package for exporting grid metadata and content to CSV and PDF formats, as well as support for aggregate footers using PlutoAggregateColumnFooter.

Tokens
12.1K
Snippets
37
Records
51
Agent score
72%

What's inside PlutoGrid

  1. Export PlutoGrid metadata to CSV or PDF

    master

    The pluto_grid_export package allows you to export the metadata and content of a PlutoGrid instance into CSV or PDF formats. To use these features, you must have access to the PlutoGridStateManager (typically obtained via the onLoaded callback of the PlutoGrid widget).

    import 'package:pluto_grid/pluto_grid.dart';
    import 'package:pluto_grid_export/pluto_grid_export.dart' as pluto_grid_export;
    
    // Access the stateManager from PlutoGrid's onLoaded callback
    // and pass it to the export functions.
  2. Customize iOS launch screen assets

    master

    To change the launch screen image for the iOS version of your Flutter application, you can either replace the image files directly in the packages/pluto_grid_export/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory or use Xcode for a more visual approach.

    Using Xcode:

    1. Open your Flutter project's iOS workspace using the command: open ios/Runner.xcworkspace.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog to replace the existing launch images.
    open ios/Runner.xcworkspace
  3. Manage PlutoGrid loading levels

    master

    When using stateManager.setShowLoading(), you can specify the PlutoGridLoadingLevel to control how the loading indicator is displayed:

    • PlutoGridLoadingLevel.grid: The entire grid becomes opaque and the indicator appears in the center. User interaction is disabled.
    • PlutoGridLoadingLevel.rows: A LinearProgressIndicator appears at the top of the row area. User interaction remains possible.
    • PlutoGridLoadingLevel.rowsBottomCircular: A CircularProgressIndicator appears at the bottom of the row area. User interaction remains possible.
  4. Understand PlutoRow hierarchy and depth

    master

    PlutoGrid supports hierarchical data through group rows. A PlutoRow can have a parent reference if it is a child of a group row.

    • isMain: Returns true if the row is a top-level row (has no parent).
    • depth: Returns an integer representing how many levels deep the row is nested within groups.
    • parent: Returns the PlutoRow that contains this row.
  5. Configure PlutoGrid selection modes

    master

    The PlutoGridMode enum determines how users interact with the grid. Use these modes to switch between editing, selecting, or read-only behaviors.

    • PlutoGridMode.normal: Standard mode allowing editing and selection.
    • PlutoGridMode.readOnly: Prevents cell editing. To force an edit programmatically, use stateManager.changeCellValue(..., force: true).
    • PlutoGridMode.select / selectWithOneTap: Non-editable modes used for picking a single item. select requires a tap or Enter, while selectWithOneTap triggers onSelected immediately on a single tap.
    • PlutoGridMode.multiSelect: Allows selecting multiple rows. Tapping a row toggles its selection. selectedRows in the event contains the current selection.
    • PlutoGridMode.popup: An internal mode used when the grid is rendered inside a popup (e.g., for filtering or column settings).
    // Example: Using select mode
    PlutoGrid(
      mode: PlutoGridMode.select,
      onSelected: (event) {
        print('Selected row: ${event.row}');
      },
      // ... other properties
    )
  6. Configure PlutoGrid execution modes

    master

    The mode property determines how the user interacts with the grid:

    • PlutoGridMode.normal: Standard editing and movement mode.
    • PlutoGridMode.readOnly: The grid is non-editable.
    • PlutoGridMode.select: Enables row selection. Tapping or pressing Enter on a row returns information via onSelected. Requires a double tap if no row is currently selected.
    • PlutoGridMode.selectWithOneTap: Similar to select, but onLoaded works when an unselected row is tapped once.
    • PlutoGridMode.multiSelect: Enables multiple row selection.
    • PlutoGridMode.popup: Specialized mode for popup interactions.
  7. Handle asynchronous row loading in PlutoGrid

    master

    To prevent UI freezing when dealing with many rows and columns, pass an empty list to the rows parameter initially. Then, use the onLoaded callback to fetch and initialize rows asynchronously using PlutoGridStateManager.initializeRowsAsync.

    Note: When using setShowLoading(true), you do not need to call stateManager.notifyListeners() because setShowLoading updates the grid state automatically.

    PlutoGrid(
      columns: columns,
      rows: [], // Start with empty rows
      onLoaded: (PlutoGridOnLoadedEvent event) {
        final stateManager = event.stateManager;
        
        stateManager.setShowLoading(true);
    
        PlutoGridStateManager.initializeRowsAsync(
          columns,
          fetchedRows,
        ).then((value) {
          stateManager.refRows.addAll(value);
          stateManager.setShowLoading(false);
        });
      },
    );
  8. Implement lazy pagination with PlutoLazyPagination

    master

    PlutoLazyPagination is a widget used in the createFooter property of PlutoGrid to enable server-side or lazy pagination. It handles page navigation, and can automatically trigger data fetching when the user sorts columns or applies filters.

    To use it, you must provide a fetch callback that conforms to the PlutoLazyPaginationFetch signature. This callback receives a PlutoLazyPaginationRequest containing the current page, the active sort column, and any active filters, and must return a PlutoLazyPaginationResponse containing the total page count and the new rows.

    createFooter: (stateManager) {
      return PlutoLazyPagination(
        fetch: (request) async {
          // 1. Call your API using request.page, request.sortColumn, and request.filterRows
          // 2. Return a PlutoLazyPaginationResponse
          return PlutoLazyPaginationResponse(
            totalPage: 10,
            rows: fetchedRows,
          );
        },
        stateManager: stateManager,
      );
    },
  9. Initialize PlutoGrid with columns and rows

    master

    The PlutoGrid widget is the primary entry point for displaying a grid UI. It requires a list of PlutoColumn and PlutoRow objects.

    Important Constraints:

    • Each PlutoColumn.field must be unique.
    • PlutoColumn.field must match the keys used in PlutoRow.cells maps.
    • For large datasets, initializing rows synchronously can freeze the UI. Use PlutoGridStateManager.initializeRowsAsync to load rows asynchronously after the grid has loaded.
    PlutoGrid(
      columns: [ 
        PlutoColumn(	itle: 'Name', field: 'name', type: PlutoColumnType.text()),
      ],
      rows: [
        PlutoRow(cells: {
          'name': PlutoCell(value: 'John Doe'),
        }),
      ],
    );
  10. Implement infinite scrolling with PlutoInfinityScrollRows

    master

    To implement infinite scrolling in a PlutoGrid, use the PlutoInfinityScrollRows plugin. This plugin automatically triggers a fetch callback when the user reaches the end of the list via scrolling, arrow keys, or PageDown.

    To use it, pass the plugin to the createFooter property of your PlutoGrid.

    Key Configuration Options:

    • fetch: A callback function that returns a Future<PlutoInfinityScrollRowsResponse>.
    • stateManager: The PlutoGridStateManager instance from your grid.
    • initialFetch: If true (default), the fetch function is called immediately upon initialization.
    • fetchWithSorting: If true (default), sorting events trigger a new fetch. If false, the grid sorts the currently loaded rows locally.
    • fetchWithFiltering: If true (default), filtering events trigger a new fetch. If false, the grid filters the currently loaded rows locally.
    createFooter: (s) => PlutoInfinityScrollRows(
      fetch: fetch,
      stateManager: s,
    ),
  11. Implement the PlutoGrid widget

    master

    To render the grid, use the PlutoGrid widget within your build method. You must provide the columns and rows lists. You can also hook into lifecycle and change events using onLoaded and onChanged.

    • onChanged: Triggered when a cell value is modified. Receives a PlutoGridOnChangedEvent.
    • onLoaded: Triggered when the grid is fully initialized. Receives a PlutoGridOnLoadedEvent.
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('PlutoGrid Demo'),
        ),
        body: Container(
          padding: const EdgeInsets.all(30),
          child: PlutoGrid(
              columns: columns,
              rows: rows,
              onChanged: (PlutoGridOnChangedEvent event) {
                print(event);
              },
              onLoaded: (PlutoGridOnLoadedEvent event) {
                print(event);
              }
          ),
        ),
      );
    }```
  12. Install PlutoGrid via pub.dev

    master

    PlutoGrid requires two main data structures: a list of PlutoColumn objects to define the schema and a list of PlutoRow objects to hold the data.

    Column Types

    Use PlutoColumnType to specify how data in a column should be handled:

    • PlutoColumnType.text()
    • PlutoColumnType.number()
    • PlutoColumnType.select(['item1', 'item2'])
    • PlutoColumnType.date()
    • PlutoColumnType.time()

    Row Structure

    Each PlutoRow contains a cells map where the keys are the field names defined in your columns, and the values are PlutoCell objects containing the actual data.

    List<PlutoColumn> columns = [
      PlutoColumn(
        title: 'text column',
        field: 'text_field',
        type: PlutoColumnType.text(),
      ),
      PlutoColumn(
        title: 'number column',
        field: 'number_field',
        type: PlutoColumnType.number(),
      ),
      PlutoColumn(
        title: 'select column',
        field: 'select_field',
        type: PlutoColumnType.select(['item1', 'item2', 'item3']),
      ),
      PlutoColumn(
        title: 'date column',
        field: 'date_field',
        type: PlutoColumnType.date(),
      ),
      PlutoColumn(
        title: 'time column',
        field: 'time_field',
        type: PlutoColumnType.time(),
      ),
    ];
    
    List<PlutoRow> rows = [
      PlutoRow(
        cells: {
          'text_field': PlutoCell(value: 'Text cell value1'),
          'number_field': PlutoCell(value: 2020),
          'select_field': PlutoCell(value: 'item1'),
          'date_field': PlutoCell(value: '2020-08-06'),
          'time_field': PlutoCell(value: '12:30'),
        },
      ),
      // ... additional rows
    ];