From 1391c727eb5d12de605212c319b2746444fe4fbc Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Tue, 26 Dec 2023 09:30:57 +0545 Subject: [PATCH 01/31] feat: PlutoCellColorCallback implemented --- lib/src/manager/pluto_grid_state_manager.dart | 5 ++++ lib/src/manager/state/cell_state.dart | 2 ++ lib/src/pluto_grid.dart | 29 +++++++++++++++++++ lib/src/ui/pluto_base_cell.dart | 21 ++++++++++++-- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/lib/src/manager/pluto_grid_state_manager.dart b/lib/src/manager/pluto_grid_state_manager.dart index 5e0a6f031..14455d154 100644 --- a/lib/src/manager/pluto_grid_state_manager.dart +++ b/lib/src/manager/pluto_grid_state_manager.dart @@ -79,6 +79,7 @@ class PlutoGridStateChangeNotifier extends PlutoChangeNotifier this.onRowsMoved, this.onColumnsMoved, this.rowColorCallback, + this.cellColorCallback, this.createHeader, this.createFooter, PlutoColumnMenuDelegate? columnMenuDelegate, @@ -142,6 +143,9 @@ class PlutoGridStateChangeNotifier extends PlutoChangeNotifier @override final PlutoRowColorCallback? rowColorCallback; + @override + final PlutoCellColorCallback? cellColorCallback; + @override final CreateHeaderCallBack? createHeader; @@ -223,6 +227,7 @@ class PlutoGridStateManager extends PlutoGridStateChangeNotifier { super.onRowsMoved, super.onColumnsMoved, super.rowColorCallback, + super.cellColorCallback, super.createHeader, super.createFooter, super.columnMenuDelegate, diff --git a/lib/src/manager/state/cell_state.dart b/lib/src/manager/state/cell_state.dart index c5ca41133..4f05df0e2 100644 --- a/lib/src/manager/state/cell_state.dart +++ b/lib/src/manager/state/cell_state.dart @@ -5,6 +5,8 @@ abstract class ICellState { /// currently selected cell. PlutoCell? get currentCell; + PlutoCellColorCallback? get cellColorCallback; + /// The position index value of the currently selected cell. PlutoGridCellPosition? get currentCellPosition; diff --git a/lib/src/pluto_grid.dart b/lib/src/pluto_grid.dart index 54d8e96ee..917210e35 100644 --- a/lib/src/pluto_grid.dart +++ b/lib/src/pluto_grid.dart @@ -45,6 +45,9 @@ typedef CreateFooterCallBack = Widget Function( typedef PlutoRowColorCallback = Color Function( PlutoRowColorContext rowColorContext); +typedef PlutoCellColorCallback = Color Function( + PlutoCellColorContext cellColorContext); + /// [PlutoGrid] is a widget that receives columns and rows and is expressed as a grid-type UI. /// /// [PlutoGrid] supports movement and editing with the keyboard, @@ -72,6 +75,7 @@ class PlutoGrid extends PlutoStatefulWidget { this.createFooter, this.noRowsWidget, this.rowColorCallback, + this.columnColorCallback, this.columnMenuDelegate, this.configuration = const PlutoGridConfiguration(), this.notifierFilterResolver, @@ -291,6 +295,8 @@ class PlutoGrid extends PlutoStatefulWidget { /// {@endtemplate} final PlutoRowColorCallback? rowColorCallback; + final PlutoCellColorCallback? columnColorCallback; + /// {@template pluto_grid_property_columnMenuDelegate} /// Column menu can be customized. /// @@ -515,6 +521,7 @@ class PlutoGridState extends PlutoStateWithChange { onRowsMoved: widget.onRowsMoved, onColumnsMoved: widget.onColumnsMoved, rowColorCallback: widget.rowColorCallback, + cellColorCallback: widget.columnColorCallback, createHeader: widget.createHeader, createFooter: widget.createFooter, columnMenuDelegate: widget.columnMenuDelegate, @@ -1471,6 +1478,28 @@ class PlutoRowColorContext { }); } +/// Argument of [PlutoGrid.cellColorCallback] callback +/// to dynamically change the background color of a row. +class PlutoCellColorContext { + final PlutoColumn column; + + final int rowIdx; + + final PlutoRow row; + + final PlutoCell cell; + + final PlutoGridStateManager stateManager; + + PlutoCellColorContext({ + required this.column, + required this.rowIdx, + required this.row, + required this.cell, + required this.stateManager, + }); +} + /// Extension class for [ScrollConfiguration.behavior] of [PlutoGrid]. class PlutoScrollBehavior extends MaterialScrollBehavior { const PlutoScrollBehavior({ diff --git a/lib/src/ui/pluto_base_cell.dart b/lib/src/ui/pluto_base_cell.dart index 2dabd63c4..b3bf729c5 100644 --- a/lib/src/ui/pluto_base_cell.dart +++ b/lib/src/ui/pluto_base_cell.dart @@ -220,9 +220,10 @@ class _CellContainerState extends PlutoStateWithChange<_CellContainer> { required Color cellColorInEditState, required Color cellColorInReadOnlyState, required PlutoGridSelectingMode selectingMode, + required Color? cellColorCallbackColor, }) { if (!hasFocus) { - return gridBackgroundColor; + return cellColorCallbackColor ?? gridBackgroundColor; } if (!isEditing) { @@ -250,9 +251,23 @@ class _CellContainerState extends PlutoStateWithChange<_CellContainer> { required Color? cellColorGroupedRow, required PlutoGridSelectingMode selectingMode, }) { + Color? color; + if (stateManager.cellColorCallback != null) { + color = stateManager.cellColorCallback!( + PlutoCellColorContext( + cell: widget.cell, + column: widget.column, + rowIdx: widget.rowIdx, + row: widget.row, + stateManager: stateManager, + ), + ); + } + if (isCurrentCell) { return BoxDecoration( color: _currentCellColor( + cellColorCallbackColor: color, hasFocus: hasFocus, isEditing: isEditing, readOnly: readOnly, @@ -269,7 +284,7 @@ class _CellContainerState extends PlutoStateWithChange<_CellContainer> { ); } else if (isSelectedCell) { return BoxDecoration( - color: activatedColor, + color: color ?? activatedColor, border: Border.all( color: hasFocus ? activatedBorderColor : inactivatedBorderColor, width: 1, @@ -277,7 +292,7 @@ class _CellContainerState extends PlutoStateWithChange<_CellContainer> { ); } else { return BoxDecoration( - color: isGroupedRowCell ? cellColorGroupedRow : null, + color: isGroupedRowCell ? cellColorGroupedRow : color, border: enableCellVerticalBorder ? BorderDirectional( end: BorderSide( From 96fa692869cd0368930dddd3ad19cdfc864f5f83 Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Tue, 26 Dec 2023 09:36:58 +0545 Subject: [PATCH 02/31] feat: columnColorCallback -> cellColorCallback --- lib/src/pluto_grid.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/pluto_grid.dart b/lib/src/pluto_grid.dart index 917210e35..fd0224fd7 100644 --- a/lib/src/pluto_grid.dart +++ b/lib/src/pluto_grid.dart @@ -75,7 +75,7 @@ class PlutoGrid extends PlutoStatefulWidget { this.createFooter, this.noRowsWidget, this.rowColorCallback, - this.columnColorCallback, + this.cellColorCallback, this.columnMenuDelegate, this.configuration = const PlutoGridConfiguration(), this.notifierFilterResolver, @@ -295,7 +295,7 @@ class PlutoGrid extends PlutoStatefulWidget { /// {@endtemplate} final PlutoRowColorCallback? rowColorCallback; - final PlutoCellColorCallback? columnColorCallback; + final PlutoCellColorCallback? cellColorCallback; /// {@template pluto_grid_property_columnMenuDelegate} /// Column menu can be customized. @@ -521,7 +521,7 @@ class PlutoGridState extends PlutoStateWithChange { onRowsMoved: widget.onRowsMoved, onColumnsMoved: widget.onColumnsMoved, rowColorCallback: widget.rowColorCallback, - cellColorCallback: widget.columnColorCallback, + cellColorCallback: widget.cellColorCallback, createHeader: widget.createHeader, createFooter: widget.createFooter, columnMenuDelegate: widget.columnMenuDelegate, From fb5b75f62de80e24bb62b696999eed059faded5a Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Tue, 26 Dec 2023 09:37:25 +0545 Subject: [PATCH 03/31] feat: support null --- lib/src/pluto_grid.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/pluto_grid.dart b/lib/src/pluto_grid.dart index fd0224fd7..100283f10 100644 --- a/lib/src/pluto_grid.dart +++ b/lib/src/pluto_grid.dart @@ -45,7 +45,7 @@ typedef CreateFooterCallBack = Widget Function( typedef PlutoRowColorCallback = Color Function( PlutoRowColorContext rowColorContext); -typedef PlutoCellColorCallback = Color Function( +typedef PlutoCellColorCallback = Color? Function( PlutoCellColorContext cellColorContext); /// [PlutoGrid] is a widget that receives columns and rows and is expressed as a grid-type UI. From ada9a362b7b046ba0ccf869f5f4edc9e0dc6afaf Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Thu, 18 Apr 2024 10:27:40 +0545 Subject: [PATCH 04/31] feat: handle each change event --- lib/src/manager/state/editing_state.dart | 28 +++++++++++++++++------- lib/src/model/pluto_column.dart | 4 ++++ lib/src/pluto_grid.dart | 20 +++++++++++++++++ lib/src/ui/cells/text_cell.dart | 8 +++++++ 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/lib/src/manager/state/editing_state.dart b/lib/src/manager/state/editing_state.dart index d07fbd6f2..a8a3940ec 100644 --- a/lib/src/manager/state/editing_state.dart +++ b/lib/src/manager/state/editing_state.dart @@ -212,6 +212,7 @@ mixin EditingState implements IPlutoGridState { bool callOnChangedEvent = true, bool force = false, bool notify = true, + bool eachChange = false, }) { final currentColumn = cell.column; @@ -241,14 +242,25 @@ mixin EditingState implements IPlutoGridState { cell.value = value; if (callOnChangedEvent == true && onChanged != null) { - onChanged!(PlutoGridOnChangedEvent( - columnIdx: columnIndex(currentColumn)!, - column: currentColumn, - rowIdx: refRows.indexOf(currentRow), - row: currentRow, - value: value, - oldValue: oldValue, - )); + onChanged!( + eachChange + ? PlutoGridOnEachChangedEvent( + columnIdx: columnIndex(currentColumn)!, + column: currentColumn, + rowIdx: refRows.indexOf(currentRow), + row: currentRow, + value: value, + oldValue: oldValue, + ) + : PlutoGridOnChangedEvent( + columnIdx: columnIndex(currentColumn)!, + column: currentColumn, + rowIdx: refRows.indexOf(currentRow), + row: currentRow, + value: value, + oldValue: oldValue, + ), + ); } notifyListeners(notify, changeCellValue.hashCode); diff --git a/lib/src/model/pluto_column.dart b/lib/src/model/pluto_column.dart index 4945d6632..e7b3d26ae 100644 --- a/lib/src/model/pluto_column.dart +++ b/lib/src/model/pluto_column.dart @@ -192,6 +192,9 @@ class PlutoColumn { /// Hide the column. bool hide; + /// Trigger [PlutoGridOnEachChangedEvent] for each character change + bool enablePlutoGridOnEachChangedEvent; + PlutoColumn({ required this.title, required this.field, @@ -226,6 +229,7 @@ class PlutoColumn { this.enableAutoEditing = false, this.enableEditingMode = true, this.hide = false, + this.enablePlutoGridOnEachChangedEvent = false, }) : _key = UniqueKey(), _checkReadOnly = checkReadOnly; diff --git a/lib/src/pluto_grid.dart b/lib/src/pluto_grid.dart index 06a0ebdb0..c1f6244dc 100644 --- a/lib/src/pluto_grid.dart +++ b/lib/src/pluto_grid.dart @@ -1295,6 +1295,26 @@ class PlutoGridOnChangedEvent { } } +class PlutoGridOnEachChangedEvent extends PlutoGridOnChangedEvent { + const PlutoGridOnEachChangedEvent({ + required super.columnIdx, + required super.column, + required super.rowIdx, + required super.row, + super.value, + super.oldValue, + }); + + @override + String toString() { + String out = '[PlutoGridOnEachChangedEvent] '; + out += 'ColumnIndex : $columnIdx, RowIndex : $rowIdx\n'; + out += '::: oldValue : $oldValue\n'; + out += '::: newValue : $value'; + return out; + } +} + /// This is the argument value of the [PlutoGrid.onSelected] callback /// that is called when the [PlutoGrid.mode] value is in select mode. /// diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index 1bb589444..dc3ee3a49 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -157,6 +157,14 @@ mixin TextCellState on State implements TextFieldProps { : _initialCellValue.toString() == value.toString() ? _CellEditingStatus.init : _CellEditingStatus.updated; + + if (widget.column.enablePlutoGridOnEachChangedEvent) { + widget.stateManager.changeCellValue( + widget.cell, + _textController.text, + eachChange: true, + ); + } } void _handleOnComplete() { From 738c606a68c68ce77df8c5d3550be9475c3e0638 Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Fri, 3 May 2024 11:58:15 +0545 Subject: [PATCH 05/31] feat: add validator on textcell --- lib/src/model/pluto_column.dart | 9 +++++++++ lib/src/ui/cells/text_cell.dart | 12 ++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/src/model/pluto_column.dart b/lib/src/model/pluto_column.dart index e7b3d26ae..1b1efa3de 100644 --- a/lib/src/model/pluto_column.dart +++ b/lib/src/model/pluto_column.dart @@ -2,6 +2,11 @@ import 'package:flutter/material.dart'; import 'package:pluto_grid/pluto_grid.dart'; typedef PlutoColumnValueFormatter = String Function(dynamic value); +typedef PlutoColumnValueValidator = String? Function( + PlutoRow row, + PlutoCell cell, + dynamic value, +); typedef PlutoColumnRenderer = Widget Function( PlutoColumnRendererContext rendererContext); @@ -195,6 +200,9 @@ class PlutoColumn { /// Trigger [PlutoGridOnEachChangedEvent] for each character change bool enablePlutoGridOnEachChangedEvent; + /// Field Validator for the column + PlutoColumnValueValidator? validator; + PlutoColumn({ required this.title, required this.field, @@ -230,6 +238,7 @@ class PlutoColumn { this.enableEditingMode = true, this.hide = false, this.enablePlutoGridOnEachChangedEvent = false, + this.validator, }) : _key = UniqueKey(), _checkReadOnly = checkReadOnly; diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index dc3ee3a49..759f4e987 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -239,13 +239,19 @@ mixin TextCellState on State implements TextFieldProps { cellFocus.requestFocus(); } - return TextField( + return TextFormField( + autovalidateMode: AutovalidateMode.onUserInteraction, focusNode: cellFocus, controller: _textController, readOnly: widget.column.checkReadOnly(widget.row, widget.cell), + validator: (value) => widget.column.validator?.call( + widget.row, + widget.cell, + value, + ), onChanged: _handleOnChanged, onEditingComplete: _handleOnComplete, - onSubmitted: (_) => _handleOnComplete(), + onFieldSubmitted: (_) => _handleOnComplete(), onTap: _handleOnTap, style: widget.stateManager.configuration.style.cellTextStyle, decoration: const InputDecoration( @@ -253,6 +259,8 @@ mixin TextCellState on State implements TextFieldProps { borderSide: BorderSide.none, ), contentPadding: EdgeInsets.zero, + errorStyle: TextStyle(fontSize: 0), + errorBorder: OutlineInputBorder(), ), maxLines: 1, keyboardType: keyboardType, From 807576397be68bf18106410bc4b05d36d3134f69 Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Fri, 3 May 2024 12:02:05 +0545 Subject: [PATCH 06/31] fix: error border validator --- lib/src/ui/cells/text_cell.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index 759f4e987..afe6519d8 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -254,13 +254,13 @@ mixin TextCellState on State implements TextFieldProps { onFieldSubmitted: (_) => _handleOnComplete(), onTap: _handleOnTap, style: widget.stateManager.configuration.style.cellTextStyle, - decoration: const InputDecoration( - border: OutlineInputBorder( + decoration: InputDecoration( + border: const OutlineInputBorder( borderSide: BorderSide.none, ), contentPadding: EdgeInsets.zero, - errorStyle: TextStyle(fontSize: 0), - errorBorder: OutlineInputBorder(), + errorStyle: const TextStyle(fontSize: 0), + errorBorder: Theme.of(context).inputDecorationTheme.errorBorder, ), maxLines: 1, keyboardType: keyboardType, From 85999764a856dfc0e91f0823e7c48499aefe6613 Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Fri, 3 May 2024 12:58:12 +0545 Subject: [PATCH 07/31] feat: error validation on text cell implemented --- lib/src/manager/state/editing_state.dart | 2 + lib/src/model/pluto_cell.dart | 18 +++++ lib/src/ui/cells/pluto_default_cell.dart | 76 +++++++++++-------- lib/src/ui/cells/text_cell.dart | 93 +++++++++++++++++------- 4 files changed, 130 insertions(+), 59 deletions(-) diff --git a/lib/src/manager/state/editing_state.dart b/lib/src/manager/state/editing_state.dart index a8a3940ec..de9f5ae35 100644 --- a/lib/src/manager/state/editing_state.dart +++ b/lib/src/manager/state/editing_state.dart @@ -213,6 +213,7 @@ mixin EditingState implements IPlutoGridState { bool force = false, bool notify = true, bool eachChange = false, + String? validationError, }) { final currentColumn = cell.column; @@ -240,6 +241,7 @@ mixin EditingState implements IPlutoGridState { currentRow.setState(PlutoRowState.updated); cell.value = value; + cell.validationError = validationError; if (callOnChangedEvent == true && onChanged != null) { onChanged!( diff --git a/lib/src/model/pluto_cell.dart b/lib/src/model/pluto_cell.dart index 072ef58b5..66b1f0ba2 100644 --- a/lib/src/model/pluto_cell.dart +++ b/lib/src/model/pluto_cell.dart @@ -10,6 +10,8 @@ class PlutoCell { final Key _key; + String? _validationError; + dynamic _value; dynamic _valueForSorting; @@ -52,6 +54,14 @@ class PlutoCell { return _value; } + String? get validationError { + return _validationError; + } + + bool get hasValidationError { + return _validationError != null && _validationError!.trim().isNotEmpty; + } + set value(dynamic changed) { if (_value == changed) { return; @@ -62,6 +72,14 @@ class PlutoCell { _valueForSorting = null; } + set validationError(String? changed) { + if (_validationError == changed) { + return; + } + _validationError = changed; + print("SET Validation Error $_validationError"); + } + dynamic get valueForSorting { _valueForSorting ??= _getValueForSorting(); diff --git a/lib/src/ui/cells/pluto_default_cell.dart b/lib/src/ui/cells/pluto_default_cell.dart index f74e5a111..e0032909b 100644 --- a/lib/src/ui/cells/pluto_default_cell.dart +++ b/lib/src/ui/cells/pluto_default_cell.dart @@ -163,39 +163,51 @@ class _PlutoDefaultCellState extends PlutoStateWithChange { ); } - return Row(children: [ - if (_canRowDrag) - _RowDragIconWidget( - column: widget.column, - row: widget.row, - rowIdx: widget.rowIdx, - stateManager: stateManager, - feedbackWidget: cellWidget, - dragIcon: Icon( - Icons.drag_indicator, - size: style.iconSize, - color: style.iconColor, - ), - ), - if (widget.column.enableRowChecked) - CheckboxSelectionWidget( - column: widget.column, - row: widget.row, - rowIdx: widget.rowIdx, - stateManager: stateManager, - ), - if (spacingWidget != null) spacingWidget, - if (expandIcon != null) expandIcon, - Expanded(child: cellWidget), - if (_showGroupCount) - Text( - '($_groupCount)', - style: stateManager.configuration.style.cellTextStyle.copyWith( - decoration: TextDecoration.none, - fontWeight: FontWeight.normal, - ), + return Tooltip( + message: widget.cell.validationError ?? "", + child: Container( + decoration: BoxDecoration( + border: widget.cell.hasValidationError + ? Border.all( + color: Theme.of(context).colorScheme.error, + ) + : null, ), - ]); + child: Row(children: [ + if (_canRowDrag) + _RowDragIconWidget( + column: widget.column, + row: widget.row, + rowIdx: widget.rowIdx, + stateManager: stateManager, + feedbackWidget: cellWidget, + dragIcon: Icon( + Icons.drag_indicator, + size: style.iconSize, + color: style.iconColor, + ), + ), + if (widget.column.enableRowChecked) + CheckboxSelectionWidget( + column: widget.column, + row: widget.row, + rowIdx: widget.rowIdx, + stateManager: stateManager, + ), + if (spacingWidget != null) spacingWidget, + if (expandIcon != null) expandIcon, + Expanded(child: cellWidget), + if (_showGroupCount) + Text( + '($_groupCount)', + style: stateManager.configuration.style.cellTextStyle.copyWith( + decoration: TextDecoration.none, + fontWeight: FontWeight.normal, + ), + ), + ]), + ), + ); } } diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index afe6519d8..1da62ce1d 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -102,6 +102,7 @@ mixin TextCellState on State implements TextFieldProps { widget.stateManager.currentCell!, _initialCellValue, notify: false, + validationError: doValidation(_initialCellValue), ); } @@ -138,7 +139,11 @@ mixin TextCellState on State implements TextFieldProps { return; } - widget.stateManager.changeCellValue(widget.cell, _textController.text); + widget.stateManager.changeCellValue( + widget.cell, + _textController.text, + validationError: doValidation(_textController.text), + ); _textController.text = formattedValue; @@ -151,6 +156,11 @@ mixin TextCellState on State implements TextFieldProps { _cellEditingStatus = _CellEditingStatus.updated; } + bool get _validateError => + _validateErrorMessage != null && _validateErrorMessage!.trim().isNotEmpty; + + String? _validateErrorMessage; + void _handleOnChanged(String value) { _cellEditingStatus = formattedValue != value.toString() ? _CellEditingStatus.changed @@ -163,6 +173,7 @@ mixin TextCellState on State implements TextFieldProps { widget.cell, _textController.text, eachChange: true, + validationError: doValidation(value), ); } } @@ -239,36 +250,64 @@ mixin TextCellState on State implements TextFieldProps { cellFocus.requestFocus(); } - return TextFormField( - autovalidateMode: AutovalidateMode.onUserInteraction, - focusNode: cellFocus, - controller: _textController, - readOnly: widget.column.checkReadOnly(widget.row, widget.cell), - validator: (value) => widget.column.validator?.call( - widget.row, - widget.cell, - value, - ), - onChanged: _handleOnChanged, - onEditingComplete: _handleOnComplete, - onFieldSubmitted: (_) => _handleOnComplete(), - onTap: _handleOnTap, - style: widget.stateManager.configuration.style.cellTextStyle, - decoration: InputDecoration( - border: const OutlineInputBorder( - borderSide: BorderSide.none, + return Tooltip( + message: _validateErrorMessage ?? widget.column.title, + child: TextFormField( + autovalidateMode: AutovalidateMode.always, + focusNode: cellFocus, + controller: _textController, + readOnly: widget.column.checkReadOnly(widget.row, widget.cell), + onChanged: _handleOnChanged, + onEditingComplete: _handleOnComplete, + onFieldSubmitted: (_) => _handleOnComplete(), + onTap: _handleOnTap, + style: widget.stateManager.configuration.style.cellTextStyle, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: _validateError + ? BorderSide(color: Colors.red) + : BorderSide.none, + ), + focusedBorder: OutlineInputBorder( + borderSide: _validateError + ? BorderSide(color: Colors.red) + : BorderSide.none, + ), + disabledBorder: OutlineInputBorder( + borderSide: _validateError + ? BorderSide(color: Colors.red) + : BorderSide.none, + ), + enabledBorder: OutlineInputBorder( + borderSide: _validateError + ? BorderSide(color: Colors.red) + : BorderSide.none, + ), + contentPadding: EdgeInsets.zero, ), - contentPadding: EdgeInsets.zero, - errorStyle: const TextStyle(fontSize: 0), - errorBorder: Theme.of(context).inputDecorationTheme.errorBorder, + maxLines: 1, + keyboardType: keyboardType, + inputFormatters: inputFormatters, + textAlignVertical: TextAlignVertical.center, + textAlign: widget.column.textAlign.value, ), - maxLines: 1, - keyboardType: keyboardType, - inputFormatters: inputFormatters, - textAlignVertical: TextAlignVertical.center, - textAlign: widget.column.textAlign.value, ); } + + String? doValidation(String value) { + if (widget.column.validator != null) { + _validateErrorMessage = widget.column.validator?.call( + widget.row, + widget.cell, + value, + ); + + setState(() {}); + return _validateErrorMessage; + } + + return null; + } } enum _CellEditingStatus { From ac2c9e56d269d09e3987346db85380be922973bf Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Fri, 3 May 2024 12:59:27 +0545 Subject: [PATCH 08/31] feat: use error colorscheme --- lib/src/ui/cells/text_cell.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index 1da62ce1d..def4d0cd6 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -265,22 +265,22 @@ mixin TextCellState on State implements TextFieldProps { decoration: InputDecoration( border: OutlineInputBorder( borderSide: _validateError - ? BorderSide(color: Colors.red) + ? BorderSide(color: Theme.of(context).colorScheme.error) : BorderSide.none, ), focusedBorder: OutlineInputBorder( borderSide: _validateError - ? BorderSide(color: Colors.red) + ? BorderSide(color: Theme.of(context).colorScheme.error) : BorderSide.none, ), disabledBorder: OutlineInputBorder( borderSide: _validateError - ? BorderSide(color: Colors.red) + ? BorderSide(color: Theme.of(context).colorScheme.error) : BorderSide.none, ), enabledBorder: OutlineInputBorder( borderSide: _validateError - ? BorderSide(color: Colors.red) + ? BorderSide(color: Theme.of(context).colorScheme.error) : BorderSide.none, ), contentPadding: EdgeInsets.zero, From d9cd10ce6d027377efc840e542b4758e4406d74e Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Fri, 3 May 2024 13:04:03 +0545 Subject: [PATCH 09/31] feat: add cellInternalPadding --- lib/src/model/pluto_column.dart | 4 ++++ lib/src/ui/cells/text_cell.dart | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/model/pluto_column.dart b/lib/src/model/pluto_column.dart index 1b1efa3de..d78769a62 100644 --- a/lib/src/model/pluto_column.dart +++ b/lib/src/model/pluto_column.dart @@ -72,6 +72,9 @@ class PlutoColumn { /// It takes precedence over defaultCellPadding in PlutoGridConfiguration. EdgeInsets? cellPadding; + /// Customisable cellField padding. + EdgeInsets? cellInternalPadding; + /// Text alignment in Cell. (Left, Right, Center) PlutoColumnTextAlign textAlign; @@ -215,6 +218,7 @@ class PlutoColumn { this.filterPadding, this.titleSpan, this.cellPadding, + this.cellInternalPadding, this.textAlign = PlutoColumnTextAlign.start, this.titleTextAlign = PlutoColumnTextAlign.start, this.frozen = PlutoColumnFrozen.none, diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index def4d0cd6..ae673490a 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -283,7 +283,7 @@ mixin TextCellState on State implements TextFieldProps { ? BorderSide(color: Theme.of(context).colorScheme.error) : BorderSide.none, ), - contentPadding: EdgeInsets.zero, + contentPadding: widget.column.cellInternalPadding ?? EdgeInsets.zero, ), maxLines: 1, keyboardType: keyboardType, From 770ddd7a50bd138101a9fddab87e354e12aef00d Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Fri, 3 May 2024 13:12:58 +0545 Subject: [PATCH 10/31] feat: changes --- lib/src/model/pluto_cell.dart | 1 - lib/src/ui/cells/pluto_default_cell.dart | 76 ++++++++++-------------- lib/src/ui/cells/text_cell.dart | 58 ++++++------------ lib/src/ui/pluto_base_cell.dart | 21 +++++-- 4 files changed, 66 insertions(+), 90 deletions(-) diff --git a/lib/src/model/pluto_cell.dart b/lib/src/model/pluto_cell.dart index 66b1f0ba2..cb39aa9d0 100644 --- a/lib/src/model/pluto_cell.dart +++ b/lib/src/model/pluto_cell.dart @@ -77,7 +77,6 @@ class PlutoCell { return; } _validationError = changed; - print("SET Validation Error $_validationError"); } dynamic get valueForSorting { diff --git a/lib/src/ui/cells/pluto_default_cell.dart b/lib/src/ui/cells/pluto_default_cell.dart index e0032909b..f74e5a111 100644 --- a/lib/src/ui/cells/pluto_default_cell.dart +++ b/lib/src/ui/cells/pluto_default_cell.dart @@ -163,51 +163,39 @@ class _PlutoDefaultCellState extends PlutoStateWithChange { ); } - return Tooltip( - message: widget.cell.validationError ?? "", - child: Container( - decoration: BoxDecoration( - border: widget.cell.hasValidationError - ? Border.all( - color: Theme.of(context).colorScheme.error, - ) - : null, + return Row(children: [ + if (_canRowDrag) + _RowDragIconWidget( + column: widget.column, + row: widget.row, + rowIdx: widget.rowIdx, + stateManager: stateManager, + feedbackWidget: cellWidget, + dragIcon: Icon( + Icons.drag_indicator, + size: style.iconSize, + color: style.iconColor, + ), ), - child: Row(children: [ - if (_canRowDrag) - _RowDragIconWidget( - column: widget.column, - row: widget.row, - rowIdx: widget.rowIdx, - stateManager: stateManager, - feedbackWidget: cellWidget, - dragIcon: Icon( - Icons.drag_indicator, - size: style.iconSize, - color: style.iconColor, - ), - ), - if (widget.column.enableRowChecked) - CheckboxSelectionWidget( - column: widget.column, - row: widget.row, - rowIdx: widget.rowIdx, - stateManager: stateManager, - ), - if (spacingWidget != null) spacingWidget, - if (expandIcon != null) expandIcon, - Expanded(child: cellWidget), - if (_showGroupCount) - Text( - '($_groupCount)', - style: stateManager.configuration.style.cellTextStyle.copyWith( - decoration: TextDecoration.none, - fontWeight: FontWeight.normal, - ), - ), - ]), - ), - ); + if (widget.column.enableRowChecked) + CheckboxSelectionWidget( + column: widget.column, + row: widget.row, + rowIdx: widget.rowIdx, + stateManager: stateManager, + ), + if (spacingWidget != null) spacingWidget, + if (expandIcon != null) expandIcon, + Expanded(child: cellWidget), + if (_showGroupCount) + Text( + '($_groupCount)', + style: stateManager.configuration.style.cellTextStyle.copyWith( + decoration: TextDecoration.none, + fontWeight: FontWeight.normal, + ), + ), + ]); } } diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index ae673490a..135a72c62 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -250,47 +250,25 @@ mixin TextCellState on State implements TextFieldProps { cellFocus.requestFocus(); } - return Tooltip( - message: _validateErrorMessage ?? widget.column.title, - child: TextFormField( - autovalidateMode: AutovalidateMode.always, - focusNode: cellFocus, - controller: _textController, - readOnly: widget.column.checkReadOnly(widget.row, widget.cell), - onChanged: _handleOnChanged, - onEditingComplete: _handleOnComplete, - onFieldSubmitted: (_) => _handleOnComplete(), - onTap: _handleOnTap, - style: widget.stateManager.configuration.style.cellTextStyle, - decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: _validateError - ? BorderSide(color: Theme.of(context).colorScheme.error) - : BorderSide.none, - ), - focusedBorder: OutlineInputBorder( - borderSide: _validateError - ? BorderSide(color: Theme.of(context).colorScheme.error) - : BorderSide.none, - ), - disabledBorder: OutlineInputBorder( - borderSide: _validateError - ? BorderSide(color: Theme.of(context).colorScheme.error) - : BorderSide.none, - ), - enabledBorder: OutlineInputBorder( - borderSide: _validateError - ? BorderSide(color: Theme.of(context).colorScheme.error) - : BorderSide.none, - ), - contentPadding: widget.column.cellInternalPadding ?? EdgeInsets.zero, - ), - maxLines: 1, - keyboardType: keyboardType, - inputFormatters: inputFormatters, - textAlignVertical: TextAlignVertical.center, - textAlign: widget.column.textAlign.value, + return TextFormField( + autovalidateMode: AutovalidateMode.always, + focusNode: cellFocus, + controller: _textController, + readOnly: widget.column.checkReadOnly(widget.row, widget.cell), + onChanged: _handleOnChanged, + onEditingComplete: _handleOnComplete, + onFieldSubmitted: (_) => _handleOnComplete(), + onTap: _handleOnTap, + style: widget.stateManager.configuration.style.cellTextStyle, + decoration: InputDecoration( + border: const OutlineInputBorder(borderSide: BorderSide.none), + contentPadding: widget.column.cellInternalPadding ?? EdgeInsets.zero, ), + maxLines: 1, + keyboardType: keyboardType, + inputFormatters: inputFormatters, + textAlignVertical: TextAlignVertical.center, + textAlign: widget.column.textAlign.value, ); } diff --git a/lib/src/ui/pluto_base_cell.dart b/lib/src/ui/pluto_base_cell.dart index ab167f84d..52b6d825b 100644 --- a/lib/src/ui/pluto_base_cell.dart +++ b/lib/src/ui/pluto_base_cell.dart @@ -307,11 +307,22 @@ class _CellContainerState extends PlutoStateWithChange<_CellContainer> { @override Widget build(BuildContext context) { - return DecoratedBox( - decoration: _decoration, - child: Padding( - padding: widget.cellPadding, - child: widget.child, + if (widget.cell.hasValidationError) { + _decoration = _decoration.copyWith( + border: Border.all( + color: Theme.of(context).colorScheme.error, + ), + ); + } + + return Tooltip( + message: widget.cell.validationError ?? "", + child: DecoratedBox( + decoration: _decoration, + child: Padding( + padding: widget.cellPadding, + child: widget.child, + ), ), ); } From 149ecd929b34b01ae76586e83276b9876cda2afd Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Fri, 3 May 2024 13:32:28 +0545 Subject: [PATCH 11/31] feat: validate on statemanager added --- lib/src/manager/state/editing_state.dart | 2 ++ lib/src/manager/state/layout_state.dart | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/src/manager/state/editing_state.dart b/lib/src/manager/state/editing_state.dart index de9f5ae35..e64f0100a 100644 --- a/lib/src/manager/state/editing_state.dart +++ b/lib/src/manager/state/editing_state.dart @@ -44,6 +44,8 @@ abstract class IEditingState { bool callOnChangedEvent = true, bool force = false, bool notify = true, + bool eachChange = false, + String? validationError, }); } diff --git a/lib/src/manager/state/layout_state.dart b/lib/src/manager/state/layout_state.dart index 0732270bb..255cb5bf9 100644 --- a/lib/src/manager/state/layout_state.dart +++ b/lib/src/manager/state/layout_state.dart @@ -440,6 +440,27 @@ mixin LayoutState implements IPlutoGridState { notifyListeners(notify, setShowColumnFooter.hashCode); } + @override + void validate({bool notify = true}) { + for (var rowElement in refRows.originalList) { + for (var cellElement in rowElement.cells.values) { + if (cellElement.column.validator != null) { + changeCellValue( + cellElement, + cellElement.value, + validationError: cellElement.column.validator?.call( + rowElement, + cellElement, + cellElement.value, + ), + ); + } + } + } + + notifyListeners(notify, validate.hashCode); + } + @override void setShowColumnFilter(bool flag, {bool notify = true}) { if (showColumnFilter == flag) { From 09bf4357b2d8c2964ae42ab3d79a66817fa6638d Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Sat, 4 May 2024 09:10:13 +0545 Subject: [PATCH 12/31] feat: validate to return isValid --- lib/src/manager/state/layout_state.dart | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/src/manager/state/layout_state.dart b/lib/src/manager/state/layout_state.dart index 255cb5bf9..a039d8496 100644 --- a/lib/src/manager/state/layout_state.dart +++ b/lib/src/manager/state/layout_state.dart @@ -440,25 +440,33 @@ mixin LayoutState implements IPlutoGridState { notifyListeners(notify, setShowColumnFooter.hashCode); } - @override - void validate({bool notify = true}) { + bool validate({bool notify = true}) { + bool isValid = true; for (var rowElement in refRows.originalList) { for (var cellElement in rowElement.cells.values) { if (cellElement.column.validator != null) { - changeCellValue( + final validationError = cellElement.column.validator?.call( + rowElement, cellElement, cellElement.value, - validationError: cellElement.column.validator?.call( - rowElement, + ); + if (validationError != null) { + changeCellValue( cellElement, cellElement.value, - ), - ); + force: true, + eachChange: true, + callOnChangedEvent: true, + validationError: validationError, + ); + isValid = false; + } } } } notifyListeners(notify, validate.hashCode); + return isValid; } @override From f0cc6f13d2ba5e8b1c9a890c9dfe45e42614f949 Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Sat, 4 May 2024 09:22:09 +0545 Subject: [PATCH 13/31] fix: init fixes --- lib/src/model/pluto_cell.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/model/pluto_cell.dart b/lib/src/model/pluto_cell.dart index cb39aa9d0..48c8cfc37 100644 --- a/lib/src/model/pluto_cell.dart +++ b/lib/src/model/pluto_cell.dart @@ -55,11 +55,15 @@ class PlutoCell { } String? get validationError { + if (_needToApplyFormatOnInit) { + _applyFormatOnInit(); + } + return _validationError; } bool get hasValidationError { - return _validationError != null && _validationError!.trim().isNotEmpty; + return validationError != null && validationError!.trim().isNotEmpty; } set value(dynamic changed) { From e591386bf0989d72edb2a695a462156be8574b7d Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Sat, 4 May 2024 09:36:11 +0545 Subject: [PATCH 14/31] fix: init fixes --- lib/src/manager/state/layout_state.dart | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/src/manager/state/layout_state.dart b/lib/src/manager/state/layout_state.dart index a039d8496..741bf5050 100644 --- a/lib/src/manager/state/layout_state.dart +++ b/lib/src/manager/state/layout_state.dart @@ -444,22 +444,24 @@ mixin LayoutState implements IPlutoGridState { bool isValid = true; for (var rowElement in refRows.originalList) { for (var cellElement in rowElement.cells.values) { - if (cellElement.column.validator != null) { - final validationError = cellElement.column.validator?.call( - rowElement, - cellElement, - cellElement.value, - ); - if (validationError != null) { - changeCellValue( + if (cellElement.initialized) { + if (cellElement.column.validator != null) { + final validationError = cellElement.column.validator?.call( + rowElement, cellElement, cellElement.value, - force: true, - eachChange: true, - callOnChangedEvent: true, - validationError: validationError, ); - isValid = false; + if (validationError != null) { + changeCellValue( + cellElement, + cellElement.value, + force: true, + eachChange: true, + callOnChangedEvent: true, + validationError: validationError, + ); + isValid = false; + } } } } From 7bca516e0690e890ee85e1c41777c1d525303270 Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Sat, 4 May 2024 09:49:34 +0545 Subject: [PATCH 15/31] fix: unvalid -> valid changes --- lib/src/manager/state/layout_state.dart | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/src/manager/state/layout_state.dart b/lib/src/manager/state/layout_state.dart index 741bf5050..e96926976 100644 --- a/lib/src/manager/state/layout_state.dart +++ b/lib/src/manager/state/layout_state.dart @@ -451,15 +451,17 @@ mixin LayoutState implements IPlutoGridState { cellElement, cellElement.value, ); + + changeCellValue( + cellElement, + cellElement.value, + force: true, + eachChange: true, + callOnChangedEvent: true, + validationError: validationError, + ); + if (validationError != null) { - changeCellValue( - cellElement, - cellElement.value, - force: true, - eachChange: true, - callOnChangedEvent: true, - validationError: validationError, - ); isValid = false; } } From 0adc7aa7a46f20c22cd9da503269d85fba343d2d Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Sat, 4 May 2024 14:54:56 +0545 Subject: [PATCH 16/31] fix: ignore hidden column --- lib/src/manager/state/layout_state.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/manager/state/layout_state.dart b/lib/src/manager/state/layout_state.dart index e96926976..cbc53e7fd 100644 --- a/lib/src/manager/state/layout_state.dart +++ b/lib/src/manager/state/layout_state.dart @@ -445,7 +445,8 @@ mixin LayoutState implements IPlutoGridState { for (var rowElement in refRows.originalList) { for (var cellElement in rowElement.cells.values) { if (cellElement.initialized) { - if (cellElement.column.validator != null) { + if (cellElement.column.validator != null && + !cellElement.column.hide) { final validationError = cellElement.column.validator?.call( rowElement, cellElement, From 8e6504bf853a40fcbb24752d2ce975b3a18161b5 Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Tue, 7 May 2024 10:16:01 +0545 Subject: [PATCH 17/31] feat: force cell update onSubmit --- lib/src/ui/cells/text_cell.dart | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/src/ui/cells/text_cell.dart b/lib/src/ui/cells/text_cell.dart index 135a72c62..042ce0c42 100644 --- a/lib/src/ui/cells/text_cell.dart +++ b/lib/src/ui/cells/text_cell.dart @@ -156,19 +156,15 @@ mixin TextCellState on State implements TextFieldProps { _cellEditingStatus = _CellEditingStatus.updated; } - bool get _validateError => - _validateErrorMessage != null && _validateErrorMessage!.trim().isNotEmpty; - - String? _validateErrorMessage; - - void _handleOnChanged(String value) { + void _handleOnChanged(String value, [bool forceChangeCellValue = false]) { _cellEditingStatus = formattedValue != value.toString() ? _CellEditingStatus.changed : _initialCellValue.toString() == value.toString() ? _CellEditingStatus.init : _CellEditingStatus.updated; - if (widget.column.enablePlutoGridOnEachChangedEvent) { + if (forceChangeCellValue || + widget.column.enablePlutoGridOnEachChangedEvent) { widget.stateManager.changeCellValue( widget.cell, _textController.text, @@ -183,7 +179,7 @@ mixin TextCellState on State implements TextFieldProps { _changeValue(); - _handleOnChanged(old); + _handleOnChanged(old, true); PlatformHelper.onMobile(() { widget.stateManager.setKeepFocus(false); @@ -274,14 +270,11 @@ mixin TextCellState on State implements TextFieldProps { String? doValidation(String value) { if (widget.column.validator != null) { - _validateErrorMessage = widget.column.validator?.call( + return widget.column.validator?.call( widget.row, widget.cell, value, ); - - setState(() {}); - return _validateErrorMessage; } return null; From e16b779118ddc085d637cd26d6662d419a95c29d Mon Sep 17 00:00:00 2001 From: ujwalbasnet1 Date: Sat, 1 Jun 2024 10:34:49 +0545 Subject: [PATCH 18/31] feat: support for body padding --- lib/src/pluto_grid_configuration.dart | 5 +++++ lib/src/ui/pluto_body_rows.dart | 1 + 2 files changed, 6 insertions(+) diff --git a/lib/src/pluto_grid_configuration.dart b/lib/src/pluto_grid_configuration.dart index 9b946b169..6dfa199a1 100644 --- a/lib/src/pluto_grid_configuration.dart +++ b/lib/src/pluto_grid_configuration.dart @@ -192,6 +192,7 @@ class PlutoGridConfiguration { class PlutoGridStyleConfig { const PlutoGridStyleConfig({ + this.bodyPadding = EdgeInsets.zero, this.enableGridBorderShadow = false, this.enableColumnBorderVertical = true, this.enableColumnBorderHorizontal = true, @@ -248,6 +249,7 @@ class PlutoGridStyleConfig { }); const PlutoGridStyleConfig.dark({ + this.bodyPadding = EdgeInsets.zero, this.enableGridBorderShadow = false, this.enableColumnBorderVertical = true, this.enableColumnBorderHorizontal = true, @@ -303,6 +305,9 @@ class PlutoGridStyleConfig { this.gridPopupBorderRadius = BorderRadius.zero, }); + /// body padding + final EdgeInsets bodyPadding; + /// Enable borderShadow in [PlutoGrid]. final bool enableGridBorderShadow; diff --git a/lib/src/ui/pluto_body_rows.dart b/lib/src/ui/pluto_body_rows.dart index fc37f7209..d7472b974 100644 --- a/lib/src/ui/pluto_body_rows.dart +++ b/lib/src/ui/pluto_body_rows.dart @@ -103,6 +103,7 @@ class PlutoBodyRowsState extends PlutoStateWithChange { itemCount: _rows.length, itemExtent: stateManager.rowTotalHeight, addRepaintBoundaries: false, + padding: stateManager.configuration.style.bodyPadding, itemBuilder: (ctx, i) { return PlutoBaseRow( key: ValueKey('body_row_${_rows[i].key}'), From cd784aea6dee98d2e3a2b33589c5ef04fde894c4 Mon Sep 17 00:00:00 2001 From: Ram Koirala <69522882+RamKoirala1123@users.noreply.github.com> Date: Thu, 12 Dec 2024 09:50:18 +0545 Subject: [PATCH 19/31] Update pubspec.yaml --- packages/pluto_grid_export/pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/pluto_grid_export/pubspec.yaml b/packages/pluto_grid_export/pubspec.yaml index 92a7dfe4e..5d332141b 100644 --- a/packages/pluto_grid_export/pubspec.yaml +++ b/packages/pluto_grid_export/pubspec.yaml @@ -13,7 +13,9 @@ dependencies: flutter: sdk: flutter pluto_grid: - path: ../.. + git: + url: https://github.com/RamKoirala1123/pluto_grid.git + ref: e16b779118ddc085d637cd26d6662d419a95c29d csv: ^5.0.1 pdf: ^3.10.3 printing: ^5.10.4 From 6c4b8abaa9adfde57ec114eea81db541a8a9c089 Mon Sep 17 00:00:00 2001 From: RamKoirala1123 Date: Thu, 12 Dec 2024 14:21:31 +0545 Subject: [PATCH 20/31] feat: header and footer support in export pdf --- .../lib/src/pdf/pluto_grid_pdf_export.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart b/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart index 2eb444fbd..bbdf45783 100644 --- a/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart +++ b/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart @@ -1,5 +1,6 @@ import 'dart:typed_data'; +import 'package:flutter/material.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart'; import 'package:pluto_grid/pluto_grid.dart'; @@ -27,8 +28,12 @@ class PlutoGridDefaultPdfExport extends AbstractTextExport { this.creator, this.format, this.themeData, + this.header, + this.footer, }); + final Widget? header; + final Widget? footer; final String title; final String? creator; PdfPageFormat? format; @@ -37,6 +42,8 @@ class PlutoGridDefaultPdfExport extends AbstractTextExport { @override Future export(PlutoGridStateManager state) async { return GenericPdfController( + header: header, + footer: footer, title: title, creator: creator ?? "https://pub.dev/packages/pluto_grid", format: format ?? PdfPageFormat.a4.landscape, From 2840ccf009a6a70910c5bcd106f6d0647be962c4 Mon Sep 17 00:00:00 2001 From: RamKoirala1123 Date: Thu, 12 Dec 2024 14:24:55 +0545 Subject: [PATCH 21/31] fix: header and footer support --- .../lib/src/pdf/generic_pdf_controller.dart | 73 ++++++++++--------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart index 4af78ab21..944c40220 100644 --- a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart +++ b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart @@ -1,3 +1,4 @@ +import 'package:flutter/widgets.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart'; @@ -17,9 +18,13 @@ class GenericPdfController extends PdfController { required this.format, required this.columns, required this.rows, + this.header, + this.footer, this.themeData, }); + final Widget? header; + final Widget? footer; final String title; final String creator; final PdfPageFormat format; @@ -51,24 +56,25 @@ class GenericPdfController extends PdfController { Widget getHeader(Context context) { String title = getDocumentTitle(); - return Container( - width: double.infinity, - margin: const EdgeInsets.only(bottom: 1), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Text( - title, - style: TextStyle( - fontWeight: FontWeight.bold, - ), - textAlign: TextAlign.center, - ), - ) - ], - ), - ); + return header ?? + Container( + width: double.infinity, + margin: const EdgeInsets.only(bottom: 1), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Text( + title, + style: TextStyle( + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ) + ], + ), + ); } @override @@ -124,22 +130,23 @@ class GenericPdfController extends PdfController { @override Widget getFooter(Context context) { - return Padding( - padding: const EdgeInsets.only(top: 8), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - '# ${context.pageNumber}/${context.pagesCount}', - ), - Text( - DateTime.now().toString(), + return footer ?? + Padding( + padding: const EdgeInsets.only(top: 8), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + '# ${context.pageNumber}/${context.pagesCount}', + ), + Text( + DateTime.now().toString(), + ), + ], ), - ], - ), - ); + ); } @override From b3f81ee06a0585e7aeaed71125d45243cbebfb93 Mon Sep 17 00:00:00 2001 From: RamKoirala1123 Date: Thu, 12 Dec 2024 14:50:57 +0545 Subject: [PATCH 22/31] fix: import issue --- .../pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart | 1 - .../pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart index 944c40220..af27a87e2 100644 --- a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart +++ b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart @@ -1,4 +1,3 @@ -import 'package:flutter/widgets.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart'; diff --git a/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart b/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart index bbdf45783..94b28f1e0 100644 --- a/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart +++ b/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart @@ -1,6 +1,5 @@ import 'dart:typed_data'; -import 'package:flutter/material.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart'; import 'package:pluto_grid/pluto_grid.dart'; From 5f793a00423d2cab6b07d5559d55f2a2c6d3ed73 Mon Sep 17 00:00:00 2001 From: RamKoirala1123 Date: Thu, 6 Feb 2025 14:56:06 +0545 Subject: [PATCH 23/31] added filter --- lib/src/model/pluto_column.dart | 5 +++++ lib/src/ui/columns/pluto_column_title.dart | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/src/model/pluto_column.dart b/lib/src/model/pluto_column.dart index d78769a62..6555a1572 100644 --- a/lib/src/model/pluto_column.dart +++ b/lib/src/model/pluto_column.dart @@ -26,6 +26,10 @@ typedef PlutoColumnCheckReadOnly = bool Function( ); class PlutoColumn { + bool? isFilterApplied; + + Function()? onPressedFilter; + /// A title to be displayed on the screen. /// If a titleSpan value is set, the title value is not displayed. String title; @@ -207,6 +211,7 @@ class PlutoColumn { PlutoColumnValueValidator? validator; PlutoColumn({ + this.isFilterApplied, required this.title, required this.field, required this.type, diff --git a/lib/src/ui/columns/pluto_column_title.dart b/lib/src/ui/columns/pluto_column_title.dart index e6f735cf0..98fe8ca79 100644 --- a/lib/src/ui/columns/pluto_column_title.dart +++ b/lib/src/ui/columns/pluto_column_title.dart @@ -530,7 +530,7 @@ class _ColumnTextWidgetState extends PlutoStateWithChange<_ColumnTextWidget> { List get _children => [ if (widget.column.titleSpan != null) widget.column.titleSpan!, - if (_isFilteredList) + if (widget.column.isFilterApplied ?? _isFilteredList) WidgetSpan( alignment: PlaceholderAlignment.middle, child: IconButton( @@ -539,7 +539,8 @@ class _ColumnTextWidgetState extends PlutoStateWithChange<_ColumnTextWidget> { color: stateManager.configuration.style.iconColor, size: stateManager.configuration.style.iconSize, ), - onPressed: _handleOnPressedFilter, + onPressed: + widget.column.onPressedFilter ?? _handleOnPressedFilter, constraints: BoxConstraints( maxHeight: widget.height + (PlutoGridSettings.rowBorderWidth * 2), From 33b88b6c4b1cf4e236ecf9f78242423e255e4a7b Mon Sep 17 00:00:00 2001 From: RamKoirala1123 Date: Thu, 6 Feb 2025 14:57:45 +0545 Subject: [PATCH 24/31] added filter --- lib/src/model/pluto_column.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/model/pluto_column.dart b/lib/src/model/pluto_column.dart index 6555a1572..560517959 100644 --- a/lib/src/model/pluto_column.dart +++ b/lib/src/model/pluto_column.dart @@ -212,6 +212,7 @@ class PlutoColumn { PlutoColumn({ this.isFilterApplied, + this.onPressedFilter, required this.title, required this.field, required this.type, From fd0fc1894f364e6397f4734903f3fdc487b7871f Mon Sep 17 00:00:00 2001 From: RamKoirala1123 Date: Fri, 7 Feb 2025 10:32:31 +0545 Subject: [PATCH 25/31] revert changes --- packages/pluto_grid_export/pubspec.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/pluto_grid_export/pubspec.yaml b/packages/pluto_grid_export/pubspec.yaml index 5d332141b..92a7dfe4e 100644 --- a/packages/pluto_grid_export/pubspec.yaml +++ b/packages/pluto_grid_export/pubspec.yaml @@ -13,9 +13,7 @@ dependencies: flutter: sdk: flutter pluto_grid: - git: - url: https://github.com/RamKoirala1123/pluto_grid.git - ref: e16b779118ddc085d637cd26d6662d419a95c29d + path: ../.. csv: ^5.0.1 pdf: ^3.10.3 printing: ^5.10.4 From e97e26b1e83320bf2f7e401d6942094e182a014b Mon Sep 17 00:00:00 2001 From: Ram Koirala <69522882+RamKoirala1123@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:03:50 +0545 Subject: [PATCH 26/31] support to change header style in pdf export --- .../lib/src/pdf/generic_pdf_controller.dart | 46 +++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart index af27a87e2..331243322 100644 --- a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart +++ b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart @@ -12,6 +12,8 @@ class GenericPdfController extends PdfController { static const PdfColor baseCellColor = PdfColors.white; GenericPdfController({ + this.headerDecoration, + this.headerStyle, required this.title, required this.creator, required this.format, @@ -23,6 +25,8 @@ class GenericPdfController extends PdfController { }); final Widget? header; + final BoxDecoration? headerDecoration; + final TextStyle? headerStyle; final Widget? footer; final String title; final String creator; @@ -88,27 +92,30 @@ class GenericPdfController extends PdfController { border: null, cellAlignment: Alignment.center, // [Resolved 3.8.1] https://github.com/DavBfr/dart_pdf/pull/1033 to replace "headerDecoration" with "headerCellDecoration" - headerCellDecoration: BoxDecoration( - color: headerBackground, - border: Border.all( - color: borderColor, - width: 0.5, - ), - ), - headerDecoration: BoxDecoration( - color: headerBackground, - border: Border.all( - color: borderColor, - width: 0.5, - ), - ), + headerCellDecoration: headerDecoration ?? + BoxDecoration( + color: headerBackground, + border: Border.all( + color: borderColor, + width: 0.5, + ), + ), + headerDecoration: headerDecoration ?? + BoxDecoration( + color: headerBackground, + border: Border.all( + color: borderColor, + width: 0.5, + ), + ), headerHeight: 25, cellHeight: 15, - headerStyle: TextStyle( - color: baseTextColor, - fontSize: 7, - fontWeight: FontWeight.bold, - ), + headerStyle: headerStyle ?? + TextStyle( + color: baseTextColor, + fontSize: 7, + fontWeight: FontWeight.bold, + ), headerAlignment: Alignment.center, cellPadding: const EdgeInsets.all(1), cellStyle: const TextStyle( @@ -117,6 +124,7 @@ class GenericPdfController extends PdfController { ), oddRowDecoration: const BoxDecoration(color: oddRowColor), cellDecoration: (index, data, rowNum) => BoxDecoration( + color: PdfColors.red, border: Border.all( color: borderColor, width: .5, From 93830f44915f240e5948ea67a264e9c649e927d7 Mon Sep 17 00:00:00 2001 From: Ram Koirala <69522882+RamKoirala1123@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:34:41 +0545 Subject: [PATCH 27/31] Update generic_pdf_controller.dart --- .../lib/src/pdf/generic_pdf_controller.dart | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart index 331243322..7a08f5eef 100644 --- a/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart +++ b/packages/pluto_grid_export/lib/src/pdf/generic_pdf_controller.dart @@ -12,6 +12,8 @@ class GenericPdfController extends PdfController { static const PdfColor baseCellColor = PdfColors.white; GenericPdfController({ + this.textStyleBuilder, + this.rowCellStyles, this.headerDecoration, this.headerStyle, required this.title, @@ -34,6 +36,10 @@ class GenericPdfController extends PdfController { final List columns; final List> rows; final ThemeData? themeData; + final BoxDecoration Function(int index, dynamic data, int rowNum)? + rowCellStyles; + final TextStyle Function(int index, dynamic data, int rowNum)? + textStyleBuilder; @override PageOrientation getPageOrientation() { @@ -89,6 +95,7 @@ class GenericPdfController extends PdfController { Widget _table(List columns, List> rows) { return TableHelper.fromTextArray( + textStyleBuilder: textStyleBuilder, border: null, cellAlignment: Alignment.center, // [Resolved 3.8.1] https://github.com/DavBfr/dart_pdf/pull/1033 to replace "headerDecoration" with "headerCellDecoration" @@ -123,13 +130,13 @@ class GenericPdfController extends PdfController { fontSize: 8, ), oddRowDecoration: const BoxDecoration(color: oddRowColor), - cellDecoration: (index, data, rowNum) => BoxDecoration( - color: PdfColors.red, - border: Border.all( - color: borderColor, - width: .5, - ), - ), + cellDecoration: rowCellStyles ?? + (index, data, rowNum) => BoxDecoration( + border: Border.all( + color: borderColor, + width: .5, + ), + ), headers: columns, data: rows, ); From a0c1ee3192fab38a59cc840d9feba5dc7eb46afa Mon Sep 17 00:00:00 2001 From: Ram Koirala <69522882+RamKoirala1123@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:35:05 +0545 Subject: [PATCH 28/31] Update pluto_grid_pdf_export.dart --- .../lib/src/pdf/pluto_grid_pdf_export.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart b/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart index 94b28f1e0..7a9e5cc7f 100644 --- a/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart +++ b/packages/pluto_grid_export/lib/src/pdf/pluto_grid_pdf_export.dart @@ -29,18 +29,32 @@ class PlutoGridDefaultPdfExport extends AbstractTextExport { this.themeData, this.header, this.footer, + this.headerDecoration, + this.headerStyle, + this.rowCellStyles, + this.textStyleBuilder, }); final Widget? header; + final BoxDecoration? headerDecoration; + final TextStyle? headerStyle; final Widget? footer; final String title; final String? creator; PdfPageFormat? format; ThemeData? themeData; + final BoxDecoration Function(int index, dynamic data, int rowNum)? + rowCellStyles; + final TextStyle Function(int index, dynamic data, int rowNum)? + textStyleBuilder; @override Future export(PlutoGridStateManager state) async { return GenericPdfController( + rowCellStyles: rowCellStyles, + textStyleBuilder: textStyleBuilder, + headerDecoration: headerDecoration, + headerStyle: headerStyle, header: header, footer: footer, title: title, From 80de94e4c510d4c432f0f9cc4738c61481a0207c Mon Sep 17 00:00:00 2001 From: Ram Koirala <69522882+RamKoirala1123@users.noreply.github.com> Date: Tue, 18 Mar 2025 20:16:19 +0545 Subject: [PATCH 29/31] Update pubspec.yaml --- packages/pluto_grid_export/pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/pluto_grid_export/pubspec.yaml b/packages/pluto_grid_export/pubspec.yaml index 92a7dfe4e..2485d3352 100644 --- a/packages/pluto_grid_export/pubspec.yaml +++ b/packages/pluto_grid_export/pubspec.yaml @@ -13,7 +13,9 @@ dependencies: flutter: sdk: flutter pluto_grid: - path: ../.. + git: + url: https://github.com/ujwalbasnet1/pluto_grid.git + ref: d3011c67efa4b4d23c9c4de13e9cb30078a23807 csv: ^5.0.1 pdf: ^3.10.3 printing: ^5.10.4 From 0c703a7bdf34117d1c9d9a0b3152e2cafb715fac Mon Sep 17 00:00:00 2001 From: Ram Koirala <69522882+RamKoirala1123@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:51:23 +0545 Subject: [PATCH 30/31] Update pubspec.yaml --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 942a9fc0e..81bd0da75 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: sdk: flutter # Follows the intl version included in Flutter. # https://github.com/flutter/flutter/blob/84a1e904f44f9b0e9c4510138010edcc653163f8/packages/flutter_localizations/pubspec.yaml#L11 - intl: ^0.19.0 + intl: ^0.20.2 rxdart: ^0.27.7 collection: ^1.18.0 From 4303de518618b47da7e25140c222dbbbe1a1718d Mon Sep 17 00:00:00 2001 From: Ram Koirala <69522882+RamKoirala1123@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:52:55 +0545 Subject: [PATCH 31/31] Update pubspec.yaml --- packages/pluto_grid_export/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pluto_grid_export/pubspec.yaml b/packages/pluto_grid_export/pubspec.yaml index 2485d3352..fd8f68638 100644 --- a/packages/pluto_grid_export/pubspec.yaml +++ b/packages/pluto_grid_export/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: pluto_grid: git: url: https://github.com/ujwalbasnet1/pluto_grid.git - ref: d3011c67efa4b4d23c9c4de13e9cb30078a23807 + ref: 0c703a7bdf34117d1c9d9a0b3152e2cafb715fac csv: ^5.0.1 pdf: ^3.10.3 printing: ^5.10.4