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.

746 lines
29KB

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