• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

juancastillo0 / json_form / 10820622711

11 Sep 2024 10:26PM UTC coverage: 72.723% (+4.1%) from 68.638%
10820622711

push

github

juancastillo0
dependencies tests

1461 of 2009 relevant lines covered (72.72%)

1.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.84
/lib/src/builder/widget_builder.dart
1
import 'dart:convert';
2
import 'dart:developer';
3

4
import 'package:cross_file/cross_file.dart';
5
import 'package:flutter/material.dart';
6
import 'package:json_form/src/builder/array_schema_builder.dart';
7
import 'package:json_form/src/builder/logic/widget_builder_logic.dart';
8
import 'package:json_form/src/builder/object_schema_builder.dart';
9
import 'package:json_form/src/builder/property_schema_builder.dart';
10
import 'package:json_form/src/models/json_form_schema_style.dart';
11

12
import '../models/models.dart';
13

14
typedef FileHandler = Map<String, Future<List<XFile>?> Function()?> Function();
15
typedef CustomPickerHandler = Map<String, Future<dynamic> Function(Map data)>
16
    Function();
17

18
typedef CustomValidatorHandler = Map<String, String? Function(dynamic)?>
19
    Function();
20

21
class JsonForm extends StatefulWidget {
22
  const JsonForm({
1✔
23
    super.key,
24
    required this.jsonSchema,
25
    required this.onFormDataSaved,
26
    this.controller,
27
    this.uiSchema,
28
    this.uiConfig,
29
    this.fileHandler,
30
    this.customPickerHandler,
31
    this.customValidatorHandler,
32
  });
33

34
  final String jsonSchema;
35
  final void Function(Object) onFormDataSaved;
36

37
  final JsonFormController? controller;
38
  final String? uiSchema;
39
  final JsonFormSchemaUiConfig? uiConfig;
40
  final FileHandler? fileHandler;
41
  final CustomPickerHandler? customPickerHandler;
42
  final CustomValidatorHandler? customValidatorHandler;
43

44
  @override
1✔
45
  _JsonFormState createState() => _JsonFormState();
1✔
46
}
47

