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.

302 lines
13KB

  1. import 'package:farm_tpf/custom_model/action_form/ActionUIField.dart';
  2. import 'package:farm_tpf/custom_model/action_form/ActionUIForm.dart';
  3. import 'package:farm_tpf/data/repository/repository.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/dropdown_supply_widget.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_action_field_date.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  11. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  12. import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_area.dart';
  13. import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart';
  14. import 'package:farm_tpf/presentation/screens/actions/cubit/action_ui_cubit.dart';
  15. import 'package:farm_tpf/utils/pref.dart';
  16. import 'package:farm_tpf/utils/validators.dart';
  17. import 'package:flutter/material.dart';
  18. import 'package:flutter_bloc/flutter_bloc.dart';
  19. import 'package:get/get.dart';
  20. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  21. import 'state_management_helper/change_file_controller.dart';
  22. class ActionScreen extends StatefulWidget {
  23. final int idAction;
  24. final String title;
  25. ActionScreen({@required this.idAction, @required this.title});
  26. @override
  27. _ActionScreenState createState() => _ActionScreenState();
  28. }
  29. class _ActionScreenState extends State<ActionScreen> {
  30. final _scaffoldKey = GlobalKey<ScaffoldState>();
  31. var _formKey = GlobalKey<FormState>();
  32. var pref = LocalPref();
  33. final _executeByController = TextEditingController();
  34. DateTime executeTime = DateTime.now();
  35. List<String> filePaths = List<String>();
  36. var changeFileController = Get.put(ChangeFileController());
  37. Map<String, TextEditingController> textFieldControllers = {};
  38. Future<Null> getSharedPrefs() async {
  39. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  40. _executeByController.text = currentFullName ?? "";
  41. }
  42. @override
  43. void initState() {
  44. super.initState();
  45. getSharedPrefs();
  46. }
  47. _validateInputs() async {
  48. if (_formKey.currentState.validate()) {
  49. _formKey.currentState.save();
  50. LoadingDialog.showLoadingDialog(context);
  51. filePaths = Get.find<ChangeFileController>().newFiles;
  52. //Create request general model
  53. try {
  54. LoadingDialog.hideLoadingDialog(context);
  55. //ADD NEW
  56. //Update
  57. textFieldControllers.forEach((key, value) {
  58. print(textFieldControllers[key].text);
  59. });
  60. } catch (e) {
  61. LoadingDialog.hideLoadingDialog(context);
  62. print(e.toString());
  63. }
  64. } else {
  65. //
  66. }
  67. }
  68. Widget _btnExecuteTimePicker() {
  69. return WidgetFieldDateTimePicker(
  70. initDateTime: executeTime,
  71. onUpdateDateTime: (selectedDate) {
  72. //
  73. });
  74. }
  75. Widget _executeByField() {
  76. return TextFormField(
  77. keyboardType: TextInputType.text,
  78. decoration: InputDecoration(labelText: "Người thực hiện"),
  79. enabled: false,
  80. controller: _executeByController,
  81. onSaved: (newValue) {},
  82. );
  83. }
  84. //
  85. // GENERATE DYNAMIC FORM
  86. //
  87. Widget generateTextField(List<ActionUIField> fields) {
  88. return Container(
  89. height: fields.length * 70.0,
  90. child: ListView.separated(
  91. itemCount: fields.length,
  92. separatorBuilder: (context, index) {
  93. return SizedBox(
  94. height: 8,
  95. );
  96. },
  97. itemBuilder: (context, index) {
  98. var field = fields[index];
  99. if (field.tbControlTypeName == 'text') {
  100. return TextFormField(
  101. keyboardType: TextInputType.text,
  102. decoration: InputDecoration(labelText: field.description),
  103. controller: textFieldControllers[field.id.toString()],
  104. onSaved: (newValue) {},
  105. validator: field.isMandatory == 0
  106. ? (String value) {
  107. return Validators.validateNotNullOrEmpty(
  108. value, 'Vui lòng nhập ${field.description}');
  109. }
  110. : null,
  111. );
  112. } else if (field.tbControlTypeName == 'number') {
  113. return WidgetTextFormFieldNumber(
  114. hintValue: field.description,
  115. textController: textFieldControllers[field.id.toString()],
  116. onSaved: (newValue) {},
  117. validator: field.isMandatory == 1
  118. ? (String value) {
  119. return Validators.validNumberOrEmpty(
  120. value, 'Vui lòng nhập ${field.description}');
  121. }
  122. : null,
  123. );
  124. } else if (field.tbControlTypeName == 'textarea') {
  125. return TextFieldAreaWidget(
  126. hint: field.description,
  127. controller: textFieldControllers[field.id.toString()],
  128. onSaved: (newValue) {});
  129. } else if (field.tbControlTypeName == 'dropdown') {
  130. return DropdownSupplyWidget(
  131. value: field.description,
  132. hint:
  133. '${field.description} ${field.isMandatory == 1 ? '*' : ''}',
  134. condition: field.tbActivityExtendTypeCondition,
  135. invalidMessage: '',
  136. onPressed: () {});
  137. } else if (field.tbControlTypeName == 'date') {
  138. return FieldDateWidget(
  139. value: field.description,
  140. hint:
  141. '${field.description} ${field.isMandatory == 1 ? '*' : ''}',
  142. invalidMessage: '',
  143. onPressed: () {});
  144. } else if (field.tbControlTypeName == 'radiobutton') {
  145. return Text(field.tbControlTypeName);
  146. } else {
  147. return Text(field.tbControlTypeName);
  148. }
  149. }),
  150. );
  151. }
  152. @override
  153. Widget build(BuildContext context) => KeyboardDismisser(
  154. gestures: [
  155. GestureType.onTap,
  156. GestureType.onPanUpdateDownDirection,
  157. ],
  158. child: Scaffold(
  159. backgroundColor: Colors.white,
  160. key: _scaffoldKey,
  161. appBar: AppBarWidget(
  162. isBack: true,
  163. action: InkWell(
  164. child: Text(
  165. 'Lưu',
  166. style: TextStyle(
  167. color: Colors.red, fontWeight: FontWeight.normal),
  168. ),
  169. onTap: () {
  170. FocusScopeNode currentFocus = FocusScope.of(context);
  171. if (!currentFocus.hasPrimaryFocus) {
  172. currentFocus.unfocus();
  173. }
  174. _validateInputs();
  175. },
  176. ),
  177. ),
  178. body: KeyboardDismisser(
  179. child: MultiBlocProvider(
  180. providers: [
  181. BlocProvider<ActionUiCubit>(
  182. create: (context) =>
  183. ActionUiCubit(repository: Repository())
  184. ..getActionUIForm(widget.idAction)),
  185. BlocProvider<MediaHelperBloc>(
  186. create: (context) =>
  187. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  188. )
  189. ],
  190. child: Form(
  191. key: _formKey,
  192. child: SafeArea(
  193. child: SingleChildScrollView(
  194. child: BlocBuilder<ActionUiCubit, ActionUiState>(
  195. builder: (context, state) {
  196. if (state is ActionUiLoading) {
  197. print('loading...');
  198. return Center(child: CircularProgressIndicator());
  199. } else if (state is ActionUiSuccess) {
  200. var actionUiForm = state.item as ActionUIForm;
  201. actionUiForm.objectParameterDTOList
  202. .forEach((element) {
  203. var textEditingController =
  204. new TextEditingController();
  205. textFieldControllers.putIfAbsent(
  206. element.id.toString(),
  207. () => textEditingController);
  208. });
  209. return Column(
  210. children: [
  211. Padding(
  212. padding: const EdgeInsets.all(8.0),
  213. child: Column(
  214. children: <Widget>[
  215. Container(
  216. width: double.infinity,
  217. child: Text(
  218. "Ngày thực hiện *",
  219. style: TextStyle(
  220. color: Colors.black54,
  221. fontSize: 13.0),
  222. ),
  223. ),
  224. _btnExecuteTimePicker(),
  225. SizedBox(
  226. height: 8.0,
  227. ),
  228. generateTextField(actionUiForm
  229. .objectParameterDTOList),
  230. _executeByField(),
  231. SizedBox(
  232. height: 8.0,
  233. ),
  234. ],
  235. ),
  236. ),
  237. Container(
  238. width: double.infinity,
  239. height: 16,
  240. color: Colors.grey[200],
  241. ),
  242. BlocBuilder<MediaHelperBloc,
  243. MediaHelperState>(
  244. builder: (context, state) {
  245. if (state is MediaHelperSuccess) {
  246. return WidgetMediaPicker(
  247. currentItems: state.items,
  248. onChangeFiles: (newPathFiles,
  249. deletePathFiles) async {
  250. Get.find<ChangeFileController>()
  251. .change(newPathFiles,
  252. deletePathFiles);
  253. });
  254. } else {
  255. return Center(
  256. child: CircularProgressIndicator());
  257. }
  258. }),
  259. Padding(
  260. padding: const EdgeInsets.all(8.0),
  261. child: ButtonWidget(
  262. title: 'CẬP NHẬT',
  263. onPressed: () {
  264. FocusScopeNode currentFocus =
  265. FocusScope.of(context);
  266. if (!currentFocus.hasPrimaryFocus) {
  267. currentFocus.unfocus();
  268. }
  269. _validateInputs();
  270. }),
  271. ),
  272. ],
  273. );
  274. } else if (state is ActionUiFailure) {
  275. print('error');
  276. return Text(state.errorString);
  277. // LoadingDialog.hideLoadingDialog(context);
  278. }
  279. },
  280. ),
  281. ),
  282. )),
  283. ))));
  284. @override
  285. void dispose() {
  286. _executeByController.dispose();
  287. super.dispose();
  288. }
  289. }