Skip to main content

Command Palette

Search for a command to run...

Columns

Published
6 min read
Columns
M

I've mainly been doing backend web development. I also have a technology for web front-end, and recently I mainly develop Flutter packages.

Default properties of columns

Columns must be passed to the columns property, which is a List<PlutoColumn> type when creating a PlutoGrid.

final List<PlutoColumn> columns = [
  PlutoColumn(
    title: 'Id',
    field: 'id',
    type: PlutoColumnType.text(),
  ),
  PlutoColumn(
    title: 'Name',
    field: 'name',
    type: PlutoColumnType.number(),
  ),
  PlutoColumn(
    title: 'Age',
    field: 'age',
    type: PlutoColumnType.date(),
  ),
];

Widget build(BuildContext context) {
  return Scaffold(
    body: Container(
      padding: const EdgeInsets.all(15),
      child: PlutoGrid(
        columns: columns,
        rows: rows,
      ),
    ),
  );
}

title is the title of the column displayed on the screen.
field is the only value that identifies the column inside PlutoGrid.
type determines the type of the column.

Type of column

You can pass defaultValue to the constructor for each column type.
defaultValue is used as the default value when a new row is added.

PlutoColumn(
  title: 'Id',
  field: 'id',
  type: PlutoColumnType.text(defaultValue: 'default value'),
),

Text column

This is a column where text can be entered or edited.

PlutoColumn(
  title: 'Id',
  field: 'id',
  type: PlutoColumnType.text(),
),

Number column

This is a column where numbers can be entered or edited.

PlutoColumn(
  title: 'Age',
  field: 'age',
  type: PlutoColumnType.number(
    negative: false,
    format: '#,###',
    applyFormatOnInit: true,
    allowFirstDot: false,
  ),
),

negative determines whether negative numbers are allowed. Default is true.

format determines the format in which numbers are displayed. The default is #,###. (Follows NumberFormat from Intl package.)

applyFormatOnInit determines whether values are initialized according to format when a row is first added. If the first set value is 1.123 and format does not accept decimal points, the value is initialized to 1. Default is true .

allowFirstDot allows a dot at the beginning if it allows negative numbers. This option is required on devices where the .- symbol works as a single button (some mobile terminals). The default is false .

Select column

This is a column where you can select one of several set items.

PlutoColumn(
  title: 'Role',
  field: 'role',
  type: PlutoColumnType.select(
    <String>[
      'Programmer',
      'Designer',
      'Owner',
    ],
    enableColumnFilter: false,
  ),
),

The user can select one item from the range of items in the List passed when creating select. A built-in popup opens in the grid, allowing you to select it with your keyboard or mouse.

enableColumnFilter is whether to enable filtering on the built-in popup. The default is false . If enabled, you can use the filtering function in the pop-up.

Date column

This is a column where you can enter or edit the date.

PlutoColumn(
  title: 'Joined',
  field: 'joined',
  type: PlutoColumnType.date(
    startDate: DateTime(2022, 01, 01),
    endDate: DateTime(2022, 01, 31),
    format: 'yyyy-MM-dd',
    headerFormat: 'yyyy-MM',
    applyFormatOnInit: true,
  ),
),

startDate can limit the optional starting range of dates. If not set, there is no limit to the starting range when selecting a date.

endDate can constrain the selection end range of dates. If not set, there is no limit to the ending range in the date selection.

format determines the format of the date. (Follows DateFormat in Intl package.)

headerFormat determines the format when displaying the current year and month at the top in the date picker popup.

applyFormatOnInit is whether to change the value to match format when a row is first added. If format is 'yyyy-MM-ddd` and the value is '2022-01-02 00:00:00', the value is changed to '2022-01-02'.

Time column

This is a column where time can be entered or edited. A popup is called to select the hour and minute in the form of 00:00.

PlutoColumn(
  title: 'Working time',
  field: 'working_time',
  type: PlutoColumnType.time(),
),

