2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 05:26:47 +00:00
inventree-app/lib/widget/fields.dart
2021-05-19 23:15:49 +10:00

164 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:one_context/one_context.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<File> {
static void _selectFromGallery(FormFieldState<File> field) {
_getImageFromGallery(field);
}
static void _selectFromCamera(FormFieldState<File> field) {
_getImageFromCamera(field);
}
static Future<void> _getImageFromGallery(FormFieldState<File> field) async {
File image;
await ImagePicker.pickImage(source: ImageSource.gallery).then((File img) {
image = img;
});
field.didChange(image);
}
static Future<void> _getImageFromCamera(FormFieldState<File> 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<File> state) {
return InputDecorator(
decoration: InputDecoration(
errorText: state.errorText,
labelText: required ? label + "*" : label,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
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<bool> {
CheckBoxField({String label, String hint, bool initial = false, Function onSaved}) :
super(
onSaved: onSaved,
initialValue: initial,
builder: (FormFieldState<bool> 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 I18N.of(OneContext().context).valueCannotBeEmpty;
}
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) {
final ctx = OneContext().context;
if (value.isEmpty) return I18N.of(ctx).quantityEmpty;
double quantity = double.tryParse(value);
if (quantity == null) return I18N.of(ctx).quantityInvalid;
if (quantity <= 0) return I18N.of(ctx).quantityPositive;
if ((max != null) && (quantity > max)) return "Quantity must not exceed ${max}";
return null;
},
);
}