Closed MalikSamiAwan closed 1 month ago
Hi @MalikSamiAwan ,
As requested, we have provided a sample demonstrating the column insertion and deletion functionality, along with the column resizing feature. The attached sample serves as a reference for your review. In this example, the solution allows for both column resizing and the dynamic addition and removal of columns while preserving the current column widths. This approach avoids unnecessarily rebuilding the entire data grid and ensures that the resizing feature works seamlessly with dynamic column operations. Please review sample for further details and adapt it to suit your specific requirements.
Regards, Abinesh P
Thankyou very much issue is resolved
In my syncfusion grid datasource if declare columns like this: List get columns => [] ;
means as a getter than column resizing works fine
but in my use case i want column resizing and i also have feature to add/remove columns but if i try to do that than that does not work i have to make columns in variable like this List columns = [];
in what way i can achieve both means i want column resizing as well as columns insertion/deletion
CODE:
`
SyncfusionHomePage( initialData: [ Employee(id: 1, name: 'John Doe', salary: 60000, jobTitle: 'Manager', joiningDate: '2022-01-15'), Employee(id: 2, name: 'Jane Doe', salary: 55000, jobTitle: 'Developer', joiningDate: '2021-06-10'), Employee(id: 3, name: 'Mark Smith', salary: 75000, jobTitle: 'Director', joiningDate: '2020-03-25'), Employee(id: 4, name: 'Sara Williams', salary: 50000, jobTitle: 'Designer', joiningDate: '2019-08-05'), Employee(id: 5, name: 'Paul Brown', salary: 45000, jobTitle: 'QA', joiningDate: '2018-11-30'), ],),
import 'package:flutter/material.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart';
class SyncfusionHomePage extends StatefulWidget { final List initialData;
SyncfusionHomePage({Key? key, required this.initialData}) : super(key: key);
@override _SyncfusionHomePageState createState() => _SyncfusionHomePageState(); }
class _SyncfusionHomePageState extends State {
late CustomDataSource _dataSource;
Color currentColor = Colors.amber;
String searchQuery = '';
@override void initState() { super.initState(); _dataSource = CustomDataSource(initialData: widget.initialData); }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('DataGrid with Dynamic Rows and Columns'), ), body: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Expanded( child: SfDataGrid( source: _dataSource, columnWidthMode: ColumnWidthMode.fill, allowEditing: true, allowColumnsResizing: true, columns: _dataSource.columns, columnResizeMode: ColumnResizeMode.onResizeEnd, onColumnResizeUpdate: (ColumnResizeUpdateDetails details) { print(details.width); setState(() {
}
void _showContextMenu(Offset globalPosition, int rowIndex, int columnIndex) { final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
}
void _selectCellColor(int rowIndex, int columnIndex) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text("Select Cell Color"), content: SingleChildScrollView( child: BlockPicker( pickerColor: currentColor, onColorChanged: (Color color) { setState(() { currentColor = color; _dataSource.updateCellStyle(rowIndex, columnIndex, backgroundColor: currentColor); }); }, availableColors: [ Colors.red, Colors.green, Colors.blue, Colors.yellow, Colors.purple, Colors.orange, ], ), ), actions: [ TextButton( child: const Text("Close"), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, ); }
void _selectCellTextStyle(int rowIndex, int columnIndex) { String selectedFontFamily = 'Roboto'; showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text("Select Font Style"), content: DropdownButton(
value: selectedFontFamily,
onChanged: (String? newFont) {
setState(() {
selectedFontFamily = newFont!;
_dataSource.updateCellStyle(rowIndex, columnIndex, fontFamily: selectedFontFamily);
});
},
items: ['Roboto', 'Arial', 'Courier', 'Times New Roman', 'Verdana']
.map<DropdownMenuItem>((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
actions: [
TextButton(
child: const Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
void _selectCellFontSize(int rowIndex, int columnIndex) { double selectedFontSize = _dataSource.getCellStyle(rowIndex, columnIndex).fontSize; showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text("Select Cell Font Size"), content: DropdownButton(
value: selectedFontSize,
onChanged: (double? newSize) {
setState(() {
selectedFontSize = newSize!;
_dataSource.updateCellStyle(rowIndex, columnIndex, fontSize: selectedFontSize);
});
},
items: [12.0, 14.0, 16.0, 18.0, 20.0, 22.0, 24.0]
.map<DropdownMenuItem>((double value) {
return DropdownMenuItem(
value: value,
child: Text(value.toString()),
);
}).toList(),
),
actions: [
TextButton(
child: const Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
class CustomDataSource extends DataGridSource { List _rows = [];
Map<String, CellStyle> _cellStyles = {}; // Store cell styles
List get columns => [
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Text('ID'),
),
),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Text('Name'),
),
),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Text('Salary'),
),
),
GridColumn(
columnName: 'jobTitle',
label: Container(
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Text('Job Title'),
),
),
GridColumn(
columnName: 'joiningDate',
label: Container(
padding: EdgeInsets.all(8),
alignment: Alignment.center,
child: Text('Joining Date'),
),
),
];
CustomDataSource({required List initialData}) {
_rows = initialData.map((employee) {
return DataGridRow(cells: [
DataGridCell(columnName: 'id', value: employee.id),
DataGridCell(columnName: 'name', value: employee.name),
DataGridCell(columnName: 'salary', value: employee.salary),
DataGridCell(columnName: 'jobTitle', value: employee.jobTitle),
DataGridCell(columnName: 'joiningDate', value: employee.joiningDate),
]);
}).toList();
}
@override List get rows => _rows;
@override DataGridRowAdapter buildRow(DataGridRow row) { return DataGridRowAdapter( cells: row.getCells().asMap().entries.map((entry) {
int index = entry.key;
DataGridCell cell = entry.value;
}
void updateCellStyle(int rowIndex, int columnIndex, {Color? backgroundColor, double? fontSize, FontWeight? fontWeight, String? fontFamily}) { String key = '${rowIndex}_$columnIndex'; final currentStyle = _cellStyles[key] ?? CellStyle(); _cellStyles[key] = currentStyle.copyWith( backgroundColor: backgroundColor ?? currentStyle.backgroundColor, fontSize: fontSize ?? currentStyle.fontSize, fontWeight: fontWeight ?? currentStyle.fontWeight, fontFamily: fontFamily ?? currentStyle.fontFamily, ); notifyListeners(); }
CellStyle getCellStyle(int rowIndex, int columnIndex) { String key = '${rowIndex}_$columnIndex'; return _cellStyles[key] ?? CellStyle(); }
void insertRow(int index) { _rows.insert( index, DataGridRow(cells: [ DataGridCell(columnName: 'id', value: 0),
DataGridCell(columnName: 'name', value: ''),
DataGridCell(columnName: 'salary', value: 0),
DataGridCell(columnName: 'jobTitle', value: ''),
DataGridCell(columnName: 'joiningDate', value: ''),
]),
);
notifyListeners();
}
void deleteRowAt(int index) { if (index >= 0 && index < _rows.length) { _rows.removeAt(index); notifyListeners(); } }
void insertColumn(int index) { final columnName = 'NewColumn${columns.length}'; columns.insert( index, GridColumn( columnName: columnName, label: Container( padding: EdgeInsets.all(8), alignment: Alignment.center, child: Text(columnName), ), ), );
}
void deleteColumnAt(int index) { if (index >= 0 && index < columns.length && columns.length > 2) { // Ensuring minimum columns String columnNameToBeRemoved = columns[index].columnName; columns.removeAt(index); for (var row in _rows) { row.getCells().removeWhere( (cell) => cell.columnName == columnNameToBeRemoved); } notifyListeners(); } }
void updateDataSource(int index, DataGridRow row) { _rows[index] = row; notifyListeners(); } }
class CellStyle { final Color backgroundColor; final double fontSize; final FontWeight fontWeight; final String fontFamily;
CellStyle({ this.backgroundColor = Colors.white, this.fontSize = 14.0, this.fontWeight = FontWeight.normal, this.fontFamily = 'Roboto', });
CellStyle copyWith({ Color? backgroundColor, double? fontSize, FontWeight? fontWeight, String? fontFamily, }) { return CellStyle( backgroundColor: backgroundColor ?? this.backgroundColor, fontSize: fontSize ?? this.fontSize, fontWeight: fontWeight ?? this.fontWeight, fontFamily: fontFamily ?? this.fontFamily, ); } }
class Employee { final int id; final String name; final int salary; final String jobTitle; final String joiningDate;
Employee({ required this.id, required this.name, required this.salary, required this.jobTitle, required this.joiningDate, }); }
`