Additional column properties

Additional properties such as limiting the edit status of a column or adding an icon to the column title.

/// Set the column to non-modifiable read mode.
PlutoColumn(readOnly: true);
/// Set the column width and minimum width.
PlutoColumn(width: 200.0, minWidth: 80.0);
/// Set the padding of the column title and filter area.
PlutoColumn(
   titlePadding: const EdgeInsets.all(10),
   filterPadding: const EdgeInsets.all(10),
);
/// You can customize the column title.
PlutoColumn(
 titleSpan: const TextSpan(
   children: [
     WidgetSpan(
       child: Text(
         '* ',
         style: TextStyle(color: Colors.red),
       ),
     ),
     TextSpan(text: 'column title'),
   ],
 ),
);
/// Set the padding of the cells of the corresponding column.
PlutoColumn(
   cellPadding: const EdgeInsets.all(10),
);
/// Set the column title and text alignment of the cells of the column.
PlutoColumn(
   textAlign: PlutoColumnTextAlign.start,
   titleTextAlign: PlutoColumnTextAlign.end,
);
/// Freeze the column at the beginning or end.
/// If the total width of the non-frozen column is 200 or less, 
/// it is processed to be unfreeze even if the frozen column is set.
PlutoColumn(
   frozen: PlutoColumnFrozen.start,
);
/// Sort the cells in the column.
PlutoColumn(
   sort: PlutoColumnSort.ascending,
);
/// Customize the format of the cells in the column.
/// The example changes the output 
/// to say (1) Allowed in the cell if the actual value is the number '1'.
PlutoColumn(
  title: 'Permission readonly',
  field: 'permission_readonly',
  readOnly: true,
  type: PlutoColumnType.number(),
  /// Apply the formatter in the editing state.
  /// However, it is applied only when the cell is readonly
  /// or the text cannot be directly modified, 
  /// such as in the form of select popup.
  applyFormatterInEditing: true,
  formatter: (dynamic value) {
    if (value.toString() == '1') {
      return '(1) Allowed';
    } else {
      return '(0) Disallowed';
    }
  },
),
/// Set the background color of the column.
PlutoColumn(
  backgroundColor: Colors.white,
);
/// You can customize the cells of the column.
/// The following is an example of dynamically changing 
/// the text color according to the selected item value 
/// in the select type column.
PlutoColumn(
  title: 'column2',
  field: 'column2',
  type: PlutoColumnType.select(<String>['red', 'blue', 'green']),
  renderer: (rendererContext) {
    Color textColor = Colors.black;

    if (rendererContext.cell.value == 'red') {
      textColor = Colors.red;
    } else if (rendererContext.cell.value == 'blue') {
      textColor = Colors.blue;
    } else if (rendererContext.cell.value == 'green') {
      textColor = Colors.green;
    }

    return Text(
      rendererContext.cell.value.toString(),
      style: TextStyle(
        color: textColor,
        fontWeight: FontWeight.bold,
      ),
    );
  },
),
/// Decide whether the position can be moved by dragging the column.
/// If set to `true`, you can move the column 
/// to the position of another column by dragging it.
PlutoColumn(
  enableColumnDrag: true,
);
/// Displays an icon that can drag a row to the cells of the column.
/// You can move the row position by dragging this icon.
PlutoColumn(
  enableRowDrag: true,
);
/// Whether to display a check box in the column and its cells.
PlutoColumn(
  enableRowChecked: true,
);
/// Whether the column can be sorted.
/// If set to `true`, you can sort by tapping the column heading.
PlutoColumn(
  enableSorting: true,
);
/// If `enableContextMenu` is `true`, 
/// an icon that can invoke the context menu is displayed 
/// at the end of the column title.
/// If `enableDropToResize` is `true`, 
/// you can change the column width by dragging the menu icon.
/// If `enableContextMenu` is `true`, 
/// set `enableFilterMenuItem` to `false` to hide filter related menus.
/// When `enableContextMenu` is `true`, if `enableHideColumnMenuItem` 
/// is set to `false`, the menu for hiding columns is not displayed.
/// If `enableContextMenu` is `true`, set `enableSetColumnsMenuItem` to `false` 
/// to hide the column setting menu.
PlutoColumn(
  enableContextMenu: true,
  enableDropToResize: true,
  enableFilterMenuItem: true,
  enableHideColumnMenuItem: true,
  enableSetColumnsMenuItem: true,
);
/// If `enableAutoEditing` is `true`, the cell is automatically changed 
/// to edit state when it receives focus.
/// If `enableEditingMode` is `true`, tap a cell or press Enter 
/// to change to editing state.
PlutoColumn(
  enableAutoEditing: true,
  enableEditingMode: true,
);
/// You can hide the column.
PlutoColumn(
  hide: true,
);
T
Terje2y ago

