거래처 datatable을 만들고 싶음.
국내 사이트에선 정보가 없고, 해외 사이트에선 밑단 service가 아닌 screen에서 처리하는 샘플만 봄.
그래서 4시간 동안 서치하고 변경한 정보를 공유 차 올림.
pub
syncfusion_flutter_datagrid: ^20.2.46
Customers
import 'package:flutter/material.dart';
import 'package:simple/datagrid/customer_datagrid.dart';
import 'package:simple/model/customer/customer_model.dart';
import 'package:simple/services/customer/customer_service.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
class Customers extends StatefulWidget {
const Customers({Key? key}) : super(key: key);
@override
State<Customers> createState() => _CustomersState();
}
class _CustomersState extends State<Customers> {
late final CustomerService customerService;
late final CustomerDatagrid customerDatagrid;
@override
Widget build(BuildContext context) {
//https://stackoverflow.com/questions/49986303/flutter-how-to-add-a-header-row-to-a-listview
//https://api.flutter.dev/flutter/material/DataTable-class.html
//https://stackoverflow.com/questions/60644375/flutter-datatable-multiline-wrapping-and-centering
//https://www.syncfusion.com/kb/12646/how-to-populate-flutter-datatable-sfdatagrid-with-json-api
customerService = CustomerService(context);
return Scaffold(
body: FutureBuilder(
future: generateCustomerList(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
return _getData(snapshot);
}),
);
}
Future generateCustomerList() async {
List<CustomerModel> customerModelList = await customerService.getCustomerList() as List<CustomerModel>;
customerDatagrid = CustomerDatagrid(customerModelList);
customerDatagrid.customerModelList = customerModelList;
}
Widget _getData(AsyncSnapshot<dynamic> snapshot) {
return snapshot.connectionState == ConnectionState.done
? SfDataGrid(
source: customerDatagrid,
columns: customerDatagrid.getColumns())
: const Center(
child: CircularProgressIndicator(
strokeWidth: 3,
),
);
}
}
CustomerService
import 'package:flutter/material.dart';
import 'package:simple/commons/text/text_information.dart';
import 'package:simple/model/customer/customer_model.dart';
import 'package:simple/model/http/http_header_model.dart';
import 'package:simple/utils/dialog/custom_dialog.dart';
import 'package:simple/utils/dialog/dialog_action.dart';
import 'package:simple/utils/http/http_request.dart';
import 'package:simple/utils/http/http_url.dart';
import 'package:simple/model/customer/customer_model_list.dart';
class CustomerService {
final BuildContext context;
CustomerService(this.context);
void add(CustomerModel customerModel) {
CustomDialog.confirm(context, title: '저장 확인', content: '입력한 정보로 거래처를 저장하시겠습니까?'
, positive: DialogAction('확인', () => _add(customerModel))
, negative: DialogAction('취소', () => true));
}
bool _add(CustomerModel customerModel) {
HttpHeaderModel httpHeaderModel = HttpHeaderModel();
httpHeaderModel.transactionNumber = "1000";
final result = HttpRequest.fetchPost<CustomerModel>(HttpUrl.customerAdd, httpHeaderModel, customerModel);
result.then((value) => {
if(value == null) {
CustomDialog.confirm(context, title: '거래처 등록', content: TextInformation.serverConnectionFailed, positive: DialogAction('확인', () => true))
} else if(!value.status) {
CustomDialog.confirm(context, title: '거래처 등록', content: '거래처 등록에 실패하였습니다. 사유 : ${value?.error.errorMessage}', positive: DialogAction('확인', () => true))
} else {
if(value.status) {
CustomDialog.confirm(context, title: '거래처 등록', content: '거래처 등록에 완료되었습니다.', positive: DialogAction('확인', () => true)),
}
}
});
return true;
}
Future getCustomerList() async {
HttpHeaderModel httpHeaderModel = HttpHeaderModel();
httpHeaderModel.transactionNumber = "1000";
final result = HttpRequest.fetchPostNoBody(HttpUrl.customerList, httpHeaderModel);
CustomerModelList customerModelList = CustomerModelList(customerModelList: <CustomerModel>[]);
var bb = await result.then((value) => {
if(value == null) {
CustomDialog.confirm(context, title: '거래처 리스트', content: TextInformation.serverConnectionFailed, positive: DialogAction('확인', () => true))
} else if(!value.status) {
CustomDialog.confirm(context, title: '거래처 리스트', content: '거래처 리스트를 불러오는데 실패했습니다. 사유 : ${value?.error.errorMessage}', positive: DialogAction('확인', () => true))
} else {
if(value.status) {
customerModelList = CustomerModelList.fromJson(value.data),
}
}
});
return customerModelList.customerModelList;
}
bool _addConfirmDialog() {
return true;
}
}
CustomerDatagrid
import 'package:flutter/material.dart';
import 'package:simple/model/customer/customer_model.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
//import 'package:intl/intl.dart';
class CustomerDatagrid extends DataGridSource {
//https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid-class.html
//https://pub.dev/packages/syncfusion_flutter_datagrid
//https://help.syncfusion.com/flutter/datagrid/getting-started
CustomerDatagrid(this.customerModelList) {
buildDataGridRow();
}
List<DataGridRow> dataGridRows = [];
List<CustomerModel> customerModelList = [];
@override
List<DataGridRow> get rows => dataGridRows;
void buildDataGridRow() {
dataGridRows = customerModelList.map<DataGridRow>((dataGridRow) {
return DataGridRow(cells: [
DataGridCell<String>(columnName: 'name', value: dataGridRow.name),
DataGridCell<String>(
columnName: 'number', value: dataGridRow.number),
DataGridCell<String>(
columnName: 'registrationNumber', value: dataGridRow.registrationNumber),
DataGridCell<String>(
columnName: 'conditions', value: dataGridRow.conditions),
DataGridCell<String>(columnName: 'type', value: dataGridRow.type),
]);
}).toList(growable: false);
}
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(cells: [
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
child: Text(
row.getCells()[0].value.toString(),
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
child: Text(
row.getCells()[1].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
child: Text(
row.getCells()[2].value.toString(),
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
child: Text(
//DateFormat('MM/dd/yyyy').format(row.getCells()[3].value).toString(),
row.getCells()[3].value.toString(),
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
child: Text(
row.getCells()[4].value.toString(),
overflow: TextOverflow.ellipsis,
),
),
]);
}
List<GridColumn> getColumns() {
return <GridColumn>[
GridColumn(
columnName: 'name',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text('name',))),
GridColumn(
columnName: 'number',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text('number'))),
GridColumn(
columnName: 'registrationNumber',
width: 120,
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text('registrationNumber'))),
GridColumn(
columnName: 'conditions',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text('conditions'))),
GridColumn(
columnName: 'type',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: const Text('type'))),
];
}
}
테스트 용으로 서버에서 받아온 데이터라 정상적인 데이터 입력 시 매핑됨.
* 매핑 변경
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((dataGridCell) {
return Container(
alignment: (dataGridCell.columnName == 'id' ||
dataGridCell.columnName == 'salary')
? Alignment.centerRight
: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
dataGridCell.value.toString(),
overflow: TextOverflow.ellipsis,
));
}).toList());
}
List<GridColumn> getColumns() {
return <GridColumn>[
customGridColumn.getCustomGridColumn("name", "상호", alignment: Alignment.center),
customGridColumn.getCustomGridColumn("number", "사업자번호", alignment: Alignment.center),
customGridColumn.getCustomGridColumn("registrationNumber", "법인 등록번호", alignment: Alignment.center, width: 150),
customGridColumn.getCustomGridColumn("conditions", "업태"),
customGridColumn.getCustomGridColumn("ceoName", "종목"),
customGridColumn.getCustomGridColumn("conditions", "대표자 성명"),
customGridColumn.getCustomGridColumn("address", "회사 주소"),
customGridColumn.getCustomGridColumn("phoneNumber", "전화번호", width: 120),
customGridColumn.getCustomGridColumn("faxNumber", "팩스번호"),
customGridColumn.getCustomGridColumn("cellNumber", "휴대폰"),
customGridColumn.getCustomGridColumn("email", "이메일"),
customGridColumn.getCustomGridColumn("bankName", "은행명"),
customGridColumn.getCustomGridColumn("bankOwnerName", "예금주"),
customGridColumn.getCustomGridColumn("bankAccountNumber", "계좌번호"),
];
}
class CustomGridColumn {
//https://flutterrdart.com/dart-optional-default-parameters-function/
GridColumn getCustomGridColumn(String columnName, String text, { Alignment alignment = Alignment.center, int width = -1 }) {
double? columnWidth = width > 0 ? width as double : null;
if(columnWidth != null) {
return _getCustomGridColumnWidth(columnName, text, alignment, columnWidth);
} else {
return GridColumn(
columnName: columnName,
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: alignment,
child: Text(text),
)
);
}
}
GridColumn _getCustomGridColumnWidth(String columnName, String text, Alignment alignment, double width) {
return GridColumn(
columnName: columnName,
width: width,
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: alignment,
child: Text(text),
)
);
}
}
'Flutter' 카테고리의 다른 글
06. Flutter Future build 이벤트 방지 (0) | 2022.09.19 |
---|---|
05. Flutter build 종료 후 이벤트 (0) | 2022.09.16 |
04. Flutter 상태 저장 shared_preferences (0) | 2022.09.16 |
02. Flutter Dio 사용법 (0) | 2022.08.28 |
01. 플러터 설치 (0) | 2021.07.26 |