ModelField<T extends AbstractModel<ID>, ID> constructor

ModelField<T extends AbstractModel<ID>, ID>({
  1. String? labelPrefix,
  2. String? label,
  3. Widget? labelWidget,
  4. ModelEditingController<T, ID>? controller,
  5. FormFieldValidator<T>? validator,
  6. TextAlign textAlign = TextAlign.start,
  7. FormFieldSetter<T?>? onSaved,
  8. T? initialValue,
  9. bool enabled = true,
  10. AutovalidateMode autoValidateMode = AutovalidateMode.disabled,
  11. TextInputAction? textInputAction,
  12. ValueChanged<String?>? onFieldSubmitted,
  13. EdgeInsets scrollPadding = const EdgeInsets.all(20),
  14. bool filled = false,
  15. Color? fillColor,
  16. Widget routeBuilder(
    1. BuildContext context
    )?,
  17. Future<bool> beforeRoute(
    1. BuildContext context,
    2. T? model
    )?,
  18. Future<T?> acceptChange(
    1. T? model
    )?,
  19. dynamic tapToVisualize(
    1. T model
    )?,
  20. InputDecoration? decoration,
  21. EdgeInsets padding = const EdgeInsets.all(8),
  22. bool clearOnCancel = true,
  23. String? hintText,
  24. EdgeInsets? contentPadding,
  25. Widget? prefix,
  26. Widget? prefixIcon,
  27. Widget? suffix,
  28. Widget? suffixIcon,
  29. int? sizeExtraSmall,
  30. int? sizeSmall,
  31. int? sizeMedium,
  32. int? sizeLarge,
  33. int? sizeExtraLarge,
  34. double? minHeight,
  35. Key? key,
})

Implementation

ModelField({
  String? labelPrefix,
  String? label,
  Widget? labelWidget,
  this.controller,
  FormFieldValidator<T>? validator,
  TextAlign textAlign = TextAlign.start,
  super.onSaved,
  T? initialValue,
  super.enabled,
  AutovalidateMode autoValidateMode = AutovalidateMode.disabled,
  // TODO(edufolly): onChanged
  TextInputAction? textInputAction,
  ValueChanged<String?>? onFieldSubmitted,
  EdgeInsets scrollPadding = const EdgeInsets.all(20),
  bool filled = false,
  Color? fillColor,
  Widget Function(BuildContext context)? routeBuilder,
  Future<bool> Function(BuildContext context, T? model)? beforeRoute,
  Future<T?> Function(T? model)? acceptChange,
  Function(T model)? tapToVisualize,
  InputDecoration? decoration,
  EdgeInsets padding = const EdgeInsets.all(8),
  bool clearOnCancel = true,
  String? hintText,
  EdgeInsets? contentPadding,
  Widget? prefix,
  Widget? prefixIcon,
  Widget? suffix,
  Widget? suffixIcon,
  super.sizeExtraSmall,
  super.sizeSmall,
  super.sizeMedium,
  super.sizeLarge,
  super.sizeExtraLarge,
  super.minHeight,
  super.key,
})  : assert(
        initialValue == null || controller == null,
        'initialValue or controller must be null.',
      ),
      assert(
        label == null || labelWidget == null,
        'label or labelWidget must be null.',
      ),
      super(
        initialValue: controller != null ? controller.model : initialValue,
        validator: enabled ? validator : (_) => null,
        autovalidateMode: autoValidateMode,
        builder: (FormFieldState<T?> field) {
          _ModelFieldState<T, ID> state = field as _ModelFieldState<T, ID>;

          InputDecoration effectiveDecoration = (decoration ??
                  InputDecoration(
                    border: const OutlineInputBorder(),
                    filled: filled,
                    fillColor: fillColor,
                    label: labelWidget,
                    labelText: (labelPrefix?.isEmpty ?? true)
                        ? label
                        : '$labelPrefix - $label',
                    counterText: '',
                    hintText: hintText,
                    contentPadding: contentPadding,
                    prefix: prefix,
                    prefixIcon: prefixIcon,
                    suffix: suffix,
                    suffixIcon: suffixIcon,
                  ))
              .applyDefaults(Theme.of(field.context).inputDecorationTheme)
              .copyWith(
                suffixIcon: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    if (enabled && routeBuilder != null)
                      const FaIcon(FontAwesomeIcons.magnifyingGlass)
                    else
                      tapToVisualize != null
                          ? const FaIcon(FontAwesomeIcons.chevronRight)
                          : Container(width: 0),
                  ],
                ),
              );

          return Padding(
            padding: padding,
            child: TextField(
              controller: state._effectiveController,
              decoration: effectiveDecoration.copyWith(
                errorText: enabled ? field.errorText : null,
                enabled: enabled,
              ),
              keyboardType: TextInputType.datetime,
              minLines: 1,
              textAlign: textAlign,
              enabled: enabled,
              textInputAction: textInputAction,
              onSubmitted: onFieldSubmitted,
              autocorrect: false,
              enableSuggestions: false,
              scrollPadding: scrollPadding,
              style: enabled
                  ? null
                  : Theme.of(field.context).textTheme.titleMedium!.copyWith(
                        color: Theme.of(field.context).disabledColor,
                      ),
              readOnly: true,
              onTap: enabled && routeBuilder != null
                  ? () async {
                      try {
                        if (beforeRoute != null) {
                          bool go = await beforeRoute(
                            state.context,
                            state.value,
                          );
                          if (!go) {
                            return;
                          }
                        }

                        T? selected = await Navigator.of(state.context).push(
                          MaterialPageRoute<T>(
                            builder: routeBuilder,
                          ),
                        );

                        try {
                          if (acceptChange != null) {
                            selected = await acceptChange(selected);
                          }
                          if (selected != null ||
                              (selected == null && clearOnCancel)) {
                            state._effectiveController.model = selected;
                            state.didChange(selected);
                          }
                        } on Exception catch (e, s) {
                          if (kDebugMode) {
                            print(e);
                            print(s);
                          }
                          await FollyDialogs.dialogMessage(
                            context: state.context,
                            message: e.toString(),
                          );
                        }
                      } on Exception catch (e, s) {
                        if (kDebugMode) {
                          print(e);
                          print(s);
                        }
                      }
                    }
                  : tapToVisualize != null && state.value != null
                      ? () => Navigator.of(state.context).push(
                            MaterialPageRoute<dynamic>(
                              builder: (BuildContext context) =>
                                  tapToVisualize(state.value!),
                            ),
                          )
                      : null,
            ),
          );
        },
      );