MetaForm.ofMModel constructor

MetaForm.ofMModel(
  1. BuildContext context, {
  2. String? id,
  3. JsonPath? embedPath,
  4. required MBaseModel? model,
  5. MSchemaRef? ref,
  6. MetadataOverrides? overrides,
  7. IMSchemaDefinition? schema,
  8. bool saveModel = true,
  9. FormController? parentForm,
  10. SubmitHook? submitHook,
  11. FormValidator? validator,
  12. Future<Result> overrideHandler(
    1. BuildContext context,
    2. FormController form,
    3. FormSubmitResult result
    )?,
  13. bool attachForm = true,
  14. bool inheritForm = false,
  15. Set? ignoredPaths,
  16. bool? skipIfUnmodified,
  17. List<MetaFormSection> sections = const [],
  18. MetaFormBuilderFn? builder,
  19. List<MetaPropertyHandler> extraHandlers = const [],
  20. Map<String, dynamic>? scope,
})

Implementation

MetaForm.ofMModel(
  BuildContext context, {

  /// A unique identifier for the form.  Typically, the form's key will be the id of the [model] instance, or
  /// the [ref], but sometimes you need a unique key, for example if you have two embedded add forms of the same type.
  String? id,

  /// If this form is a subform, this basePath will relocate
  /// all the child fields
  JsonPath? embedPath,
  required MBaseModel? model,
  MSchemaRef? ref,
  MetadataOverrides? overrides,
  IMSchemaDefinition? schema,
  bool saveModel = true,
  this.parentForm,
  SubmitHook? submitHook,
  FormValidator? validator,

  /// Intercepts the submit handler, in case this form should submit its value somewhere other
  /// than the standard data endpoint
  this.overrideHandler,

  /// Whether this form should be attached as a subform to any parent form that exists in scope, either [parentForm]
  /// or a provided [Provider] form that's in scope.  Attaching to the parent form means that this form will validate
  /// and submit when the parent form submits.
  this.attachForm = true,

  /// If inheritForm is true, then this [MetaForm] will bind directly to the parent form, instead of creating a new
  /// subform that's nested inside the parent form
  this.inheritForm = false,
  Set? ignoredPaths,
  this.skipIfUnmodified,
  this.sections = const [],
  this.builder,
  List<MetaPropertyHandler> extraHandlers = const [],
  Map<String, dynamic>? scope,
})  : assert(
          (id ?? (model is MEntity ? model.id : '') ?? ref ?? model?.mtype) != null, "Must provide a valid type or identifier"),
      name = "${ref ?? model?.mtype}",
      ref = ref ?? model?.mtype,
      submitHook = inheritForm == true
          ? submitHook
          : submitHook ??
              (saveModel == true ? ((overrideHandler ?? saveFactCallback(ref ?? model?.mtype)) as SubmitHook) : null),
      formCreator = inheritForm == false ? ((context) => FormController.ofModel(context, model!)) : null,
      validator = validator ??
          ((FormController form) async {
            final errors =
                model is MModel ? (await sunny.get<IMSchemaService>(context: context).validate(model)) : <ValidationError>[];

            /// We validate the schema, but also check for formConfig violations
            final ov = overrides;
            ov?.formConfig?.forEach((path, value) {
              if (value.any((element) => element.isRequired == true)) {
                final val = form.get(path);
                if (val == null || (val is String && val.isNullOrBlank)) {
                  errors.add(ValidationError(path: path, message: "You must enter a value"));
                }
              }
            });
            return errors;
          }),
      metaFormContext = metaFormService.createContext(
        context,
        model,
        schemaRef: ref ?? model?.mtype,
        extraHandlers: extraHandlers,
        embedPath: embedPath,
        schema: schema,
        scope: scope,
        overrides: MetadataOverrides(ignoredPaths: {...?ignoredPaths?.map((p) => JsonPath.of(p))}) + overrides,
      ),
      super(key: Key("meta-form-${(id ?? (model is MEntity ? model.id : '') ?? ref ?? model?.mtype)}"));