import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:image_picker/image_picker.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'dart:async'; import 'dart:io'; // TODO - Perhaps refactor all this using flutter_form_builder - https://pub.dev/packages/flutter_form_builder /* * Form field for selecting an image file, * either from the gallery, or from the camera. */ class ImagePickerField extends FormField { static void _selectFromGallery(FormFieldState field) { _getImageFromGallery(field); } static void _selectFromCamera(FormFieldState field) { _getImageFromCamera(field); } static Future _getImageFromGallery(FormFieldState field) async { File image; await ImagePicker.pickImage(source: ImageSource.gallery).then((File img) { image = img; }); field.didChange(image); } static Future _getImageFromCamera(FormFieldState field) async { File image; await ImagePicker.pickImage(source: ImageSource.camera).then((File img) { image = img; }); field.didChange(image); } ImagePickerField(BuildContext context, {String label = "Attach Image", Function onSaved, bool required = false}) : super( onSaved: onSaved, validator: (File img) { if (required && (img == null)) { return I18N.of(context).required; } return null; }, builder: (FormFieldState state) { return InputDecorator( decoration: InputDecoration( errorText: state.errorText, labelText: required ? label + "*" : label, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ FlatButton( child: Text(I18N.of(context).selectImage), onPressed: () { _selectFromGallery(state); }, ), FlatButton( child: Text(I18N.of(context).takePicture), onPressed: () { _selectFromCamera(state); }, ) ], ), ); return ListTile( title: Text(I18N.of(context).selectImage), ); } ); } class CheckBoxField extends FormField { CheckBoxField({String label, String hint, bool initial = false, Function onSaved}) : super( onSaved: onSaved, initialValue: initial, builder: (FormFieldState state) { return CheckboxListTile( //dense: state.hasError, title: label == null ? null : Text(label), value: state.value, onChanged: state.didChange, subtitle: hint == null ? null : Text(hint), ); } ); } class StringField extends TextFormField { StringField({String label, String hint, String initial, Function onSaved, Function validator, bool allowEmpty = false, bool isEnabled = true}) : super( decoration: InputDecoration( labelText: allowEmpty ? label : label + "*", hintText: hint ), initialValue: initial, onSaved: onSaved, enabled: isEnabled, validator: (value) { if (!allowEmpty && value.isEmpty) { return "Value cannot be empty"; } if (validator != null) { return validator(value); } return null; } ); } /* * Helper class for quantity values */ class QuantityField extends TextFormField { QuantityField({String label = "", String hint = "", String initial = "", double max = null, TextEditingController controller}) : super( decoration: InputDecoration( labelText: label, hintText: hint, ), controller: controller, keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), validator: (value) { if (value.isEmpty) return "Quantity is empty"; double quantity = double.tryParse(value); if (quantity == null) return "Invalid quantity"; if (quantity <= 0) return "Quantity must be positive"; if ((max != null) && (quantity > max)) return "Quantity must not exceed ${max}"; return null; }, ); }