The framework is truly awesome. Is it possible to have vertical borders on ColumnGroups and NOT on Columns? This is to visually distinguish groups from each other better. It would also, possibly, be a good thing to have the ability to change the background colors on columns/column groups as well as on rows.

J

Is it possible to create an action column having a button or link and then start an action using the data of this row? Every row should show the button or link. Thx jan

R
Rick3y ago

Is there any event that is triggered when someone drag a column or hide a column?

I'm looking for the trigger so I can store and save the column order after dragging and save the visible columns.

M
manki kim3y ago

You can listen for column move events with the PlutoGrid.onColumnsMoved callback. However, there is no event for hiding a column, adding a column, or deleting a column. I have attached the code below for these events.

import 'dart:async';

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;

  late StreamSubscription<PlutoNotifierEvent> notifierEvent;

  late final columnsNotifier = {
    stateManager.moveColumn.hashCode,
    stateManager.hideColumn.hashCode,
    stateManager.hideColumns.hashCode,
    stateManager.insertColumns.hashCode,
    stateManager.removeColumns.hashCode,
    stateManager.toggleFrozenColumn.hashCode,
  };

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

    final dummyData = DummyData(10, 100);

    columns = dummyData.columns;

    rows = dummyData.rows;
  }

  @override
  void dispose() {
    notifierEvent.cancel();

    super.dispose();
  }

  void _notifyListener(PlutoNotifierEvent event) {
    if (event.notifier.firstWhere((e) => columnsNotifier.contains(e)) != -1) {
      print('changed columns');
      // Column currently displayed
      print(stateManager.columns.length);
      // All columns including hidden columns
      print(stateManager.refColumns.originalList.length);
      // fixed left column
      print(stateManager.leftFrozenColumns.length);
      // non-fixed column
      print(stateManager.bodyColumns.length);
      // fixed right column
      print(stateManager.rightFrozenColumns.length);
      // The index of the column according to the order in which the columns are displayed List<int>
      // Assuming there is a column [0,1,2,3,4]
      // If number 3 is fixed to the left, [3,0,1,2,4]
      print(stateManager.columnIndexesByShowFrozen);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.all(15),
          child: PlutoGrid(
            columns: columns,
            rows: rows,
            onLoaded: (PlutoGridOnLoadedEvent event) {
              stateManager = event.stateManager;
              notifierEvent = stateManager.streamNotifier.stream.listen(
                _notifyListener,
              );
            },
          ),
        ),
      ),
    );
  }
}
1
J

Can we have a custom column? For Eg: I wanted to provide an icon with the title in the column. Is the renderer for that?

M
manki kim3y ago

The renderer is a property that customizes the cell (row) of the corresponding column. Customizing column titles is possible with titleSpan .

/// You can customize the column title.
PlutoColumn(
 titleSpan: const TextSpan(
   children: [
     WidgetSpan(
       child: Text(
         '* ',
         style: TextStyle(color: Colors.red),
       ),
     ),
     TextSpan(text: 'column title'),
   ],
 ),
);