48
class _JsonFormState extends State<JsonForm> {
49
  late JsonFormController controller;
50
  Schema get mainSchema => controller.mainSchema!;
3✔
51
  GlobalKey<FormState> get _formKey => controller.formKey!;
3✔
52

53
  _JsonFormState();
1✔
54

55
  @override
1✔
56
  void initState() {
57
    super.initState();
1✔
58
    initMainSchema(controllerChanged: true, schemaChanged: true);
1✔
59
  }
60

61
  void initMainSchema({
1✔
62
    required bool controllerChanged,
63
    required bool schemaChanged,
64
  }) {
65
    if (controllerChanged) {
66
      controller = widget.controller ?? JsonFormController(data: {});
5✔
67
      controller.formKey ??= GlobalKey<FormState>();
3✔
68
      if (controller.mainSchema != null &&
2✔
69
          (!schemaChanged || widget.jsonSchema.isEmpty)) {
3✔
70
        return;
71
      }
72
    }
73
    final mainSchema = Schema.fromJson(
1✔
74
      json.decode(widget.jsonSchema),
3✔
75
      id: kGenesisIdKey,
76
    );
77
    final map = widget.uiSchema != null
2✔
78
        ? json.decode(widget.uiSchema!) as Map<String, Object?>
3✔
79
        : null;
80
    if (map != null) {
81
      mainSchema.setUiSchema(map, fromOptions: false);
1✔
82
    }
83
    controller.mainSchema = mainSchema;
2✔
84
  }
85

86
  @override
1✔
87
  void didUpdateWidget(covariant JsonForm oldWidget) {
88
    super.didUpdateWidget(oldWidget);
1✔
89
    final controllerChanged = oldWidget.controller != widget.controller;
4✔
90
    final schemaChanged = oldWidget.jsonSchema != widget.jsonSchema ||
4✔
91
        oldWidget.uiSchema != widget.uiSchema;
4✔
92
    if (schemaChanged || controllerChanged) {
93
      initMainSchema(
1✔
94
        controllerChanged: controllerChanged,
95
        schemaChanged: schemaChanged,
96
      );
97
    }
98
  }
99

100
  @override
1✔
101
  Widget build(BuildContext context) {
102
    return WidgetBuilderInherited(
1✔
103
      controller: controller,
1✔
104
      fileHandler: widget.fileHandler,
2✔
105
      customPickerHandler: widget.customPickerHandler,
2✔
106
      customValidatorHandler: widget.customValidatorHandler,
2✔
107
      child: Builder(
1✔
108
        builder: (context) {
1✔
109
          final widgetBuilderInherited = WidgetBuilderInherited.of(context);
1✔
110
          final uiConfig = widgetBuilderInherited.uiConfig;
1✔
111

112
          final formChild = Column(
1✔
113
            children: <Widget>[
1✔
114
              if (uiConfig.debugMode)
1✔
115
                TextButton(
×
116
                  onPressed: () {
×
117
                    inspect(mainSchema);
×
118
                  },
119
                  child: const Text('INSPECT'),
120
                ),
121
              _buildHeaderTitle(context),
1✔
122
              FormFromSchemaBuilder(
1✔
123
                mainSchema: mainSchema,
1✔
124
                schema: mainSchema,
1✔
125
              ),
126
              uiConfig.submitButtonBuilder?.call(onSubmit) ??
2✔
127
                  Padding(
1✔
128
                    padding: const EdgeInsets.symmetric(vertical: 10),
129
                    child: ElevatedButton(
1✔
130
                      key: const Key('JsonForm_submitButton'),
131
                      onPressed: onSubmit,
1✔
132
                      child: Text(
1✔
133
                        uiConfig.localizedTexts.submit(),
2✔
134
                      ),
135
                    ),
136
                  ),
137
            ],
138
          );
139

140
          return SingleChildScrollView(
1✔
141
            key: const Key('JsonForm_scrollView'),
142
            child: uiConfig.formBuilder?.call(_formKey, formChild) ??
1✔
143
                Form(
1✔
144
                  key: _formKey,
1✔
145
                  autovalidateMode: uiConfig.autovalidateMode,
1✔
146
                  child: Padding(
1✔
147
                    padding: const EdgeInsets.all(12.0),
148
                    child: formChild,
149
                  ),
150
                ),
151
          );
152
        },
153
      ),
154
    )..setJsonFormSchemaStyle(context, widget.uiConfig);
3✔
155
  }
156

157
  Widget _buildHeaderTitle(BuildContext context) {
1✔
158
    final uiConfig = WidgetBuilderInherited.of(context).uiConfig;
2✔
159
    final custom = uiConfig.titleAndDescriptionBuilder?.call(mainSchema);
1✔
160
    if (custom != null) return custom;
161

162
    return Column(
1✔
163
      crossAxisAlignment: CrossAxisAlignment.start,
164
      children: <Widget>[
1✔
165
        if (mainSchema.title != null)
2✔
166
          SizedBox(
1✔
167
            width: double.infinity,
168
            child: Text(
1✔
169
              mainSchema.title!,
2✔
170
              style: uiConfig.title,
1✔
171
              textAlign: uiConfig.titleAlign,
1✔
172
            ),
173
          ),
174
        const Divider(),
1✔
175
        if (mainSchema.description != null)
2✔
176
          SizedBox(
1✔
177
            width: double.infinity,
178
            child: Text(
1✔
179
              mainSchema.description!,
2✔
180
              style: uiConfig.description,
1✔
181
              textAlign: uiConfig.titleAlign,
1✔
182
            ),
183
          ),
184
      ],
185
    );
186
  }
187

188
  //  Form methods
189
  void onSubmit() {
1✔
190
    final data = controller.submit();
2✔
191
    if (data != null) {
192
      widget.onFormDataSaved(data);
3✔
193
    }
194
  }
195
}
196

197
class FormFromSchemaBuilder extends StatelessWidget {
198
  const FormFromSchemaBuilder({
1✔
199
    super.key,
200
    required this.mainSchema,
201
    required this.schema,
202
    this.schemaObject,
203
  });
204
  final Schema mainSchema;
205
  final Schema schema;
206
  final SchemaObject? schemaObject;
207

208
  @override
1✔
209
  Widget build(BuildContext context) {
210
    if (schema.uiSchema.hidden) {
3✔
211
      return const SizedBox.shrink();
212
    }
213
    if (schema is SchemaProperty) {
2✔
214
      return PropertySchemaBuilder(
1✔
215
        mainSchema: mainSchema,
1✔
216
        schemaProperty: schema as SchemaProperty,
1✔
217
      );
218
    }
219
    if (schema is SchemaArray) {
2✔
220
      return ArraySchemaBuilder(
1✔
221
        mainSchema: mainSchema,
1✔
222
        schemaArray: schema as SchemaArray,
1✔
223
      );
224
    }
225

226
    if (schema is SchemaObject) {
2✔
227
      return ObjectSchemaBuilder(
1✔
228
        mainSchema: mainSchema,
1✔
229
        schemaObject: schema as SchemaObject,
1✔
230
      );
231
    }
232

233
    return const SizedBox.shrink();
234
  }
235
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc