Advertisement
Guest User

flutter form with future builder

a guest
Jul 8th, 2021
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 16.87 KB | None | 0 0
  1. import 'package:flutter/material.dart';
  2. import 'package:kanboard/src/models/column_model.dart';
  3. import 'package:kanboard/src/models/task_model.dart';
  4. import 'package:kanboard/src/models/user_model.dart';
  5. import 'package:kanboard/src/providers/column_provider.dart';
  6. import 'package:kanboard/src/providers/tag_provider.dart';
  7. import 'package:kanboard/src/providers/user_provider.dart';
  8. import 'package:kanboard/src/utils/utils.dart';
  9. import 'package:kanboard/src/utils/widgets_utils.dart';
  10. import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
  11. import 'dart:ui';
  12. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  13.  
  14. import 'package:intl/intl.dart';
  15.  
  16. class TaskFormPage extends StatefulWidget {
  17.   @override
  18.   _TaskFormPageState createState() => _TaskFormPageState();
  19. }
  20.  
  21. class _TaskFormPageState extends State<TaskFormPage> {
  22.   final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  23.   final userProvider = new UserProvider();
  24.   final columnProvider = new ColumnProvider();
  25.   final tagProvider = new TagProvider();
  26.  
  27.   TaskModel task = new TaskModel();
  28.   List<UserModel> _users = [];
  29.   List<ColumnModel> _columns = [];
  30.  
  31.   String _title = '';
  32.   String _description = '';
  33.   ColorSwatch _tempTaskColor;
  34.   ColorSwatch _mainColor = Colors.blue;
  35.   String _colorId = '';
  36.   String _creatorId = '0';
  37.   String _ownerId = '0';
  38.   String _columnId = '0';
  39.   String _startDue = '';
  40.   String _dateDue = '';
  41.   String _score = ''; // COMPLEXITY
  42.   String _priority = '0';
  43.   List<String> _tags = [];
  44.  
  45.   bool createTask = true;
  46.  
  47.   TextEditingController _titleFieldController = new TextEditingController();
  48.   TextEditingController _descriptionFieldController =
  49.       new TextEditingController();
  50.   TextEditingController _timeEstimatedFieldController =
  51.       new TextEditingController();
  52.   TextEditingController _startDueFieldController = new TextEditingController();
  53.   TextEditingController _dateDueFieldController = new TextEditingController();
  54.   TextEditingController _scoreFieldController = new TextEditingController();
  55.  
  56.   @override
  57.   void initState() {
  58.     super.initState();
  59.     // this should not be done in build method.
  60.     // _users = await _loadUsers();
  61.   }
  62.  
  63.   @override
  64.   Widget build(BuildContext context) {
  65.     final Map taskArgs = ModalRoute.of(context).settings.arguments;
  66.     if (taskArgs != null) {
  67.       task = taskArgs['task'];
  68.       createTask = false;
  69.     }
  70.  
  71.     return Scaffold(
  72.       appBar: normalAppBar(createTask ? 'New Task' : task.title),
  73.       body: ListView(
  74.         padding: EdgeInsets.only(top: 10.0, bottom: 80.0),
  75.         children: [_taskForm()],
  76.       ),
  77.     );
  78.   }
  79.  
  80.   Widget _taskForm() {
  81.     return Form(
  82.       key: _formKey,
  83.       child: Column(
  84.         children: [
  85.           Container(
  86.             margin: EdgeInsets.only(top: 15, left: 20),
  87.             child: Text(
  88.               'Some Subtitle',
  89.               style: TextStyle(
  90.                 fontSize: 16,
  91.                 fontWeight: FontWeight.w600,
  92.               ),
  93.             ),
  94.           ),
  95.           _titleField(),
  96.           SizedBox(height: 15.0),
  97.           _descriptionField(),
  98.           SizedBox(height: 15.0),
  99.           _creatorSelect(),
  100.           SizedBox(height: 10.0),
  101.           _ownerSelect(),
  102.           SizedBox(height: 10.0),
  103.           _columnSelect(),
  104.           SizedBox(height: 10.0),
  105.           _timeEstimatedField(),
  106.           SizedBox(height: 30.0),
  107.           _taskColorPicker(),
  108.           SizedBox(height: 15.0),
  109.           Row(
  110.             children: [
  111.               new Flexible(
  112.                 child: _dateDueSelect(context),
  113.               ),
  114.               new Flexible(
  115.                 child: _datestartSelect(context),
  116.               ),
  117.             ],
  118.           ),
  119.           SizedBox(height: 15.0),
  120.           Row(
  121.             children: [
  122.               new Flexible(
  123.                 child: _prioritySelect(),
  124.               ),
  125.               new Flexible(
  126.                 child: _scoreField(),
  127.               ),
  128.             ],
  129.           ),
  130.           // _dateDueSelect(context),
  131.           // SizedBox(height: 15.0),
  132.           // _datestartSelect(context),
  133.           SizedBox(height: 40.0),
  134.           _submitButton()
  135.         ],
  136.       ),
  137.     );
  138.   }
  139.  
  140.   Widget _titleField() {
  141.     return Container(
  142.       padding: EdgeInsets.symmetric(horizontal: 20.0),
  143.       child: TextFormField(
  144.           controller: _titleFieldController,
  145.           decoration: InputDecoration(
  146.             hintText: 'Super Title',
  147.             labelText: 'Title',
  148.             suffixIcon:
  149.                 Icon(Icons.swap_horizontal_circle_outlined, color: Colors.blue),
  150.           ),
  151.           onChanged: (value) {},
  152.           validator: (value) {
  153.             if (value == null || value.isEmpty) {
  154.               return 'Please type a title';
  155.             }
  156.             return null;
  157.           }),
  158.     );
  159.   }
  160.  
  161.   Widget _descriptionField() {
  162.     return Container(
  163.       padding: EdgeInsets.symmetric(horizontal: 20.0),
  164.       child: TextFormField(
  165.         keyboardType: TextInputType.multiline,
  166.         maxLines: null,
  167.         controller: _descriptionFieldController,
  168.         decoration: InputDecoration(
  169.           hintText: 'The quick brown fox jumped over...',
  170.           labelText: 'Description',
  171.           suffixIcon: Icon(Icons.library_books_outlined, color: Colors.blue),
  172.         ),
  173.         onChanged: (value) {},
  174.       ),
  175.     );
  176.   }
  177.  
  178.   Widget _creatorSelect() {
  179.     return FutureBuilder(
  180.       future: userProvider.getUsers(),
  181.       builder: (BuildContext context, AsyncSnapshot snapshot) {
  182.         List<DropdownMenuItem<String>> usernameList = [];
  183.         if (snapshot.hasData) {
  184.           usernameList.add(DropdownMenuItem<String>(
  185.               child: Text('Select Creator'), value: 0.toString()));
  186.           _users = snapshot.data;
  187.         } else {
  188.           usernameList.add(DropdownMenuItem<String>(
  189.               child: Text('Loading..'), value: 0.toString()));
  190.         }
  191.         _users.forEach((user) {
  192.           usernameList.add(DropdownMenuItem<String>(
  193.               child: Container(
  194.                 child: Text(
  195.                   user.name,
  196.                 ),
  197.               ),
  198.               value: user.id.toString()));
  199.         });
  200.         return Container(
  201.           // margin: EdgeInsets.only(left: 40.0),
  202.           padding: EdgeInsets.symmetric(horizontal: 20.0),
  203.           child: DropdownButtonFormField(
  204.             icon: Padding(
  205.               padding: const EdgeInsets.only(right: 12),
  206.               child: Icon(Icons.person_pin_circle_outlined, color: Colors.blue),
  207.             ),
  208.             items: usernameList,
  209.             value: _creatorId,
  210.             decoration: InputDecoration(helperText: 'Optional'),
  211.             onChanged: (newValue) {
  212.               _creatorId = newValue;
  213.             },
  214.           ),
  215.         );
  216.       },
  217.     );
  218.   }
  219.  
  220.   Widget _ownerSelect() {
  221.     return FutureBuilder(
  222.       future: userProvider.getUsers(),
  223.       builder: (BuildContext context, AsyncSnapshot snapshot) {
  224.         List<DropdownMenuItem<String>> usernameList = [];
  225.         if (snapshot.hasData) {
  226.           usernameList.add(DropdownMenuItem<String>(
  227.               child: Text('Select Owner'), value: 0.toString()));
  228.           _users = snapshot.data;
  229.         } else {
  230.           usernameList.add(DropdownMenuItem<String>(
  231.               child: Text('Loading..'), value: 0.toString()));
  232.         }
  233.         _users.forEach((user) {
  234.           usernameList.add(DropdownMenuItem<String>(
  235.               child: Container(
  236.                 child: Text(
  237.                   user.name,
  238.                 ),
  239.               ),
  240.               value: user.id.toString()));
  241.         });
  242.         return Container(
  243.           // margin: EdgeInsets.only(left: 40.0),
  244.           padding: EdgeInsets.symmetric(horizontal: 20.0),
  245.           child: DropdownButtonFormField(
  246.             icon: Padding(
  247.               padding: const EdgeInsets.only(right: 12),
  248.               child: Icon(Icons.person, color: Colors.blue),
  249.             ),
  250.             items: usernameList,
  251.             value: _ownerId,
  252.             decoration: InputDecoration(helperText: 'Optional'),
  253.             onChanged: (newValue) {
  254.               _ownerId = newValue;
  255.             },
  256.           ),
  257.         );
  258.       },
  259.     );
  260.   }
  261.  
  262.   Widget _columnSelect() {
  263.     return FutureBuilder(
  264.       future: columnProvider.getColumns(task.projectId),
  265.       builder: (BuildContext context, AsyncSnapshot snapshot) {
  266.         List<DropdownMenuItem<String>> columnList = [];
  267.         if (snapshot.hasData) {
  268.           columnList.add(DropdownMenuItem<String>(
  269.               child: Text('Select Column'), value: 0.toString()));
  270.           _columns = snapshot.data;
  271.         } else {
  272.           columnList.add(DropdownMenuItem<String>(
  273.               child: Text('Loading..'), value: 0.toString()));
  274.         }
  275.         _columns.forEach((column) {
  276.           columnList.add(DropdownMenuItem<String>(
  277.               child: Container(
  278.                 child: Text(
  279.                   column.title,
  280.                 ),
  281.               ),
  282.               value: column.id.toString()));
  283.         });
  284.         return Container(
  285.           // margin: EdgeInsets.only(left: 40.0),
  286.           padding: EdgeInsets.symmetric(horizontal: 20.0),
  287.           child: DropdownButtonFormField(
  288.             icon: Padding(
  289.               padding: const EdgeInsets.only(right: 12),
  290.               child: Icon(Icons.view_column, color: Colors.blue),
  291.             ),
  292.             items: columnList,
  293.             value: _columnId,
  294.             decoration: InputDecoration(helperText: 'Optional'),
  295.             onChanged: (newValue) {
  296.               _columnId = newValue;
  297.             },
  298.           ),
  299.         );
  300.       },
  301.     );
  302.   }
  303.  
  304.   Widget _timeEstimatedField() {
  305.     return Container(
  306.       padding: EdgeInsets.symmetric(horizontal: 20.0),
  307.       child: TextFormField(
  308.         controller: _timeEstimatedFieldController,
  309.         keyboardType: TextInputType.number,
  310.         decoration: InputDecoration(
  311.           hintText: 'Hours (Integer)',
  312.           labelText: 'Original Estimate',
  313.           suffixIcon: Icon(Icons.watch_later_outlined, color: Colors.blue),
  314.         ),
  315.         onChanged: (value) {},
  316.       ),
  317.     );
  318.   }
  319.  
  320.   Widget _submitButton() {
  321.     return RaisedButton(
  322.         child: Container(
  323.           padding: EdgeInsets.symmetric(horizontal: 50.0, vertical: 15.0),
  324.           child: Text('Create'),
  325.         ),
  326.         shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),
  327.         elevation: 0.0,
  328.         color: Colors.blue,
  329.         textColor: Colors.white,
  330.         onPressed: () {
  331.           if (_formKey.currentState.validate()) {
  332.             _createSubtask(context);
  333.           } else {
  334.             mostrarAlerta(context, 'Please fill required fields');
  335.           }
  336.         });
  337.   }
  338.  
  339.   _createSubtask(BuildContext context) async {
  340.     final String _subtaskTitle = _titleFieldController.text;
  341.     final String _subtaskTimeEstimated = _timeEstimatedFieldController.text;
  342.  
  343.     // int newSubtaskId = await subtaskProvider.createSubtask(int.parse(task.id),
  344.     //     _subtaskTitle, int.parse(_subtaskUserId), _subtaskTimeEstimated);
  345.  
  346.     // if (newSubtaskId > 0) {
  347.     //   setState(() {
  348.     //     Navigator.pop(context);
  349.     //   });
  350.     // } else {
  351.     //   mostrarAlerta(context, 'Something went Wront!');
  352.     // }
  353.   }
  354.  
  355.   void _openDialog(String title, Widget content) {
  356.     showDialog(
  357.       context: context,
  358.       builder: (context) {
  359.         return AlertDialog(
  360.           contentPadding: const EdgeInsets.all(6.0),
  361.           title: Text(title),
  362.           content: content,
  363.           actions: [
  364.             TextButton(
  365.               child: Text('CANCEL'),
  366.               onPressed: Navigator.of(context).pop,
  367.             ),
  368.           ],
  369.         );
  370.       },
  371.     );
  372.   }
  373.  
  374.   void _openMainColorPicker() async {
  375.     _openDialog(
  376.       "Tag Color",
  377.       Container(
  378.         height: 200.0,
  379.         child: MaterialColorPicker(
  380.             selectedColor: _mainColor,
  381.             colors: TaskModel().getTaskColorsList(),
  382.             allowShades: false,
  383.             onMainColorChange: (color) {
  384.               _tempTaskColor = color;
  385.               _colorId = TaskModel().getTaskColorName(color);
  386.               Navigator.of(context).pop();
  387.               setState(() => _mainColor = _tempTaskColor);
  388.             }),
  389.       ),
  390.     );
  391.   }
  392.  
  393.   _taskColorPicker() {
  394.     return Container(
  395.       padding: EdgeInsets.symmetric(horizontal: 20.0),
  396.       child: Row(
  397.         children: [
  398.           Text('Task Color'),
  399.           SizedBox(width: 20.0),
  400.           GestureDetector(
  401.             child: Container(
  402.               height: 40.0,
  403.               width: 40.0,
  404.               decoration: BoxDecoration(
  405.                   borderRadius: BorderRadius.circular(20.0), color: _mainColor),
  406.             ),
  407.             onTap: _openMainColorPicker,
  408.           ),
  409.         ],
  410.       ),
  411.     );
  412.   }
  413.  
  414.   Widget _dateDueSelect(BuildContext context) {
  415.     return Padding(
  416.       padding: const EdgeInsets.only(left: 20.0, right: 10.0),
  417.       child: TextFormField(
  418.         enableInteractiveSelection: false,
  419.         controller: _dateDueFieldController,
  420.         decoration: InputDecoration(
  421.           hintText: 'Due Date',
  422.           labelText: 'Due Date',
  423.           suffixIcon: Icon(Icons.calendar_today_outlined, color: Colors.blue),
  424.         ),
  425.         validator: (value) {
  426.           if (value == null || value.isEmpty) {
  427.             return 'Debe especificar fecha de entrega';
  428.           }
  429.           return null;
  430.         },
  431.         onTap: () {
  432.           FocusScope.of(context).requestFocus(new FocusNode());
  433.           _dateDueDateTime(context);
  434.         },
  435.       ),
  436.     );
  437.   }
  438.  
  439.   Widget _datestartSelect(BuildContext context) {
  440.     return Padding(
  441.       padding: const EdgeInsets.only(left: 10.0, right: 20.0),
  442.       child: TextFormField(
  443.         enableInteractiveSelection: false,
  444.         controller: _dateDueFieldController,
  445.         decoration: InputDecoration(
  446.           hintText: 'Start Date',
  447.           labelText: 'Start Date',
  448.           suffixIcon: Icon(Icons.calendar_today, color: Colors.blue),
  449.         ),
  450.         validator: (value) {
  451.           if (value == null || value.isEmpty) {
  452.             return 'Debe especificar fecha de entrega';
  453.           }
  454.           return null;
  455.         },
  456.         onTap: () {
  457.           FocusScope.of(context).requestFocus(new FocusNode());
  458.           _datestartDateTime(context);
  459.         },
  460.       ),
  461.     );
  462.   }
  463.  
  464.   _datestartDateTime(BuildContext context) async {
  465.     DatePicker.showDateTimePicker(
  466.       context,
  467.       showTitleActions: true,
  468.       minTime: new DateTime(2018),
  469.       maxTime: new DateTime(2025),
  470.       onConfirm: (date) {
  471.         _dateDue = _dateDueFieldController.text =
  472.             DateFormat('dd/MM/yy HH:mm', 'en_US').format(date);
  473.         _dateDueFieldController.text =
  474.             DateFormat('dd/MM/yy HH:mm', 'en_US').format(date);
  475.         print(_dateDue);
  476.       },
  477.       currentTime: DateTime.now(),
  478.       locale: LocaleType.en,
  479.     );
  480.   }
  481.  
  482.   _dateDueDateTime(BuildContext context) async {
  483.     DatePicker.showDateTimePicker(
  484.       context,
  485.       showTitleActions: true,
  486.       minTime: new DateTime(2018),
  487.       maxTime: new DateTime(2025),
  488.       onConfirm: (date) {
  489.         _dateDue = _dateDueFieldController.text =
  490.             DateFormat('dd/MM/yy HH:mm', 'en_US').format(date);
  491.         _dateDueFieldController.text =
  492.             DateFormat('dd/MM/yy HH:mm', 'en_US').format(date);
  493.         print(_dateDue);
  494.       },
  495.       currentTime: DateTime.now(),
  496.       locale: LocaleType.en,
  497.     );
  498.   }
  499.  
  500.   Widget _prioritySelect() {
  501.     return Container(
  502.       // margin: EdgeInsets.only(left: 40.0),
  503.       padding: EdgeInsets.only(left: 20.0, right: 10.0),
  504.       child: DropdownButtonFormField(
  505.         icon: Padding(
  506.           padding: const EdgeInsets.only(right: 12),
  507.           child: Icon(Icons.star_border, color: Colors.blue),
  508.         ),
  509.         items: [
  510.           DropdownMenuItem<String>(
  511.               child: Text('Priority'), value: 0.toString()),
  512.           DropdownMenuItem<String>(child: Text('1'), value: 1.toString()),
  513.           DropdownMenuItem<String>(child: Text('2'), value: 2.toString()),
  514.           DropdownMenuItem<String>(child: Text('3'), value: 3.toString()),
  515.         ],
  516.         value: _priority,
  517.         decoration: InputDecoration(labelText: 'Priority'),
  518.         onChanged: (newValue) {
  519.           _priority = newValue;
  520.         },
  521.       ),
  522.     );
  523.   }
  524.  
  525.   // COMPLEXITY
  526.   Widget _scoreField() {
  527.     return Container(
  528.       padding: EdgeInsets.only(left: 10.0, right: 20.0, top: 5.0),
  529.       child: TextFormField(
  530.         controller: _scoreFieldController,
  531.         keyboardType: TextInputType.number,
  532.         decoration: InputDecoration(
  533.           labelText: 'Complexity',
  534.           suffixIcon: Icon(Icons.handyman_rounded, color: Colors.blue),
  535.         ),
  536.         onChanged: (value) {},
  537.       ),
  538.     );
  539.   }
  540. }
  541.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement