You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

691 lines
28KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/SuppliesUsing.dart';
  3. import 'package:farm_tpf/custom_model/action_form/ActionUIField.dart';
  4. import 'package:farm_tpf/custom_model/action_form/ActionUIForm.dart';
  5. import 'package:farm_tpf/custom_model/action_form/CommonData.dart';
  6. import 'package:farm_tpf/custom_model/action_form/RequestActivity.dart';
  7. import 'package:farm_tpf/data/api/app_exception.dart';
  8. import 'package:farm_tpf/data/repository/repository.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  11. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  12. import 'package:farm_tpf/presentation/custom_widgets/dropdown_supply_widget.dart';
  13. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  14. import 'package:farm_tpf/presentation/custom_widgets/widget_action_field_date.dart';
  15. import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart';
  16. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  17. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  18. import 'package:farm_tpf/presentation/custom_widgets/widget_radio_button.dart';
  19. import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_area.dart';
  20. import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart';
  21. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  22. import 'package:farm_tpf/presentation/screens/actions/cubit/action_ui_cubit.dart';
  23. import 'package:farm_tpf/utils/const_string.dart';
  24. import 'package:farm_tpf/utils/pref.dart';
  25. import 'package:farm_tpf/utils/validators.dart';
  26. import 'package:flutter/material.dart';
  27. import 'package:flutter/scheduler.dart';
  28. import 'package:flutter_bloc/flutter_bloc.dart';
  29. import 'package:get/get.dart';
  30. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  31. import 'package:farm_tpf/utils/formatter.dart';
  32. import 'controller/ChangeFieldInForm.dart';
  33. import 'controller/ChangeSupplyUsing.dart';
  34. import 'controller/ChangeWorker.dart';
  35. import 'dung/widget_dung_supply.dart';
  36. import 'nursery/widget_worker.dart';
  37. import 'plant/widget_plant_supply.dart';
  38. import 'spraying/widget_spraying_supply.dart';
  39. import 'state_management_helper/change_dropdown_controller.dart';
  40. import 'state_management_helper/change_file_controller.dart';
  41. import 'util_action.dart';
  42. class ActionScreen extends StatefulWidget {
  43. final bool isEdit;
  44. final int cropId;
  45. final int idAction;
  46. final String activityType;
  47. final String title;
  48. final int activityId;
  49. ActionScreen({
  50. required this.isEdit,
  51. required this.cropId,
  52. required this.idAction,
  53. required this.title,
  54. required this.activityType,
  55. required this.activityId,
  56. });
  57. @override
  58. _ActionScreenState createState() => _ActionScreenState();
  59. }
  60. class _ActionScreenState extends State<ActionScreen> {
  61. var _formKey = GlobalKey<FormState>();
  62. var pref = LocalPref();
  63. final _executeByController = TextEditingController();
  64. DateTime executeTime = DateTime.now();
  65. List<String> filePaths = <String>[];
  66. var changeFileController = Get.put(ChangeFileController());
  67. Map<String, TextEditingController> textFieldControllers = {};
  68. Map<String, String> valueObjects = {};
  69. var _requestActivity = RequestActivity();
  70. final _repository = Repository();
  71. var _actionUIForm = ActionUIForm();
  72. var _nurseryDetails = <TbNurseryDetailsDTO>[];
  73. var _supplyUsings = <SuppliesUsing>[];
  74. var _previousGroupFieldName = '';
  75. var isValidated = false;
  76. Future<Null> getSharedPrefs() async {
  77. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  78. _executeByController.text = currentFullName ?? "";
  79. }
  80. @override
  81. void initState() {
  82. super.initState();
  83. getSharedPrefs();
  84. changeFileController.initValue();
  85. }
  86. _submitForm() async {
  87. switch (widget.activityType) {
  88. case 'ACTIVE_TYPE_NURSERY':
  89. if (Get.find<ChangeFieldFormSupply>().isChanged ?? false) {
  90. Utils.showDialog(
  91. title: 'Thông tin người thực hiện chưa cập nhật',
  92. message: 'Bạn có muốn cập nhật',
  93. textConfirm: 'Tiếp tục',
  94. textCancel: 'Xem lại',
  95. onConfirm: () {
  96. Get.back();
  97. _validateInputs();
  98. });
  99. } else {
  100. _validateInputs();
  101. }
  102. break;
  103. case 'ACTIVE_TYPE_PLANTING':
  104. case 'ACTIVE_TYPE_FERTILIZE':
  105. case 'ACTIVE_TYPE_SPRAYING_PESTICIDES':
  106. if (Get.find<ChangeFieldFormSupply>().isChanged ?? false) {
  107. Utils.showDialogConfirmSupply(onConfirm: () {
  108. Get.back();
  109. _validateInputs();
  110. });
  111. } else {
  112. _validateInputs();
  113. }
  114. break;
  115. default:
  116. _validateInputs();
  117. break;
  118. }
  119. }
  120. _validateInputs() async {
  121. if (_formKey.currentState!.validate()) {
  122. _formKey.currentState!.save();
  123. try {
  124. LoadingDialog.showLoadingDialog(context);
  125. filePaths = Get.find<ChangeFileController>().newFiles ?? [];
  126. //Create request general model
  127. _requestActivity
  128. ..tbActivityTypeId = widget.idAction
  129. ..tbCropId = widget.cropId;
  130. if ((_actionUIForm.activityExtendTypeDTOList ?? []).isNotEmpty) {
  131. _requestActivity..externalTable = _actionUIForm?.activityExtendTypeDTOList?.first?.externalTable ?? '';
  132. }
  133. filePaths = Get.find<ChangeFileController>().newFiles ?? [];
  134. textFieldControllers.forEach((key, value) {
  135. valueObjects[key] = textFieldControllers[key]?.text ?? '';
  136. });
  137. //tbObjectUpdateDTOList
  138. var _objectPrameters = <TbObjectUpdateDTO>[];
  139. if (widget.isEdit) {
  140. // Edit
  141. if (_requestActivity.tbObjectUpdateDTOList != null) {
  142. _requestActivity.tbObjectUpdateDTOList?.forEach((element) {
  143. print(valueObjects[element.tbObjectParameterId.toString()]);
  144. var updateValue = '';
  145. if (Validators.stringNotNullOrEmpty(valueObjects[element.tbObjectParameterId.toString()] ?? '')) {
  146. updateValue = valueObjects[element.tbObjectParameterId.toString()] ?? '';
  147. } else {
  148. updateValue = element.index ?? '';
  149. }
  150. var objectUpdate = TbObjectUpdateDTO()
  151. ..id = element.id
  152. ..tbObjectParameterId = element.tbObjectParameterId
  153. ..index = updateValue;
  154. _objectPrameters.add(objectUpdate);
  155. });
  156. _requestActivity.tbObjectUpdateDTOList = _objectPrameters;
  157. }
  158. } else {
  159. //Add new
  160. valueObjects.forEach((key, value) {
  161. var objectUpdate = TbObjectUpdateDTO()
  162. ..tbObjectParameterId = int.tryParse(key)
  163. ..index = value;
  164. _objectPrameters.add(objectUpdate);
  165. });
  166. _requestActivity.tbObjectUpdateDTOList = _objectPrameters;
  167. }
  168. //CHECK NURSERY
  169. if (widget.activityType == 'ACTIVE_TYPE_NURSERY') {
  170. _requestActivity.tbNurseryDetailsDTOList = _nurseryDetails;
  171. } else if (widget.activityType == 'ACTIVE_TYPE_PLANTING' ||
  172. widget.activityType == 'ACTIVE_TYPE_FERTILIZE' ||
  173. widget.activityType == 'ACTIVE_TYPE_SPRAYING_PESTICIDES') {
  174. _requestActivity.tbSuppliesUsingDetailsDTOs = _supplyUsings;
  175. }
  176. //delete images
  177. _requestActivity.deletedImages = Get.find<ChangeFileController>().deleteFiles;
  178. //convert data to json
  179. var activityCommonData = jsonEncode(_requestActivity.toJson()).toString();
  180. print(activityCommonData);
  181. if (widget.activityId < 0) {
  182. //ADD New
  183. _repository.createActionCommon((data) {
  184. LoadingDialog.hideLoadingDialog(context);
  185. Get.back(result: 'ok');
  186. Utils.showSnackBarSuccess(message: label_add_success);
  187. }, (error) {
  188. LoadingDialog.hideLoadingDialog(context);
  189. Utils.showSnackBarError(message: AppException.handleError(error));
  190. }, activityType: widget.activityType, activityData: activityCommonData, filePaths: filePaths);
  191. } else {
  192. //UPDATE
  193. _repository.updateActionCommon((data) {
  194. LoadingDialog.hideLoadingDialog(context);
  195. Get.back(result: 'ok');
  196. Utils.showSnackBarSuccess(message: label_update_success);
  197. }, (error) {
  198. LoadingDialog.hideLoadingDialog(context);
  199. Utils.showSnackBarError(message: AppException.handleError(error));
  200. }, activityType: widget.activityType, activityData: activityCommonData, filePaths: filePaths);
  201. }
  202. //ADD NEW
  203. //Update
  204. } catch (e) {
  205. LoadingDialog.hideLoadingDialog(context);
  206. print(e.toString());
  207. }
  208. } else {
  209. //
  210. setState(() {
  211. isValidated = true;
  212. });
  213. }
  214. }
  215. Widget _btnExecuteTimePicker() {
  216. return WidgetFieldDateTimePicker(
  217. initDateTime: executeTime,
  218. onUpdateDateTime: (selectedDate) {
  219. _requestActivity.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
  220. });
  221. }
  222. Widget _executeByField() {
  223. return TextFormField(
  224. keyboardType: TextInputType.text,
  225. decoration: InputDecoration(labelText: "Người thực hiện"),
  226. enabled: false,
  227. controller: _executeByController,
  228. onSaved: (newValue) {},
  229. );
  230. }
  231. //
  232. // GENERATE DYNAMIC FORM
  233. //
  234. Widget groupName(String name) {
  235. if (_previousGroupFieldName == name || !Validators.stringNotNullOrEmpty(name)) {
  236. return SizedBox();
  237. } else {
  238. _previousGroupFieldName = name ?? '';
  239. return Container(
  240. child: Row(
  241. children: [
  242. Container(
  243. width: 24,
  244. height: 0.5,
  245. color: Colors.green,
  246. ),
  247. Text(' ${name ?? ''} '),
  248. Expanded(
  249. child: Container(
  250. width: 5,
  251. height: 0.5,
  252. color: Colors.green,
  253. ),
  254. ),
  255. ],
  256. ),
  257. );
  258. }
  259. }
  260. Widget generateField(List<ActionUIField> fields) {
  261. return Wrap(
  262. children: [
  263. ListView.separated(
  264. shrinkWrap: true,
  265. physics: NeverScrollableScrollPhysics(),
  266. itemCount: fields.length,
  267. separatorBuilder: (context, index) {
  268. return SizedBox(
  269. height: 8,
  270. );
  271. },
  272. itemBuilder: (context, index) {
  273. var field = fields[index];
  274. if (field.tbControlTypeName == 'text') {
  275. return Column(
  276. children: [
  277. groupName(field.groupName ?? ''),
  278. TextFormField(
  279. keyboardType: TextInputType.text,
  280. decoration: InputDecoration(
  281. labelText: ((field.isMandatory ?? false) ?? false) ? '${field.description} *' : '${field.description}',
  282. hintText: field.description),
  283. controller: textFieldControllers[field.id.toString()],
  284. onSaved: (newValue) {},
  285. validator: ((field.isMandatory ?? false) ?? false)
  286. ? (String? value) {
  287. return Validators.validateNotNullOrEmpty(
  288. value ?? '',
  289. 'Vui lòng nhập ${field.description}',
  290. );
  291. }
  292. : null,
  293. ),
  294. ],
  295. );
  296. } else if (field.tbControlTypeName == 'number') {
  297. return Column(
  298. children: [
  299. groupName(field.groupName ?? ''),
  300. WidgetTextFormFieldNumber(
  301. hintValue: field.description ?? '',
  302. labelText: ((field.isMandatory ?? false) ?? false) ? '${field.description} *' : '${field.description}',
  303. textController: textFieldControllers[field.id.toString()] ?? TextEditingController(),
  304. onSaved: (newValue) {},
  305. validator: ((field.isMandatory ?? false) ?? false)
  306. ? (String? value) {
  307. return Validators.validNumberOrEmpty(
  308. value ?? '',
  309. 'Vui lòng nhập ${field.description}',
  310. );
  311. }
  312. : null,
  313. ),
  314. ],
  315. );
  316. } else if (field.tbControlTypeName == 'textarea') {
  317. return Column(
  318. children: [
  319. groupName(field.groupName ?? ''),
  320. TextFieldAreaWidget(
  321. hint: field.description ?? '',
  322. labelText: (field.isMandatory ?? false) ? '${field.description} *' : '${field.description}',
  323. controller: textFieldControllers[field.id.toString()] ?? TextEditingController(),
  324. onSaved: (newValue) {},
  325. validator: (field.isMandatory ?? false)
  326. ? (String? value) {
  327. return Validators.validateNotNullOrEmpty(
  328. value ?? '',
  329. 'Vui lòng nhập ${field.description}',
  330. );
  331. }
  332. : null,
  333. ),
  334. ],
  335. );
  336. } else if (field.tbControlTypeName == 'dropdown') {
  337. return Column(
  338. children: [
  339. groupName(field.groupName ?? ''),
  340. DropdownSupplyWidget(
  341. titleName: field.description ?? '',
  342. tbSupply: field.tbActivityExtendTypeExternalTable ?? '',
  343. tag: field.name ?? '',
  344. value: field.description,
  345. hint: '${field.description} ${(field.isMandatory ?? false) ? '*' : ''}',
  346. condition: field.tbActivityExtendTypeCondition ?? '',
  347. invalidMessage: '',
  348. onPressed: (commonData) {
  349. valueObjects[field.id.toString()] = commonData.id.toString();
  350. }),
  351. ],
  352. );
  353. } else if (field.tbControlTypeName == 'radiobutton') {
  354. return Column(
  355. children: [
  356. groupName(field.groupName ?? ''),
  357. RadioButtonWidget(
  358. tag: field.name ?? '',
  359. condition: field.tbActivityExtendTypeCondition ?? '',
  360. supply: field.tbActivityExtendTypeExternalTable ?? '',
  361. onPressed: (commonData) {
  362. valueObjects[field.id.toString()] = commonData.id.toString();
  363. },
  364. ),
  365. ],
  366. );
  367. } else if (field.tbControlTypeName == 'date') {
  368. return Column(
  369. children: [
  370. groupName(field.groupName ?? ''),
  371. FieldDateWidget(
  372. tag: field.name ?? '',
  373. isValidated: isValidated,
  374. value: field.description,
  375. hint: '${field.description} ${(field.isMandatory ?? false) ? '*' : ''}',
  376. onPressed: (selectedDate) {
  377. valueObjects[field.id.toString()] = selectedDate.convertLocalDateTimeToStringUtcDateTime();
  378. },
  379. validator: (field.isMandatory ?? false)
  380. ? (String? value) {
  381. return Validators.validateNotNullOrEmpty(value ?? '', 'Vui lòng nhập ${field.description}');
  382. }
  383. : null,
  384. ),
  385. ],
  386. );
  387. } else {
  388. return Container();
  389. }
  390. })
  391. ],
  392. );
  393. }
  394. //
  395. // GENERATE SUPPLY
  396. //
  397. Widget generateSupply(String activityType) {
  398. switch (activityType) {
  399. case 'ACTIVE_TYPE_NURSERY':
  400. return WidgetWorker(onChangeWorkers: (nurseryDetails) {
  401. _nurseryDetails = nurseryDetails;
  402. });
  403. break;
  404. case 'ACTIVE_TYPE_PLANTING':
  405. return Column(
  406. children: [
  407. Container(
  408. width: double.infinity,
  409. height: 16,
  410. color: Colors.grey[200],
  411. ),
  412. WidgetPlantSupply(
  413. currentItems: [],
  414. onChangeSupplies: (value) {
  415. _supplyUsings = value;
  416. }),
  417. ],
  418. );
  419. break;
  420. case 'ACTIVE_TYPE_FERTILIZE':
  421. return Column(
  422. children: [
  423. Container(
  424. width: double.infinity,
  425. height: 16,
  426. color: Colors.grey[200],
  427. ),
  428. WidgetDungSupply(
  429. currentItems: [],
  430. onChangeSupplies: (value) {
  431. _supplyUsings = value;
  432. }),
  433. ],
  434. );
  435. break;
  436. case 'ACTIVE_TYPE_SPRAYING_PESTICIDES':
  437. return Column(
  438. children: [
  439. Container(
  440. width: double.infinity,
  441. height: 16,
  442. color: Colors.grey[200],
  443. ),
  444. WidgetSprayingSupply(
  445. currentItems: [],
  446. onChangeSupplies: (value) {
  447. _supplyUsings = value;
  448. }),
  449. ],
  450. );
  451. break;
  452. default:
  453. return Container();
  454. break;
  455. }
  456. }
  457. void showDataWhenEdit(BuildContext context) {
  458. //Show media
  459. try {
  460. if (Validators.stringNotNullOrEmpty(_requestActivity.media ?? '')) {
  461. BlocProvider.of<MediaHelperBloc>(context).add(
  462. ChangeListMedia(
  463. items: UtilAction.convertFilePathToMedia(
  464. _requestActivity.media ?? '',
  465. ),
  466. ),
  467. );
  468. }
  469. } catch (e) {
  470. print(e);
  471. }
  472. SchedulerBinding.instance.addPostFrameCallback((_) {
  473. if (widget.activityType == 'ACTIVE_TYPE_PLANTING' ||
  474. widget.activityType == 'ACTIVE_TYPE_FERTILIZE' ||
  475. widget.activityType == 'ACTIVE_TYPE_SPRAYING_PESTICIDES') {
  476. //list supply
  477. Get.find<ChangeSupplyUsing>().changeInitList(_requestActivity.tbSuppliesUsingDetailsDTOs ?? []);
  478. } else if (widget.activityType == 'ACTIVE_TYPE_NURSERY') {
  479. //list nursery
  480. Get.find<ChangeWorker>().changeInitList(_requestActivity.tbNurseryDetailsDTOList ?? []);
  481. }
  482. });
  483. //Show value textfield
  484. if (_requestActivity.tbObjectUpdateDTOList != null) {
  485. print(textFieldControllers.keys.toList());
  486. _requestActivity.tbObjectUpdateDTOList?.forEach((element) {
  487. if (element.tbObjectParameterDTO?.tbControlTypeName == 'text' || element.tbObjectParameterDTO?.tbControlTypeName == 'textarea') {
  488. SchedulerBinding.instance.addPostFrameCallback((_) {
  489. textFieldControllers[element.tbObjectParameterId.toString()]?.text = element.index ?? '';
  490. });
  491. } else if (element.tbObjectParameterDTO?.tbControlTypeName == 'number') {
  492. SchedulerBinding.instance.addPostFrameCallback((_) {
  493. textFieldControllers[element.tbObjectParameterId.toString()]?.text = element.index?.formatStringToStringDecimal() ?? '';
  494. });
  495. } else {
  496. SchedulerBinding.instance.addPostFrameCallback((_) {
  497. if (element.tbObjectParameterDTO?.tbControlTypeName == 'dropdown' ||
  498. element.tbObjectParameterDTO?.tbControlTypeName?.toLowerCase() == 'radiobutton') {
  499. var dropdownValueName = '';
  500. if ((element.tbObjectParameterDTO?.tbActivityExtendTypeDropDownDTOList ?? []).isNotEmpty ||
  501. element.tbObjectParameterDTO?.tbActivityExtendTypeDropDownDTOList != null) {
  502. element.tbObjectParameterDTO?.tbActivityExtendTypeDropDownDTOList?.forEach((dropdownData) {
  503. if (dropdownData.id == int.tryParse(element.index ?? '-1')) {
  504. dropdownValueName = dropdownData.name ?? '';
  505. }
  506. });
  507. }
  508. var commonData = CommonData()
  509. ..id = int.tryParse(element.index ?? '-1')
  510. ..name = dropdownValueName;
  511. Get.find<ChangeDropdownController>(tag: element.tbObjectParameterDTO?.name).change(commonData);
  512. } else if (element.tbObjectParameterDTO?.tbControlTypeName == 'date') {
  513. Get.find<ChangeDateTimePicker>(tag: element.tbObjectParameterDTO?.name).change(
  514. element.index?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
  515. );
  516. }
  517. });
  518. }
  519. });
  520. } else {
  521. //
  522. }
  523. }
  524. @override
  525. Widget build(BuildContext context) => KeyboardDismisser(
  526. gestures: [
  527. GestureType.onTap,
  528. GestureType.onPanUpdateDownDirection,
  529. ],
  530. child: Scaffold(
  531. backgroundColor: Colors.white,
  532. appBar: AppBarWidget(
  533. isBack: true,
  534. action: InkWell(
  535. child: Text(
  536. 'Lưu',
  537. style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
  538. ),
  539. onTap: () {
  540. FocusScopeNode currentFocus = FocusScope.of(context);
  541. if (!currentFocus.hasPrimaryFocus) {
  542. currentFocus.unfocus();
  543. }
  544. _submitForm();
  545. },
  546. ),
  547. ),
  548. body: MultiBlocProvider(
  549. providers: [
  550. BlocProvider<ActionUiCubit>(
  551. create: (context) => ActionUiCubit(repository: Repository())
  552. ..getActionUIForm(
  553. actionId: widget.idAction, actionType: widget.activityType, isEdit: widget.isEdit, activityId: widget.activityId)),
  554. BlocProvider<MediaHelperBloc>(
  555. create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
  556. )
  557. ],
  558. child: Form(
  559. key: _formKey,
  560. child: SafeArea(
  561. child: BlocBuilder<ActionUiCubit, ActionUiState>(
  562. builder: (context, state) {
  563. if (state is ActionUiLoading) {
  564. print('loading...');
  565. return Center(
  566. child: LoadingListPage(),
  567. );
  568. } else if (state is ActionUiSuccess) {
  569. _actionUIForm = state.actionUIForm ?? ActionUIForm();
  570. _requestActivity = state.activityDetail ?? RequestActivity();
  571. //CREATE UI
  572. _actionUIForm.objectParameterDTOList?.forEach((element) {
  573. //generate controller
  574. if (element.tbControlTypeName == 'text' ||
  575. element.tbControlTypeName == 'number' ||
  576. element.tbControlTypeName == 'textarea') {
  577. var textEditingController = new TextEditingController();
  578. textFieldControllers.putIfAbsent(element.id.toString(), () => textEditingController);
  579. }
  580. // generate value each parameter
  581. valueObjects.putIfAbsent(element.id.toString(), () => '');
  582. });
  583. //SHOW EDIT DATA
  584. if (widget.isEdit) {
  585. showDataWhenEdit(context);
  586. }
  587. return SingleChildScrollView(
  588. child: Column(
  589. children: [
  590. Padding(
  591. padding: const EdgeInsets.all(8.0),
  592. child: Column(
  593. children: <Widget>[
  594. Container(
  595. width: double.infinity,
  596. child: Text(
  597. "Ngày thực hiện *",
  598. style: TextStyle(color: Colors.black54, fontSize: 13.0),
  599. ),
  600. ),
  601. _btnExecuteTimePicker(),
  602. SizedBox(
  603. height: 8.0,
  604. ),
  605. generateField(_actionUIForm.objectParameterDTOList ?? []),
  606. _executeByField(),
  607. SizedBox(
  608. height: 8.0,
  609. ),
  610. ],
  611. ),
  612. ),
  613. generateSupply(widget.activityType),
  614. Container(
  615. width: double.infinity,
  616. height: 16,
  617. color: Colors.grey[200],
  618. ),
  619. BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
  620. if (state is MediaHelperSuccess) {
  621. return WidgetMediaPicker(
  622. currentItems: state.items,
  623. onChangeFiles: (newPathFiles, deletePathFiles) async {
  624. Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
  625. });
  626. } else {
  627. return Center(child: CircularProgressIndicator());
  628. }
  629. }),
  630. Padding(
  631. padding: const EdgeInsets.all(8.0),
  632. child: ButtonWidget(
  633. title: 'CẬP NHẬT',
  634. onPressed: () {
  635. FocusScopeNode currentFocus = FocusScope.of(context);
  636. if (!currentFocus.hasPrimaryFocus) {
  637. currentFocus.unfocus();
  638. }
  639. _submitForm();
  640. }),
  641. ),
  642. ],
  643. ),
  644. );
  645. } else if (state is ActionUiFailure) {
  646. return Center(child: Text(state.errorString));
  647. }
  648. return Container();
  649. },
  650. ),
  651. )),
  652. )));
  653. @override
  654. void dispose() {
  655. _executeByController.dispose();
  656. textFieldControllers.forEach((key, value) {
  657. textFieldControllers[key]?.dispose();
  658. });
  659. super.dispose();
  660. }
  661. }