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.

305 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
  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
  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. titleName: field.description ?? '',
  132. tbSupply: field.tbActivityExtendTypeExternalTable ?? '',
  133. tag: field.name,
  134. value: field.description,
  135. hint: '${field.description} ${field.isMandatory ? '*' : ''}',
  136. condition: field.tbActivityExtendTypeCondition,
  137. invalidMessage: '',
  138. onPressed: (commonData) {
  139. print(commonData.name);
  140. });
  141. } else if (field.tbControlTypeName == 'date') {
  142. return FieldDateWidget(
  143. value: field.description,
  144. hint: '${field.description} ${field.isMandatory ? '*' : ''}',
  145. invalidMessage: '',
  146. onPressed: () {});
  147. } else if (field.tbControlTypeName == 'radiobutton') {
  148. return Text(field.tbControlTypeName);
  149. } else {
  150. return Text(field.tbControlTypeName);
  151. }
  152. }),
  153. );
  154. }
  155. @override
  156. Widget build(BuildContext context) => KeyboardDismisser(
  157. gestures: [
  158. GestureType.onTap,
  159. GestureType.onPanUpdateDownDirection,
  160. ],
  161. child: Scaffold(
  162. backgroundColor: Colors.white,
  163. key: _scaffoldKey,
  164. appBar: AppBarWidget(
  165. isBack: true,
  166. action: InkWell(
  167. child: Text(
  168. 'Lưu',
  169. style: TextStyle(
  170. color: Colors.red, fontWeight: FontWeight.normal),
  171. ),
  172. onTap: () {
  173. FocusScopeNode currentFocus = FocusScope.of(context);
  174. if (!currentFocus.hasPrimaryFocus) {
  175. currentFocus.unfocus();
  176. }
  177. _validateInputs();
  178. },
  179. ),
  180. ),
  181. body: KeyboardDismisser(
  182. child: MultiBlocProvider(
  183. providers: [
  184. BlocProvider<ActionUiCubit>(
  185. create: (context) =>
  186. ActionUiCubit(repository: Repository())
  187. ..getActionUIForm(widget.idAction)),
  188. BlocProvider<MediaHelperBloc>(
  189. create: (context) =>
  190. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  191. )
  192. ],
  193. child: Form(
  194. key: _formKey,
  195. child: SafeArea(
  196. child: SingleChildScrollView(
  197. child: BlocBuilder<ActionUiCubit, ActionUiState>(
  198. builder: (context, state) {
  199. if (state is ActionUiLoading) {
  200. print('loading...');
  201. return Center(child: CircularProgressIndicator());
  202. } else if (state is ActionUiSuccess) {
  203. var actionUiForm = state.item as ActionUIForm;
  204. actionUiForm.objectParameterDTOList
  205. .forEach((element) {
  206. var textEditingController =
  207. new TextEditingController();
  208. textFieldControllers.putIfAbsent(
  209. element.id.toString(),
  210. () => textEditingController);
  211. });
  212. return Column(
  213. children: [
  214. Padding(
  215. padding: const EdgeInsets.all(8.0),
  216. child: Column(
  217. children: <Widget>[
  218. Container(
  219. width: double.infinity,
  220. child: Text(
  221. "Ngày thực hiện *",
  222. style: TextStyle(
  223. color: Colors.black54,
  224. fontSize: 13.0),
  225. ),
  226. ),
  227. _btnExecuteTimePicker(),
  228. SizedBox(
  229. height: 8.0,
  230. ),
  231. generateTextField(actionUiForm
  232. .objectParameterDTOList),
  233. _executeByField(),
  234. SizedBox(
  235. height: 8.0,
  236. ),
  237. ],
  238. ),
  239. ),
  240. Container(
  241. width: double.infinity,
  242. height: 16,
  243. color: Colors.grey[200],
  244. ),
  245. BlocBuilder<MediaHelperBloc,
  246. MediaHelperState>(
  247. builder: (context, state) {
  248. if (state is MediaHelperSuccess) {
  249. return WidgetMediaPicker(
  250. currentItems: state.items,
  251. onChangeFiles: (newPathFiles,
  252. deletePathFiles) async {
  253. Get.find<ChangeFileController>()
  254. .change(newPathFiles,
  255. deletePathFiles);
  256. });
  257. } else {
  258. return Center(
  259. child: CircularProgressIndicator());
  260. }
  261. }),
  262. Padding(
  263. padding: const EdgeInsets.all(8.0),
  264. child: ButtonWidget(
  265. title: 'CẬP NHẬT',
  266. onPressed: () {
  267. FocusScopeNode currentFocus =
  268. FocusScope.of(context);
  269. if (!currentFocus.hasPrimaryFocus) {
  270. currentFocus.unfocus();
  271. }
  272. _validateInputs();
  273. }),
  274. ),
  275. ],
  276. );
  277. } else if (state is ActionUiFailure) {
  278. print('error');
  279. return Text(state.errorString);
  280. // LoadingDialog.hideLoadingDialog(context);
  281. }
  282. },
  283. ),
  284. ),
  285. )),
  286. ))));
  287. @override
  288. void dispose() {
  289. _executeByController.dispose();
  290. super.dispose();
  291. }
  292. }